Skip to content

Commit

Permalink
feat: 🎸 implement .del() method
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Jun 20, 2023
1 parent 63aacb6 commit 9a7fd37
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 6 deletions.
4 changes: 3 additions & 1 deletion src/crud/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ export interface CrudApi {
*
* @param collection Type of the resource, collection name.
* @param id Id of the resource, document name.
* @param silent When true, does not throw an error if the collection or
* resource does not exist. Default is false.
*/
del: (collection: CrudCollection, id: string) => Promise<void>;
del: (collection: CrudCollection, id: string, silent?: boolean) => Promise<void>;

/**
* Fetches information about a resource.
Expand Down
17 changes: 12 additions & 5 deletions src/fsa-crud/FsaCrud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ export class FsaCrud implements crud.CrudApi {
}
}

protected async getFile(collection: crud.CrudCollection, id: string): Promise<fsa.IFileSystemFileHandle> {
protected async getFile(collection: crud.CrudCollection, id: string): Promise<[dir: fsa.IFileSystemDirectoryHandle, file: fsa.IFileSystemFileHandle]> {
const dir = await this.getDir(collection, false);
try {
const file = await dir.getFileHandle(id, {create: false});
return file;
return [dir, file];
} catch (error) {
if (error.name === 'NotFoundError')
throw new DOMException(`Resource "${id}" in /${collection.join('/')} not found`, 'ResourceNotFound');
Expand Down Expand Up @@ -68,14 +68,21 @@ export class FsaCrud implements crud.CrudApi {
public readonly get = async (collection: crud.CrudCollection, id: string): Promise<Uint8Array> => {
assertType(collection, 'get', 'crudfs');
assertName(id, 'get', 'crudfs');
const file = await this.getFile(collection, id);
const [, file] = await this.getFile(collection, id);
const blob = await file.getFile();
const buffer = await blob.arrayBuffer();
return new Uint8Array(buffer);
};

public readonly del = async (collection: crud.CrudCollection, id: string): Promise<void> => {
throw new Error('Not implemented');
public readonly del = async (collection: crud.CrudCollection, id: string, silent?: boolean): Promise<void> => {
assertType(collection, 'get', 'crudfs');
assertName(id, 'get', 'crudfs');
try {
const [dir] = await this.getFile(collection, id);
await dir.removeEntry(id, {recursive: false});
} catch (error) {
if (!silent) throw error;
}
};

public readonly info = async (collection: crud.CrudCollection, id?: string): Promise<crud.CrudResourceInfo> => {
Expand Down
55 changes: 55 additions & 0 deletions src/fsa-crud/__tests__/FsaCrud.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,59 @@ onlyOnNode20('FsaCrud', () => {
expect(blob).toStrictEqual(b('abc'));
});
});

describe('.del()', () => {
test('throws if the type is not valid', async () => {
const {crud} = setup();
const [, err] = await of(crud.del(['', 'foo'], 'bar'));
expect(err).toBeInstanceOf(TypeError);
});

test('throws if id is not valid', async () => {
const {crud} = setup();
const [, err] = await of(crud.del(['foo'], ''));
expect(err).toBeInstanceOf(TypeError);
});


describe('when collection does not exist', () => {
test('throws by default', async () => {
const {crud} = setup();
const [, err] = await of(crud.del(['foo'], 'bar'));
expect(err).toBeInstanceOf(DOMException);
expect((<any>err).name).toBe('CollectionNotFound');
});

test('does not throw when "silent" flag set', async () => {
const {crud} = setup();
await crud.del(['foo'], 'bar', true);
});
});

describe('when collection is found but resource is not', () => {
test('throws by default', async () => {
const {crud} = setup();
await crud.put(['foo'], 'bar', b('abc'));
const [, err] = await of(crud.del(['foo'], 'baz'));
expect(err).toBeInstanceOf(DOMException);
expect((<any>err).name).toBe('ResourceNotFound');
});

test('does not throw when "silent" flag set', async () => {
const {crud} = setup();
await crud.put(['foo'], 'bar', b('abc'));
await crud.del(['foo'], 'baz', true);
});
});

test('deletes an existing resource', async () => {
const {crud} = setup();
await crud.put(['foo'], 'bar', b('abc'));
await crud.get(['foo'], 'bar');
await crud.del(['foo'], 'bar');
const [, err] = await of(crud.get(['foo'], 'bar'));
expect(err).toBeInstanceOf(DOMException);
expect((<any>err).name).toBe('ResourceNotFound');
});
});
});

0 comments on commit 9a7fd37

Please sign in to comment.