UNPKG

@feathersjs/memory

Version:
211 lines 7.79 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MemoryService = exports.MemoryAdapter = void 0; exports.memory = memory; const errors_1 = require("@feathersjs/errors"); const commons_1 = require("@feathersjs/commons"); const adapter_commons_1 = require("@feathersjs/adapter-commons"); const sift_1 = __importDefault(require("sift")); const _select = (data, params, ...args) => { const base = (0, adapter_commons_1.select)(params, ...args); return base(JSON.parse(JSON.stringify(data))); }; class MemoryAdapter extends adapter_commons_1.AdapterBase { constructor(options = {}) { super({ id: 'id', matcher: sift_1.default, sorter: adapter_commons_1.sorter, store: {}, startId: 0, ...options }); this._uId = this.options.startId; this.store = { ...this.options.store }; } async getEntries(_params) { const params = _params || {}; return this._find({ ...params, paginate: false }); } getQuery(params) { const { $skip, $sort, $limit, $select, ...query } = params.query || {}; return { query, filters: { $skip, $sort, $limit, $select } }; } async _find(params = {}) { const { paginate } = this.getOptions(params); const { query, filters } = this.getQuery(params); let values = commons_1._.values(this.store); const hasSkip = filters.$skip !== undefined; const hasSort = filters.$sort !== undefined; const hasLimit = filters.$limit !== undefined; const hasQuery = commons_1._.keys(query).length > 0; if (hasSort) { values.sort(this.options.sorter(filters.$sort)); } if (paginate) { if (hasQuery) { values = values.filter(this.options.matcher(query)); } const total = values.length; if (hasSkip) { values = values.slice(filters.$skip); } if (hasLimit) { values = values.slice(0, filters.$limit); } const result = { total, limit: filters.$limit, skip: filters.$skip || 0, data: values.map((value) => _select(value, params, this.id)) }; return result; } /* Without pagination, we don't have to match every result and gain considerable performance improvements with a breaking for loop. */ if (hasQuery || hasLimit || hasSkip) { let skipped = 0; const matcher = this.options.matcher(query); const matched = []; if (hasLimit && filters.$limit === 0) { return []; } for (let index = 0, length = values.length; index < length; index++) { const value = values[index]; if (hasQuery && !matcher(value, index, values)) { continue; } if (hasSkip && filters.$skip > skipped) { skipped++; continue; } matched.push(_select(value, params, this.id)); if (hasLimit && filters.$limit === matched.length) { break; } } return matched; } return values.map((value) => _select(value, params, this.id)); } async _get(id, params = {}) { const { query } = this.getQuery(params); if (id in this.store) { const value = this.store[id]; if (this.options.matcher(query)(value)) { return _select(value, params, this.id); } } throw new errors_1.NotFound(`No record found for id '${id}'`); } async _create(data, params = {}) { if (Array.isArray(data)) { return Promise.all(data.map((current) => this._create(current, params))); } const id = data[this.id] || this._uId++; const current = commons_1._.extend({}, data, { [this.id]: id }); const result = (this.store[id] = current); return _select(result, params, this.id); } async _update(id, data, params = {}) { if (id === null || Array.isArray(data)) { throw new errors_1.BadRequest("You can not replace multiple instances. Did you mean 'patch'?"); } const oldEntry = await this._get(id); // We don't want our id to change type if it can be coerced const oldId = oldEntry[this.id]; // eslint-disable-next-line eqeqeq id = oldId == id ? oldId : id; this.store[id] = commons_1._.extend({}, data, { [this.id]: id }); return this._get(id, params); } async _patch(id, data, params = {}) { if (id === null && !this.allowsMulti('patch', params)) { throw new errors_1.MethodNotAllowed('Can not patch multiple entries'); } const { query } = this.getQuery(params); const patchEntry = (entry) => { const currentId = entry[this.id]; this.store[currentId] = commons_1._.extend(this.store[currentId], commons_1._.omit(data, this.id)); return _select(this.store[currentId], params, this.id); }; if (id === null) { const entries = await this.getEntries({ ...params, query }); return entries.map(patchEntry); } return patchEntry(await this._get(id, params)); // Will throw an error if not found } async _remove(id, params = {}) { if (id === null && !this.allowsMulti('remove', params)) { throw new errors_1.MethodNotAllowed('Can not remove multiple entries'); } const { query } = this.getQuery(params); if (id === null) { const entries = await this.getEntries({ ...params, query }); return Promise.all(entries.map((current) => this._remove(current[this.id], params))); } const entry = await this._get(id, params); delete this.store[id]; return entry; } } exports.MemoryAdapter = MemoryAdapter; class MemoryService extends MemoryAdapter { async find(params) { return this._find({ ...params, query: await this.sanitizeQuery(params) }); } async get(id, params) { return this._get(id, { ...params, query: await this.sanitizeQuery(params) }); } async create(data, params) { if (Array.isArray(data) && !this.allowsMulti('create', params)) { throw new errors_1.MethodNotAllowed('Can not create multiple entries'); } return this._create(data, params); } async update(id, data, params) { return this._update(id, data, { ...params, query: await this.sanitizeQuery(params) }); } async patch(id, data, params) { const { $limit, ...query } = await this.sanitizeQuery(params); return this._patch(id, data, { ...params, query }); } async remove(id, params) { const { $limit, ...query } = await this.sanitizeQuery(params); return this._remove(id, { ...params, query }); } } exports.MemoryService = MemoryService; function memory(options = {}) { return new MemoryService(options); } //# sourceMappingURL=index.js.map