UNPKG

7.5 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.NeDbAdapter = void 0;
7const adapter_commons_1 = require("@feathersjs/adapter-commons");
8const commons_1 = require("@feathersjs/commons");
9const errors_1 = require("@feathersjs/errors");
10const crypto_1 = __importDefault(require("crypto"));
11function errorHandler(error) {
12 throw error;
13}
14class NeDbAdapter extends adapter_commons_1.AdapterBase {
15 constructor(options) {
16 if (!options || !options.Model) {
17 throw new Error("NeDB datastore `Model` needs to be provided");
18 }
19 super({
20 id: "_id",
21 ...options,
22 });
23 }
24 getSelect(select) {
25 if (Array.isArray(select)) {
26 const result = { [this.id]: 1 };
27 select.forEach((name) => (result[name] = 1));
28 return result;
29 }
30 return select;
31 }
32 filterQuery(id, params) {
33 const options = this.getOptions(params);
34 const { $select, $sort, $limit: _limit, $skip = 0, ...query } = (params.query || {});
35 const $limit = (0, adapter_commons_1.getLimit)(_limit, options.paginate);
36 if (id !== null) {
37 query.$and = (query.$and || []).concat({
38 [this.id]: id,
39 });
40 }
41 return {
42 filters: { $select, $sort, $limit, $skip },
43 query,
44 };
45 }
46 async _findOrGet(id, params) {
47 return id === null ? await this._find(params) : await this._get(id, params);
48 }
49 normalizeId(id, data) {
50 if (id !== null) {
51 // If not using the default Mongo _id field set the ID to its
52 // previous value. This prevents orphaned documents.
53 return {
54 ...data,
55 [this.id]: id,
56 };
57 }
58 return data;
59 }
60 async _find(params = {}) {
61 const { Model, paginate } = this.getOptions(params);
62 const { filters: { $select, $sort, $limit, $skip }, query, } = this.filterQuery(null, params);
63 const countDocuments = async () => {
64 if (paginate && paginate.default) {
65 return await Model.countAsync(query);
66 }
67 return Promise.resolve(0);
68 };
69 const q = $select
70 ? Model.findAsync(query, this.getSelect($select))
71 : Model.findAsync(query);
72 // Handle $sort
73 if ($sort) {
74 q.sort($sort);
75 }
76 // Handle $limit
77 if ($limit) {
78 q.limit($limit);
79 }
80 if ($skip) {
81 q.skip($skip);
82 }
83 const [request, total] = await Promise.all([q, countDocuments()]);
84 const page = {
85 total,
86 limit: $limit,
87 skip: $skip || 0,
88 data: $limit === 0 ? [] : (await request),
89 };
90 return paginate && paginate.default ? page : page.data;
91 }
92 _get(id, params = {}) {
93 const { Model } = this.getOptions(params);
94 const { query, filters: { $select }, } = this.filterQuery(id, params);
95 return $select
96 ? Model.findOneAsync(query, this.getSelect($select))
97 : Model.findOneAsync(query)
98 .then((data) => {
99 if (data == null) {
100 throw new errors_1.NotFound(`No record found for id '${id}'`);
101 }
102 return data;
103 })
104 .catch(errorHandler);
105 }
106 async _create(_data, params = {}) {
107 if (Array.isArray(_data) && !this.allowsMulti("create", params)) {
108 throw new errors_1.MethodNotAllowed("Can not create multiple entries");
109 }
110 const { Model } = this.getOptions(params);
111 const addId = (item) => {
112 if (this.id !== "_id" && item[this.id] === undefined) {
113 return Object.assign({
114 [this.id]: crypto_1.default.randomBytes(8).toString("hex"),
115 }, item);
116 }
117 return item;
118 };
119 const data = Array.isArray(_data) ? _data.map(addId) : addId(_data);
120 //@ts-ignore
121 return Model.insertAsync(data)
122 .then((0, adapter_commons_1.select)(params, this.id))
123 .catch(errorHandler);
124 }
125 async _update(id, data, params = {}) {
126 if (id === null || Array.isArray(data)) {
127 throw new errors_1.BadRequest("You can not replace multiple instances. Did you mean 'patch'?");
128 }
129 const { Model } = this.getOptions(params);
130 const { query } = this.filterQuery(id, params);
131 const entry = commons_1._.omit(data, "_id");
132 if (this.id !== "_id" || (params.nedb && params.nedb.upsert)) {
133 entry[this.id] = id;
134 }
135 const response = await Model.updateAsync(query, entry, {
136 returnUpdatedDocs: true,
137 multi: false,
138 ...params.nedb,
139 });
140 if (response.affectedDocuments == null) {
141 throw new errors_1.NotFound(`No record found for id '${id}'`);
142 }
143 if (Array.isArray(response.affectedDocuments)) {
144 return response.affectedDocuments[0];
145 }
146 return (0, adapter_commons_1.select)(params, this.id)(response.affectedDocuments);
147 }
148 async _patch(id, data, params = {}) {
149 if (id === null && !this.allowsMulti("patch", params)) {
150 throw new errors_1.MethodNotAllowed("Can not patch multiple entries");
151 }
152 const { Model } = this.getOptions(params);
153 const { query, filters: { $select, $sort, $limit, $skip }, } = this.filterQuery(id, params);
154 const updateOptions = {
155 returnUpdatedDocs: true,
156 multi: id == null ? true : false,
157 };
158 //@ts-ignore
159 const updateData = Object.keys(data).reduce((result, key) => {
160 if (key.indexOf("$") === 0) {
161 //@ts-ignore
162 result[key] = data[key];
163 }
164 else if (key !== "_id" && key !== this.id) {
165 //@ts-ignore
166 result.$set[key] = data[key];
167 }
168 return result;
169 }, { $set: {} });
170 const response = await Model.updateAsync(query, updateData, updateOptions);
171 if (response.affectedDocuments == null) {
172 throw new errors_1.NotFound(`No record found for id '${id}'`);
173 }
174 return (0, adapter_commons_1.select)(params, this.id)(response.affectedDocuments);
175 }
176 async _remove(id, params = {}) {
177 if (id === null && !this.allowsMulti("remove", params)) {
178 throw new errors_1.MethodNotAllowed("Can not remove multiple entries");
179 }
180 const { Model } = this.getOptions(params);
181 const { query, filters: { $select }, } = this.filterQuery(id, params);
182 const deleteOptions = {
183 multi: id == null ? true : false,
184 };
185 const findParams = {
186 ...params,
187 paginate: false,
188 query: {
189 ...query,
190 $select,
191 },
192 };
193 return this._findOrGet(id, findParams)
194 .then(async (items) => {
195 await Model.removeAsync(query, deleteOptions);
196 return items;
197 })
198 .catch(errorHandler);
199 }
200}
201exports.NeDbAdapter = NeDbAdapter;
202//# sourceMappingURL=adapter.js.map
\No newline at end of file