Skip to content

Instantly share code, notes, and snippets.

@mgabeler-lee-6rs
Created May 30, 2019 19:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgabeler-lee-6rs/6f30a3e117182060cc88a8d20e6ed914 to your computer and use it in GitHub Desktop.
Save mgabeler-lee-6rs/6f30a3e117182060cc88a8d20e6ed914 to your computer and use it in GitHub Desktop.
import * as _ from 'lodash';
import {Constructor} from '@loopback/context';
import {
DefaultCrudRepository,
Entity,
juggler,
DataObject,
Options,
EntityNotFoundError,
Filter,
} from '@loopback/repository';
export abstract class BugfixedRestRepository<T extends Entity, ID> extends DefaultCrudRepository<T, ID> {
constructor(
entityClass: typeof Entity & Constructor<T>,
dataSource: juggler.DataSource,
) {
super(entityClass, dataSource);
}
async find(filter?: Filter<T>, options?: Options): Promise<T[]> {
return await super.find(filter ? {filter} as any : undefined, options);
}
async findOne(filter?: Filter<T>, options?: Options): Promise<T | null> {
filter = filter || {};
// re-apply some logic that we are going to cause to be skipped in the super class
filter.limit = 1;
filter.offset = 0;
filter.skip = 0;
const results = await super.find({filter} as any, options);
if (!results.length) {
return null;
} else {
return results[0];
}
}
async findById(id: ID, filter?: Filter<T>, options?: Options): Promise<T> {
if (!filter) {
try {
return await super.findById(id, filter, options);
} catch (err) {
if (err.statusCode && typeof err.statusCode === 'number' && err.statusCode >= 400 && err.statusCode < 500) {
throw new EntityNotFoundError(this.entityClass, id);
}
}
}
// can't direct call super on this one because it rebuilds the query object
// return await super.findById(id, filter ? {filter} as any : undefined, options);
const result = await this.findOne(_.merge({}, filter, {where: {[this.modelClass.definition.idName()]: id}}));
if (result === null) {
throw new EntityNotFoundError(this.entityClass, id);
} else {
return result;
}
}
async updateById(id: ID, data: DataObject<T>, options?: Options): Promise<void> {
// redirect to method that works
return await this.updateAttributes(id, data, options);
}
// TODO: other methods probably need bug fixing too
// extended methods
async updateAttributes(
id: ID,
data: DataObject<T>,
options?: Options,
): Promise<void> {
options = options || {};
if (!('validate' in options)) {
// suppress validation unless explicitly requested, as we are specifically only patching a subset of attrs
options.validate = false;
}
// eslint-disable-next-line 6river/new-cap
const fakeInstance = new this.modelClass({[this.modelClass.definition.idName()]: id});
try {
await fakeInstance.updateAttributes(data, options);
} catch (err) {
if (err.statusCode === 404) {
throw new EntityNotFoundError(this.entityClass, id);
}
throw err;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment