Skip to content

Commit

Permalink
refactor api
Browse files Browse the repository at this point in the history
  • Loading branch information
TheodoreKrypton committed Jul 9, 2024
1 parent ae5c6e5 commit 9164b20
Show file tree
Hide file tree
Showing 19 changed files with 140 additions and 186 deletions.
12 changes: 7 additions & 5 deletions src/api/client/directory-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import { MetaDataApi } from './metadata-api';
export class DirectoryApi {
constructor(private metadataApi: MetaDataApi) {}

public root() {
return this.metadataApi.getRootDirectory();
}


public async createDirectory(
public async create(
where: { name: string; under: TGFSDirectory },
dir?: TGFSDirectory,
) {
Expand All @@ -38,14 +40,14 @@ export class DirectoryApi {
return [...dir.findDirs(), ...dir.findFiles()];
}

public async deleteEmptyDirectory(directory: TGFSDirectory) {
public async rmEmpty(directory: TGFSDirectory) {
if (directory.findDirs().length > 0 || directory.findFiles().length > 0) {
throw new DirectoryIsNotEmptyError();
}
await this.dangerouslyDeleteDirectory(directory);
await this.rmDangerously(directory);
}

public async dangerouslyDeleteDirectory(directory: TGFSDirectory) {
public async rmDangerously(directory: TGFSDirectory) {
directory.delete();
await this.metadataApi.syncMetadata();
}
Expand Down
9 changes: 8 additions & 1 deletion src/api/client/file-desc-api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FileDescAPIResponse } from 'src/api/client/model';
import { TGFSFileRef } from 'src/model/directory';
import { TGFSFile } from 'src/model/file';
import { TGFSFile, TGFSFileVersion } from 'src/model/file';

import { GeneralFileMessage, isFileMessageEmpty } from './model';
import { FileRepository } from './repository/impl/file';
Expand Down Expand Up @@ -31,6 +31,13 @@ export class FileDescApi {
return await this.fdRepo.get(fr);
}

public async *downloadFileAtVersion(
asName: string,
version: TGFSFileVersion,
): AsyncGenerator<Buffer> {
return this.fileRepo.downloadFile(asName, version.messageId);
}

public async addFileVersion(
fr: TGFSFileRef,
fileMsg: GeneralFileMessage,
Expand Down
41 changes: 33 additions & 8 deletions src/api/client/file-ref-api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TGFSDirectory, TGFSFileRef } from 'src/model/directory';
import { TGFSFile } from 'src/model/file';
import { TGFSFile, TGFSFileVersion } from 'src/model/file';
import { validateName } from 'src/utils/validate-name';

import { FileDescApi } from './file-desc-api';
Expand All @@ -12,7 +12,7 @@ export class FileRefApi {
private readonly fileDescApi: FileDescApi,
) {}

public async copyFile(
public async copy(
where: TGFSDirectory,
fr: TGFSFileRef,
name?: string,
Expand All @@ -22,7 +22,7 @@ export class FileRefApi {
return copiedFR;
}

private async createFile(
private async create(
where: TGFSDirectory,
fileMsg: GeneralFileMessage,
): Promise<TGFSFile> {
Expand All @@ -45,7 +45,7 @@ export class FileRefApi {
}
}

private async updateFile(
private async update(
fr: TGFSFileRef,
fileMsg: GeneralFileMessage,
versionId?: string,
Expand All @@ -57,7 +57,7 @@ export class FileRefApi {
return fd;
}

public async deleteFile(fr: TGFSFileRef, version?: string): Promise<void> {
public async rm(fr: TGFSFileRef, version?: string): Promise<void> {
if (!version) {
fr.delete();
await this.metadataApi.syncMetadata();
Expand All @@ -70,7 +70,7 @@ export class FileRefApi {
}
}

public async uploadFile(
public async upload(
where: {
under: TGFSDirectory;
versionId?: string;
Expand All @@ -79,9 +79,34 @@ export class FileRefApi {
): Promise<TGFSFile> {
const fr = where.under.findFiles([fileMsg.name])[0];
if (fr) {
return await this.updateFile(fr, fileMsg, where.versionId);
return await this.update(fr, fileMsg, where.versionId);
} else {
return await this.createFile(where.under, fileMsg);
return await this.create(where.under, fileMsg);
}
}

public async *retrieve(
fr: TGFSFileRef,
asName?: string,
): AsyncGenerator<Buffer> {
const fd = await this.desc(fr);

if (fd.isEmptyFile()) {
yield Buffer.from('');
} else {
const version = fd.getLatest();
yield* this.fileDescApi.downloadFileAtVersion(asName ?? fr.name, version);
}
}

public async *retrieveVersion(
version: TGFSFileVersion,
asName: string,
): AsyncGenerator<Buffer> {
yield* this.fileDescApi.downloadFileAtVersion(asName, version);
}

public async desc(fr: TGFSFileRef): Promise<TGFSFile> {
return await this.fileDescApi.getFileDesc(fr);
}
}
95 changes: 12 additions & 83 deletions src/api/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
import { gramjs, telegraf } from 'src/api/impl';
import { config } from 'src/config';
import { TGFSDirectory, TGFSFileRef } from 'src/model/directory';
import { TGFSFile } from 'src/model/file';

import { DirectoryApi } from './directory-api';
import { FileDescApi } from './file-desc-api';
import { FileRefApi } from './file-ref-api';
import { MessageApi } from './message-api';
import { MetaDataApi } from './metadata-api';
import { GeneralFileMessage } from './model';
import { TGMsgFDRepository } from './repository/impl/fd/tg-msg';
import { FileRepository } from './repository/impl/file';
import { MetadataRepository } from './repository/impl/metadata/tg-msg';
import { JSONMetadataRepository } from './repository/impl/metadata/tg-msg';

export const createClient = async () => {
const api = {
tdlib: {
const msgApi = new MessageApi(
{
account: new gramjs.GramJSApi(await gramjs.loginAsAccount(config)),
bot: new gramjs.GramJSApi(await gramjs.loginAsBot(config)),
},
bot: new telegraf.TelegrafApi(telegraf.createBot(config)),
};

const msgApi = new MessageApi(api.tdlib, api.bot);
new telegraf.TelegrafApi(telegraf.createBot(config)),
);

const fileRepo = new FileRepository(msgApi);
const fdRepo = new TGMsgFDRepository(msgApi);
const metadataRepo = new MetadataRepository(msgApi, fileRepo);
const metadataRepo = new JSONMetadataRepository(msgApi, fileRepo);

const fdApi = new FileDescApi(fdRepo, fileRepo);

Expand All @@ -36,85 +31,19 @@ export const createClient = async () => {
const frApi = new FileRefApi(metadataApi, fdApi);
const dirApi = new DirectoryApi(metadataApi);

return new Client(metadataApi, frApi, fdApi, dirApi, fileRepo);
return new Client(metadataApi, frApi, dirApi);
};

export class Client {
file: FileRefApi;
dir: DirectoryApi;

constructor(
private readonly metadataApi: MetaDataApi,
private readonly frApi: FileRefApi,
private readonly fdApi: FileDescApi,
private readonly dirApi: DirectoryApi,
private readonly fileRepo: FileRepository,
) {}

public async *downloadLatestVersion(
fr: TGFSFileRef,
asName: string,
): AsyncGenerator<Buffer> {
const fd = await this.fdApi.getFileDesc(fr);

if (fd.isEmptyFile()) {
yield Buffer.from('');
} else {
const version = fd.getLatest();
yield* this.fileRepo.downloadFile(asName, version.messageId);
}
}

public async getFileDesc(fr: TGFSFileRef) {
return this.fdApi.getFileDesc(fr);
}

public getRootDirectory() {
return this.metadataApi.getRootDirectory();
}

public async createDirectory(
where: { name: string; under: TGFSDirectory },
dir?: TGFSDirectory,
) {
return this.dirApi.createDirectory(where, dir);
}

public findDirs(dir: TGFSDirectory) {
return dir.findDirs();
}

public async copyFile(
where: TGFSDirectory,
fr: TGFSFileRef,
name?: string,
): Promise<TGFSFileRef> {
return this.frApi.copyFile(where, fr, name);
}

public async uploadFile(
where: {
under: TGFSDirectory;
versionId?: string;
},
fileMsg?: GeneralFileMessage,
): Promise<TGFSFile> {
return this.frApi.uploadFile(where, fileMsg);
}

public async ls(
dir: TGFSDirectory,
fileName?: string,
): Promise<TGFSFileRef | Array<TGFSDirectory | TGFSFileRef>> {
return this.dirApi.ls(dir, fileName);
}

public async deleteEmptyDirectory(directory: TGFSDirectory) {
return this.dirApi.deleteEmptyDirectory(directory);
}

public async dangerouslyDeleteDirectory(directory: TGFSDirectory) {
return this.dirApi.dangerouslyDeleteDirectory(directory);
}

public async deleteFile(fr: TGFSFileRef, version?: string) {
return this.frApi.deleteFile(fr, version);
this.file = this.frApi;
this.dir = this.dirApi;
}
}
2 changes: 1 addition & 1 deletion src/api/client/repository/impl/metadata/tg-msg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { TGFSMetadata } from 'src/model/metadata';

import { FileRepository } from '../file';

export class MetadataRepository implements IMetaDataRepository {
export class JSONMetadataRepository implements IMetaDataRepository {
constructor(
private readonly msgApi: MessageApi,
private readonly fileRepo: FileRepository,
Expand Down
2 changes: 1 addition & 1 deletion src/api/ops/copy-dir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const copyDir =
const [basePathTo, nameTo] = splitPath(pathTo);
const dir2 = navigateToDir(client)(basePathTo);

const res = await client.createDirectory(
const res = await client.dir.create(
{ name: nameTo ?? nameFrom, under: dir2 },
dirToCopy,
);
Expand Down
2 changes: 1 addition & 1 deletion src/api/ops/copy-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ export const copyFile =
const [basePathTo, nameTo] = splitPath(pathTo);
const dir2 = navigateToDir(client)(basePathTo);

const res = await client.copyFile(dir2, frToCopy, nameTo ?? nameFrom);
const res = await client.file.copy(dir2, frToCopy, nameTo ?? nameFrom);
return { from: frToCopy, to: res };
};
6 changes: 3 additions & 3 deletions src/api/ops/create-dir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ export const createDir =
if (!parents) {
const [basePath, name] = splitPath(path);
const dir = navigateToDir(client)(basePath);
return await client.createDirectory({ name: name, under: dir });
return await client.dir.create({ name: name, under: dir });
} else {
if (!path.startsWith('/')) {
throw new RelativePathError(path);
}

const paths = path.split('/').filter((p) => p);
let currentDir = client.getRootDirectory();
let currentDir = client.dir.root();
for (const p of paths) {
const children = currentDir.findDirs([p]);
if (children.length > 0) {
currentDir = children[0];
continue;
}

const dir = await client.createDirectory({
const dir = await client.dir.create({
name: p,
under: currentDir,
});
Expand Down
2 changes: 1 addition & 1 deletion src/api/ops/create-empty-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export const createEmptyFile = (client: Client) => async (path: PathLike) => {
const dir = navigateToDir(client)(basePath);

if (!existsSync(path)) {
return await client.uploadFile({ under: dir }, { name, empty: true });
return await client.file.upload({ under: dir }, { name, empty: true });
}
};
32 changes: 16 additions & 16 deletions src/api/ops/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ import { splitPath } from './utils';

export const list =
(client: Client) =>
async (
path: PathLike,
): Promise<TGFSFileRef | Array<TGFSFileRef | TGFSDirectory>> => {
const [basePath, name] = splitPath(path);
const dir = navigateToDir(client)(basePath);
async (
path: PathLike,
): Promise<TGFSFileRef | Array<TGFSFileRef | TGFSDirectory>> => {
const [basePath, name] = splitPath(path);
const dir = navigateToDir(client)(basePath);

let nextDir = dir;
let nextDir = dir;

if (name) {
nextDir = dir.findDir(name);
}
if (nextDir) {
return client.ls(nextDir);
} else {
// cannot find a sub-directory with the given name, so assume it's a file
return client.ls(dir, name);
}
};
if (name) {
nextDir = dir.findDir(name);
}
if (nextDir) {
return client.dir.ls(nextDir);
} else {
// cannot find a sub-directory with the given name, so assume it's a file
return client.dir.ls(dir, name);
}
};
2 changes: 1 addition & 1 deletion src/api/ops/move-dir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ export const moveDir =
(client: Client) => async (pathFrom: string, pathTo: string) => {
const { from, to } = await copyDir(client)(pathFrom, pathTo);

await client.dangerouslyDeleteDirectory(from);
await client.dir.rmDangerously(from);
};
2 changes: 1 addition & 1 deletion src/api/ops/move-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import { copyFile } from './copy-file';
export const moveFile =
(client: Client) => async (pathFrom: string, pathTo: string) => {
const { from, to } = await copyFile(client)(pathFrom, pathTo);
await client.deleteFile(from);
await client.file.rm(from);
};
2 changes: 1 addition & 1 deletion src/api/ops/navigate-to-dir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const navigateToDir = (client: Client) => (path: string) => {
.split('/')
.filter((part) => part !== '');

let currentDirectory = client.getRootDirectory();
let currentDirectory = client.dir.root();

for (const pathPart of pathParts) {
const directory = currentDirectory.findDirs([pathPart])[0];
Expand Down
Loading

0 comments on commit 9164b20

Please sign in to comment.