mirror of
https://github.com/TheodoreKrypton/tgfs
synced 2024-11-21 22:55:40 +00:00
refactor api
This commit is contained in:
parent
ae5c6e5f70
commit
9164b200da
@ -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,
|
||||
) {
|
||||
@ -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();
|
||||
}
|
||||
|
@ -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';
|
||||
@ -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,
|
||||
|
@ -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';
|
||||
@ -12,7 +12,7 @@ export class FileRefApi {
|
||||
private readonly fileDescApi: FileDescApi,
|
||||
) {}
|
||||
|
||||
public async copyFile(
|
||||
public async copy(
|
||||
where: TGFSDirectory,
|
||||
fr: TGFSFileRef,
|
||||
name?: string,
|
||||
@ -22,7 +22,7 @@ export class FileRefApi {
|
||||
return copiedFR;
|
||||
}
|
||||
|
||||
private async createFile(
|
||||
private async create(
|
||||
where: TGFSDirectory,
|
||||
fileMsg: GeneralFileMessage,
|
||||
): Promise<TGFSFile> {
|
||||
@ -45,7 +45,7 @@ export class FileRefApi {
|
||||
}
|
||||
}
|
||||
|
||||
private async updateFile(
|
||||
private async update(
|
||||
fr: TGFSFileRef,
|
||||
fileMsg: GeneralFileMessage,
|
||||
versionId?: string,
|
||||
@ -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();
|
||||
@ -70,7 +70,7 @@ export class FileRefApi {
|
||||
}
|
||||
}
|
||||
|
||||
public async uploadFile(
|
||||
public async upload(
|
||||
where: {
|
||||
under: TGFSDirectory;
|
||||
versionId?: string;
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
);
|
||||
|
@ -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 };
|
||||
};
|
||||
|
@ -11,14 +11,14 @@ 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) {
|
||||
@ -26,7 +26,7 @@ export const createDir =
|
||||
continue;
|
||||
}
|
||||
|
||||
const dir = await client.createDirectory({
|
||||
const dir = await client.dir.create({
|
||||
name: p,
|
||||
under: currentDir,
|
||||
});
|
||||
|
@ -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 });
|
||||
}
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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];
|
||||
|
@ -11,12 +11,12 @@ export const removeDir =
|
||||
if (!recursive) {
|
||||
const child = dir.findDirs([name])[0];
|
||||
if (child) {
|
||||
await client.deleteEmptyDirectory(child);
|
||||
await client.dir.rmEmpty(child);
|
||||
} else {
|
||||
throw new FileOrDirectoryDoesNotExistError(path, `remove dir ${path}`);
|
||||
}
|
||||
} else {
|
||||
const nextDir = name ? dir.findDirs([name])[0] : dir;
|
||||
await client.dangerouslyDeleteDirectory(nextDir);
|
||||
await client.dir.rmDangerously(nextDir);
|
||||
}
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ export const removeFile = (client: Client) => async (path: string) => {
|
||||
const dir = navigateToDir(client)(basePath);
|
||||
const fileRef = dir.findFiles([name])[0];
|
||||
if (fileRef) {
|
||||
await client.deleteFile(fileRef);
|
||||
await client.file.rm(fileRef);
|
||||
} else {
|
||||
throw new FileOrDirectoryDoesNotExistError(path, `remove file ${path}`);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ export const uploadFromLocal =
|
||||
throw new FileOrDirectoryDoesNotExistError(path, `upload from ${path}`);
|
||||
}
|
||||
|
||||
return await client.uploadFile(
|
||||
return await client.file.upload(
|
||||
{ under: dir },
|
||||
{ name, path: local.toString() },
|
||||
);
|
||||
@ -30,7 +30,7 @@ export const uploadFromBytes =
|
||||
|
||||
const dir = navigateToDir(client)(basePath);
|
||||
|
||||
return await client.uploadFile({ under: dir }, { name, buffer: bytes });
|
||||
return await client.file.upload({ under: dir }, { name, buffer: bytes });
|
||||
};
|
||||
|
||||
export const uploadFromStream =
|
||||
@ -40,5 +40,5 @@ export const uploadFromStream =
|
||||
|
||||
const dir = navigateToDir(client)(basePath);
|
||||
|
||||
return await client.uploadFile({ under: dir }, { name, stream, size });
|
||||
return await client.file.upload({ under: dir }, { name, stream, size });
|
||||
};
|
||||
|
@ -16,7 +16,7 @@ export const ls = (client: Client) => async (argv: { path: PathLike }) => {
|
||||
})
|
||||
.join(' ');
|
||||
} else {
|
||||
const fd = await client.getFileDesc(res);
|
||||
const fd = await client.file.desc(res);
|
||||
return fileInfo(client, fd);
|
||||
}
|
||||
};
|
||||
|
@ -152,7 +152,7 @@ export class TGFSFileSystem extends VirtualFileSystem {
|
||||
): Promise<TGFSFileRef | (TGFSFileRef | TGFSDirectory)[]> {
|
||||
const res = await list(this.tgClient)(path.toString());
|
||||
if (res instanceof TGFSFileRef) {
|
||||
const fd = await this.tgClient.getFileDesc(res);
|
||||
const fd = await this.tgClient.file.desc(res);
|
||||
this.resources[path.toString()] = TGFSFileResource.fromFileDesc(fd);
|
||||
} else {
|
||||
this.resources[path.toString()] = new TGFSDirResource();
|
||||
@ -169,7 +169,7 @@ export class TGFSFileSystem extends VirtualFileSystem {
|
||||
.filter((res) => res instanceof TGFSFileRef)
|
||||
.map((fr) => {
|
||||
return (async () => {
|
||||
const fd = await this.tgClient.getFileDesc(fr as TGFSFileRef);
|
||||
const fd = await this.tgClient.file.desc(fr as TGFSFileRef);
|
||||
if (path.toString() === '/') {
|
||||
this.resources[`/${fr.name}`] = TGFSFileResource.fromFileDesc(fd);
|
||||
} else {
|
||||
@ -315,10 +315,7 @@ export class TGFSFileSystem extends VirtualFileSystem {
|
||||
const fileRef = (await list(this.tgClient)(
|
||||
path.toString(),
|
||||
)) as TGFSFileRef;
|
||||
const chunks = this.tgClient.downloadLatestVersion(
|
||||
fileRef,
|
||||
fileRef.name,
|
||||
);
|
||||
const chunks = this.tgClient.file.retrieve(fileRef, fileRef.name);
|
||||
|
||||
callback(null, Readable.from(chunks));
|
||||
} catch (err) {
|
||||
|
@ -20,38 +20,38 @@ describe('file and directory operations', () => {
|
||||
});
|
||||
|
||||
it('should create a directory', async () => {
|
||||
const root = client.getRootDirectory();
|
||||
const d1 = await client.createDirectory({ name: 'd1', under: root });
|
||||
const root = client.dir.root();
|
||||
const d1 = await client.dir.create({ name: 'd1', under: root });
|
||||
expect(root.findDirs(['d1'])[0]).toEqual(d1);
|
||||
});
|
||||
|
||||
it('should throw an error if the directory name is illegal', async () => {
|
||||
const root = client.getRootDirectory();
|
||||
const root = client.dir.root();
|
||||
|
||||
await expect(
|
||||
client.createDirectory({ name: '-d1', under: root }),
|
||||
client.dir.create({ name: '-d1', under: root }),
|
||||
).rejects.toThrow();
|
||||
await expect(
|
||||
client.createDirectory({ name: 'd/1', under: root }),
|
||||
client.dir.create({ name: 'd/1', under: root }),
|
||||
).rejects.toThrow();
|
||||
});
|
||||
|
||||
it('should remove a directory', async () => {
|
||||
const root = client.getRootDirectory();
|
||||
const root = client.dir.root();
|
||||
|
||||
const d1 = await client.createDirectory({ name: 'd1', under: root });
|
||||
await client.dangerouslyDeleteDirectory(d1);
|
||||
const d1 = await client.dir.create({ name: 'd1', under: root });
|
||||
await client.dir.rmDangerously(d1);
|
||||
expect(root.findDirs(['d1'])[0]).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should remove all directories', async () => {
|
||||
const d1 = await client.createDirectory({
|
||||
const d1 = await client.dir.create({
|
||||
name: 'd1',
|
||||
under: client.getRootDirectory(),
|
||||
under: client.dir.root(),
|
||||
});
|
||||
await client.createDirectory({ name: 'd2', under: d1 });
|
||||
await client.dangerouslyDeleteDirectory(client.getRootDirectory());
|
||||
expect(client.getRootDirectory().findDirs(['d1'])[0]).toBeUndefined();
|
||||
await client.dir.create({ name: 'd2', under: d1 });
|
||||
await client.dir.rmDangerously(client.dir.root());
|
||||
expect(client.dir.root().findDirs(['d1'])[0]).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@ -63,8 +63,8 @@ describe('file and directory operations', () => {
|
||||
});
|
||||
|
||||
it('should create a small file from buffer', async () => {
|
||||
const root = client.getRootDirectory();
|
||||
const f1 = await client.uploadFile(
|
||||
const root = client.dir.root();
|
||||
const f1 = await client.file.upload(
|
||||
{ under: root },
|
||||
{ name: 'f1', buffer: Buffer.from('mock-file-content') },
|
||||
);
|
||||
@ -75,8 +75,8 @@ describe('file and directory operations', () => {
|
||||
const fileName = `${Math.random()}.txt`;
|
||||
fs.writeFileSync(fileName, 'mock-file-content');
|
||||
|
||||
const root = client.getRootDirectory();
|
||||
const f1 = await client.uploadFile(
|
||||
const root = client.dir.root();
|
||||
const f1 = await client.file.upload(
|
||||
{ under: root },
|
||||
{ name: 'f1', path: fileName },
|
||||
);
|
||||
@ -88,9 +88,9 @@ describe('file and directory operations', () => {
|
||||
it('should create a big file from buffer', async () => {
|
||||
const content = Buffer.alloc(1024 * 1024 * 10, 'a');
|
||||
|
||||
const root = client.getRootDirectory();
|
||||
const root = client.dir.root();
|
||||
|
||||
const f1 = await client.uploadFile(
|
||||
const f1 = await client.file.upload(
|
||||
{ under: root },
|
||||
{ name: 'f1', buffer: content },
|
||||
);
|
||||
@ -102,9 +102,9 @@ describe('file and directory operations', () => {
|
||||
const content = Buffer.alloc(1024 * 1024 * 10, 'a');
|
||||
fs.writeFileSync(fileName, content);
|
||||
|
||||
const root = client.getRootDirectory();
|
||||
const root = client.dir.root();
|
||||
|
||||
const f1 = await client.uploadFile(
|
||||
const f1 = await client.file.upload(
|
||||
{ under: root },
|
||||
{ name: 'f1', path: fileName },
|
||||
);
|
||||
@ -114,47 +114,43 @@ describe('file and directory operations', () => {
|
||||
});
|
||||
|
||||
it('should add a file version', async () => {
|
||||
const root = client.getRootDirectory();
|
||||
await client.uploadFile(
|
||||
const root = client.dir.root();
|
||||
await client.file.upload(
|
||||
{ under: root },
|
||||
{ name: 'f1', buffer: Buffer.from('mock-file-content') },
|
||||
);
|
||||
|
||||
await sleep(300); // wait for the timestamp to change to ensure the order of versions
|
||||
const content2 = 'mock-file-content-edited';
|
||||
await client.uploadFile(
|
||||
await client.file.upload(
|
||||
{ under: root },
|
||||
{ name: 'f1', buffer: Buffer.from(content2) },
|
||||
);
|
||||
const fr = root.findFiles(['f1'])[0];
|
||||
const fd = await client.getFileDesc(fr);
|
||||
const fd = await client.file.desc(fr);
|
||||
expect(Object.keys(fd.versions)).toHaveLength(2);
|
||||
const content = await saveToBuffer(
|
||||
client.downloadLatestVersion(fr, 'f1'),
|
||||
);
|
||||
const content = await saveToBuffer(client.file.retrieve(fr, 'f1'));
|
||||
expect(content.toString()).toEqual(content2);
|
||||
});
|
||||
|
||||
it('should edit a file version', async () => {
|
||||
const root = client.getRootDirectory();
|
||||
const root = client.dir.root();
|
||||
|
||||
await client.uploadFile(
|
||||
await client.file.upload(
|
||||
{ under: root },
|
||||
{ name: 'f1', buffer: Buffer.from('mock-file-content') },
|
||||
);
|
||||
|
||||
const content2 = 'mock-file-content-edited';
|
||||
let fr = root.findFiles(['f1'])[0];
|
||||
const fd = await client.getFileDesc(fr);
|
||||
const fd = await client.file.desc(fr);
|
||||
|
||||
await client.uploadFile(
|
||||
await client.file.upload(
|
||||
{ under: root, versionId: fd.latestVersionId },
|
||||
{ name: 'f1', buffer: Buffer.from(content2) },
|
||||
);
|
||||
|
||||
const content = await saveToBuffer(
|
||||
client.downloadLatestVersion(fr, 'f1'),
|
||||
);
|
||||
const content = await saveToBuffer(client.file.retrieve(fr, 'f1'));
|
||||
expect(content.toString()).toEqual(content2);
|
||||
});
|
||||
|
||||
@ -176,48 +172,46 @@ describe('file and directory operations', () => {
|
||||
// });
|
||||
|
||||
it('should remove a file', async () => {
|
||||
const root = client.getRootDirectory();
|
||||
const root = client.dir.root();
|
||||
|
||||
const f1 = await client.uploadFile(
|
||||
const f1 = await client.file.upload(
|
||||
{ under: root },
|
||||
{ name: 'f1', buffer: Buffer.from('mock-file-content') },
|
||||
);
|
||||
|
||||
const fr = root.findFiles(['f1'])[0];
|
||||
await client.deleteFile(fr);
|
||||
await client.file.rm(fr);
|
||||
expect(root.findFiles(['f1'])[0]).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should remove a file version', async () => {
|
||||
const root = client.getRootDirectory();
|
||||
const root = client.dir.root();
|
||||
const content = 'mock-file-content';
|
||||
await client.uploadFile(
|
||||
await client.file.upload(
|
||||
{ under: root },
|
||||
{ name: 'f1', buffer: Buffer.from(content) },
|
||||
);
|
||||
await sleep(300);
|
||||
await client.uploadFile(
|
||||
await client.file.upload(
|
||||
{ under: root },
|
||||
{ name: 'f1', buffer: Buffer.from('mock-file-content-edited') },
|
||||
);
|
||||
|
||||
const fr = root.findFiles(['f1'])[0];
|
||||
let fd = await client.getFileDesc(fr);
|
||||
let fd = await client.file.desc(fr);
|
||||
|
||||
await client.deleteFile(fr, fd.latestVersionId);
|
||||
await client.file.rm(fr, fd.latestVersionId);
|
||||
|
||||
fd = await client.getFileDesc(fr);
|
||||
fd = await client.file.desc(fr);
|
||||
expect(Object.keys(fd.versions)).toHaveLength(1);
|
||||
const content2 = await saveToBuffer(
|
||||
client.downloadLatestVersion(fr, 'f1'),
|
||||
);
|
||||
const content2 = await saveToBuffer(client.file.retrieve(fr, 'f1'));
|
||||
expect(content2.toString()).toEqual(content);
|
||||
});
|
||||
|
||||
it('should download a file as a local file', async () => {
|
||||
const root = client.getRootDirectory();
|
||||
const root = client.dir.root();
|
||||
const content = 'mock-file-content';
|
||||
await client.uploadFile(
|
||||
await client.file.upload(
|
||||
{ under: root },
|
||||
{ name: 'f1', buffer: Buffer.from(content) },
|
||||
);
|
||||
@ -225,7 +219,7 @@ describe('file and directory operations', () => {
|
||||
const fr = root.findFiles(['f1'])[0];
|
||||
const localFileName = `${Math.random()}.txt`;
|
||||
|
||||
await saveToFile(client.downloadLatestVersion(fr, 'f1'), localFileName);
|
||||
await saveToFile(client.file.retrieve(fr, 'f1'), localFileName);
|
||||
|
||||
const contentRead = fs.readFileSync(localFileName);
|
||||
expect(contentRead.toString()).toEqual(content);
|
||||
|
Loading…
Reference in New Issue
Block a user