Skip to content

Commit

Permalink
feat(core): Implement asset binary deletion
Browse files Browse the repository at this point in the history
Relates to #306
  • Loading branch information
michaelbromley committed Apr 15, 2020
1 parent 65be8c8 commit b8fc937
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,48 @@ import { Stream } from 'stream';
*/
export interface AssetStorageStrategy {
/**
* @description
* Writes a buffer to the store and returns a unique identifier for that
* file such as a file path or a URL.
*/
writeFileFromBuffer(fileName: string, data: Buffer): Promise<string>;

/**
* @description
* Writes a readable stream to the store and returns a unique identifier for that
* file such as a file path or a URL.
*/
writeFileFromStream(fileName: string, data: Stream): Promise<string>;

/**
* Reads a file based on an identifier which was generated by the writeFile
* method, and returns the file in binary form.
* @description
* Reads a file based on an identifier which was generated by the a writeFile
* method, and returns the as a Buffer.
*/
readFileToBuffer(identifier: string): Promise<Buffer>;

/**
* Reads a file based on an identifier which was generated by the writeFile
* method, and returns the file in binary form.
* @description
* Reads a file based on an identifier which was generated by the a writeFile
* method, and returns the file as a Stream.
*/
readFileToStream(identifier: string): Promise<Stream>;

/**
* @description
* Deletes a file from the storage.
*/
deleteFile(identifier: string): Promise<void>;

/**
* @description
* Check whether a file with the given name already exists. Used to avoid
* naming conflicts before saving the file.
*/
fileExists(fileName: string): Promise<boolean>;

/**
* @description
* Convert an identifier as generated by the writeFile... methods into an absolute
* url (if it is not already in that form). If no conversion step is needed
* (i.e. the identifier is already an absolute url) then this method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export class NoAssetStorageStrategy implements AssetStorageStrategy {
throw new InternalServerError(errorMessage);
}

deleteFile(identifier: string): Promise<void> {
throw new InternalServerError(errorMessage);
}

toAbsoluteUrl(request: Request, identifier: string): string {
throw new InternalServerError(errorMessage);
}
Expand Down
12 changes: 9 additions & 3 deletions packages/core/src/service/services/asset.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export class AssetService {
});
assets = (entityWithAssets && entityWithAssets.assets) || [];
}
return assets.sort((a, b) => a.position - b.position).map((a) => a.asset);
return assets.sort((a, b) => a.position - b.position).map(a => a.asset);
}

async updateFeaturedAsset<T extends EntityWithAssets>(entity: T, input: EntityAssetInput): Promise<T> {
Expand Down Expand Up @@ -133,7 +133,7 @@ export class AssetService {
if (assetIds && assetIds.length) {
const assets = await this.connection.getRepository(Asset).findByIds(assetIds);
const sortedAssets = assetIds
.map((id) => assets.find((a) => idsAreEqual(a.id, id)))
.map(id => assets.find(a => idsAreEqual(a.id, id)))
.filter(notNullOrUndefined);
await this.removeExistingOrderableAssets(entity);
entity.assets = await this.createOrderableAssets(entity, sortedAssets);
Expand Down Expand Up @@ -185,6 +185,12 @@ export class AssetService {
// after deletion (the .remove() method sets it to undefined)
const deletedAsset = new Asset(asset);
await this.connection.getRepository(Asset).remove(asset);
try {
await this.configService.assetOptions.assetStorageStrategy.deleteFile(asset.source);
await this.configService.assetOptions.assetStorageStrategy.deleteFile(asset.preview);
} catch (e) {
Logger.error(`error.could-not-delete-asset-file`, undefined, e.stack);
}
this.eventBus.publish(new AssetEvent(ctx, deletedAsset, 'deleted'));
return {
result: DeletionResult.DELETED,
Expand Down Expand Up @@ -303,7 +309,7 @@ export class AssetService {
private getOrderableAssetType(entity: EntityWithAssets): Type<OrderableAsset> {
const assetRelation = this.connection
.getRepository(entity.constructor)
.metadata.relations.find((r) => r.propertyName === 'assets');
.metadata.relations.find(r => r.propertyName === 'assets');
if (!assetRelation || typeof assetRelation.type === 'string') {
throw new InternalServerError('error.could-not-find-matching-orderable-asset');
}
Expand Down
4 changes: 4 additions & 0 deletions packages/testing/src/config/testing-asset-storage-strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,8 @@ export class TestingAssetStorageStrategy implements AssetStorageStrategy {
fileExists(fileName: string): Promise<boolean> {
return Promise.resolve(false);
}

deleteFile(identifier: string): Promise<void> {
return Promise.resolve();
}
}

0 comments on commit b8fc937

Please sign in to comment.