@xitkov/core 2.4.9 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,18 @@
1
1
  import type { Application } from 'express';
2
2
  import { Config, IAuth } from '..';
3
+ type Functions = 'find' | 'get' | 'create' | 'update' | 'patch' | 'remove';
4
+ /**
5
+ * Validate one method's input and return the coerced result.
6
+ *
7
+ * Joi converts as well as checks: `"25"` becomes `25`, and a declared default
8
+ * fills a missing field. The caller must therefore use the returned value —
9
+ * discarding it would validate the request and then hand the service the raw
10
+ * one, so defaults would silently never arrive.
11
+ */
12
+ export declare function validate(Validator: any, func: string, value: any): Promise<any>;
13
+ /** Where a method's validated input sits in the service call. */
14
+ export declare const VALIDATED_INDEX: Record<Functions, number>;
3
15
  export declare function registerServices(app: Application, auth?: IAuth, database?: Config['database']): Promise<{
4
16
  [serviceName: string]: any;
5
17
  }>;
18
+ export {};
@@ -27,7 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  var _a, _b, _c, _d, _e;
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.registerServices = void 0;
30
+ exports.registerServices = exports.VALIDATED_INDEX = exports.validate = void 0;
31
31
  // eslint-disable-next-line node/no-unsupported-features/node-builtins
32
32
  const fs_1 = require("fs");
33
33
  const path_1 = __importDefault(require("path"));
@@ -35,6 +35,14 @@ const express_1 = require("express");
35
35
  const __1 = require("..");
36
36
  const errors_1 = require("../errors");
37
37
  const auth_1 = require("./auth");
38
+ /**
39
+ * Validate one method's input and return the coerced result.
40
+ *
41
+ * Joi converts as well as checks: `"25"` becomes `25`, and a declared default
42
+ * fills a missing field. The caller must therefore use the returned value —
43
+ * discarding it would validate the request and then hand the service the raw
44
+ * one, so defaults would silently never arrive.
45
+ */
38
46
  async function validate(Validator, func, value) {
39
47
  const schema = await Validator[func];
40
48
  if (schema) {
@@ -48,6 +56,16 @@ async function validate(Validator, func, value) {
48
56
  }
49
57
  return value;
50
58
  }
59
+ exports.validate = validate;
60
+ /** Where a method's validated input sits in the service call. */
61
+ exports.VALIDATED_INDEX = {
62
+ find: 0,
63
+ get: 1,
64
+ create: 0,
65
+ patch: 1,
66
+ update: 1,
67
+ remove: 1,
68
+ };
51
69
  async function hooks(Hooks, func, parameters, methodName) {
52
70
  var _a;
53
71
  const allHooks = Hooks[func];
@@ -146,7 +164,9 @@ async function registerServices(app, auth, database) {
146
164
  serviceConfig.dialect = (_c = database === null || database === void 0 ? void 0 : database.dialect) !== null && _c !== void 0 ? _c : 'mongodb';
147
165
  const service = new (await (_e = servicePath, Promise.resolve().then(() => __importStar(require(_e))))).default(serviceConfig);
148
166
  services[serviceName] = service;
149
- const router = (0, express_1.Router)();
167
+ // `mergeParams` lets a nested handler read the parent id from the mount
168
+ // path rather than only its own parameters.
169
+ const router = (0, express_1.Router)({ mergeParams: true });
150
170
  for (const { method, url, func } of methods) {
151
171
  const callback = async (req, res) => {
152
172
  var _a, _b;
@@ -185,47 +205,48 @@ async function registerServices(app, auth, database) {
185
205
  const user = req.user;
186
206
  const { id } = params;
187
207
  let parameters = [];
188
- let validatorValue;
189
208
  switch (func) {
190
209
  case 'find':
191
210
  parameters = [query, user, req];
192
- validatorValue = query;
193
211
  break;
194
212
  case 'get':
195
213
  parameters = [id, query, user, req];
196
- validatorValue = query;
197
214
  break;
198
215
  case 'create':
199
216
  parameters = [body, query, user, req];
200
- validatorValue = body;
201
217
  break;
202
218
  case 'patch':
203
219
  parameters = [id, body, query, user, req];
204
- validatorValue = body;
205
220
  break;
206
221
  case 'update':
207
222
  parameters = [id, body, query, user, req];
208
- validatorValue = body;
209
223
  break;
210
224
  case 'remove':
211
225
  parameters = [id, query, user, req];
212
- validatorValue = query;
213
226
  break;
214
227
  }
215
- if (Hooks) {
216
- await hooks(Hooks, 'all', parameters, func);
217
- await hooks(Hooks, func, parameters, func);
218
- }
219
- if (service.filtering !== false && func === 'find') {
220
- parameters[0] = (0, __1.addQuerySupport)(...parameters, func);
221
- }
222
228
  if (service[func] == undefined) {
223
229
  return res.status(404).send({
224
230
  message: "Not found"
225
231
  });
226
232
  }
233
+ // Validation runs before the hooks so a hook inspects the same
234
+ // coerced value the service receives, and writing the result back
235
+ // into `parameters` is what carries Joi's defaults and type
236
+ // conversions through to the service.
227
237
  if (Validator) {
228
- await validate(Validator, func, validatorValue);
238
+ const index = exports.VALIDATED_INDEX[func];
239
+ parameters[index] = await validate(Validator, func, parameters[index]);
240
+ }
241
+ if (Hooks) {
242
+ await hooks(Hooks, 'all', parameters, func);
243
+ await hooks(Hooks, func, parameters, func);
244
+ }
245
+ // Filter translation comes last: it rewrites the query in place, so
246
+ // running it before validation would validate a value the service
247
+ // never sees.
248
+ if (service.filtering !== false && func === 'find') {
249
+ parameters[0] = (0, __1.addQuerySupport)(...parameters, func);
229
250
  }
230
251
  const response = await service[func](...parameters);
231
252
  let data = response;
@@ -264,7 +285,12 @@ async function registerServices(app, auth, database) {
264
285
  router[method](url, callback);
265
286
  }
266
287
  app.set('services', services);
267
- app.use(`/${serviceName}`, router);
288
+ // `parent = 'agents'` mounts at /agents/:parentId/<service> instead of
289
+ // /<service>, so a child is only reachable through its parent.
290
+ const mountPath = service.parent
291
+ ? `/${service.parent}/:parentId/${serviceName}`
292
+ : `/${serviceName}`;
293
+ app.use(mountPath, router);
268
294
  }
269
295
  return services;
270
296
  }
@@ -1 +1 @@
1
- {"version":3,"file":"register-services.js","sourceRoot":"","sources":["../../src/services/register-services.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"register-services.js","sourceRoot":"","sources":["../../src/services/register-services.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,14 @@ export declare class XitkovService<T, U extends Dialect = DefaultDialect> implem
24
24
  private service;
25
25
  private Model;
26
26
  pagination?: boolean;
27
+ /**
28
+ * Mount beneath another service, by name.
29
+ *
30
+ * `parent = "agents"` serves this resource at
31
+ * `/agents/:parentId/<service>`, and the handler reads `req.params.parentId`.
32
+ * Unset means a top-level resource.
33
+ */
34
+ parent?: string;
27
35
  static defaultDialect: Dialect;
28
36
  static setDefaultDialect(dialect: Dialect): void;
29
37
  constructor({ Model, dialect, pagination }: IXitovServiceProps);
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/services/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/services/service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xitkov/core",
3
- "version": "2.4.9",
3
+ "version": "2.5.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -31,6 +31,7 @@
31
31
  "@types/node": "^14.11.2",
32
32
  "gts": "^3.1.0",
33
33
  "jest": "^30.4.2",
34
+ "joi": "^18.2.9",
34
35
  "sqlite3": "^6.0.1",
35
36
  "ts-jest": "^29.4.11",
36
37
  "typescript": "^4.0.3"
@@ -20,7 +20,15 @@ interface Methods {
20
20
  func: Functions;
21
21
  }
22
22
 
23
- async function validate(Validator: any, func: string, value: any) {
23
+ /**
24
+ * Validate one method's input and return the coerced result.
25
+ *
26
+ * Joi converts as well as checks: `"25"` becomes `25`, and a declared default
27
+ * fills a missing field. The caller must therefore use the returned value —
28
+ * discarding it would validate the request and then hand the service the raw
29
+ * one, so defaults would silently never arrive.
30
+ */
31
+ export async function validate(Validator: any, func: string, value: any) {
24
32
  const schema = await Validator[func]
25
33
  if (schema) {
26
34
  try {
@@ -33,6 +41,16 @@ async function validate(Validator: any, func: string, value: any) {
33
41
  return value
34
42
  }
35
43
 
44
+ /** Where a method's validated input sits in the service call. */
45
+ export const VALIDATED_INDEX: Record<Functions, number> = {
46
+ find: 0,
47
+ get: 1,
48
+ create: 0,
49
+ patch: 1,
50
+ update: 1,
51
+ remove: 1,
52
+ }
53
+
36
54
  async function hooks(Hooks: any, func: string, parameters: any[], methodName: string) {
37
55
  const allHooks = Hooks[func]
38
56
 
@@ -137,7 +155,9 @@ export async function registerServices(app: Application, auth?: IAuth, database?
137
155
 
138
156
  const service = new (await import(servicePath)).default(serviceConfig);
139
157
  services[serviceName] = service
140
- const router = Router();
158
+ // `mergeParams` lets a nested handler read the parent id from the mount
159
+ // path rather than only its own parameters.
160
+ const router = Router({mergeParams: true});
141
161
  for (const {method, url, func} of methods) {
142
162
  const callback = async (req: Request, res: Response) => {
143
163
  const { required, baseURL } = auth ?? {}
@@ -180,48 +200,52 @@ export async function registerServices(app: Application, auth?: IAuth, database?
180
200
  const user = (req as any).user
181
201
  const {id} = params;
182
202
  let parameters: any[] = [];
183
- let validatorValue
184
203
  switch (func) {
185
204
  case 'find':
186
205
  parameters = [query, user, req];
187
- validatorValue = query
188
206
  break;
189
207
  case 'get':
190
208
  parameters = [id, query, user, req];
191
- validatorValue = query
192
209
  break;
193
210
  case 'create':
194
211
  parameters = [body, query, user, req];
195
- validatorValue = body
196
212
  break;
197
213
  case 'patch':
198
214
  parameters = [id, body, query, user, req];
199
- validatorValue = body
200
215
  break;
201
216
  case 'update':
202
217
  parameters = [id, body, query, user, req];
203
- validatorValue = body
204
218
  break;
205
219
  case 'remove':
206
220
  parameters = [id, query, user, req];
207
- validatorValue = query
208
221
  break;
209
222
  }
210
- if (Hooks) {
211
- await hooks(Hooks, 'all', parameters, func)
212
- await hooks(Hooks, func, parameters, func)
213
- }
214
- if (service.filtering !== false && func === 'find') {
215
- parameters[0] = addQuerySupport(...parameters, func)
216
- }
217
223
 
218
224
  if(service[func] == undefined) {
219
225
  return res.status(404).send({
220
226
  message: "Not found"
221
227
  });
222
228
  }
229
+
230
+ // Validation runs before the hooks so a hook inspects the same
231
+ // coerced value the service receives, and writing the result back
232
+ // into `parameters` is what carries Joi's defaults and type
233
+ // conversions through to the service.
223
234
  if (Validator) {
224
- await validate(Validator, func, validatorValue)
235
+ const index = VALIDATED_INDEX[func]
236
+ parameters[index] = await validate(Validator, func, parameters[index])
237
+ }
238
+
239
+ if (Hooks) {
240
+ await hooks(Hooks, 'all', parameters, func)
241
+ await hooks(Hooks, func, parameters, func)
242
+ }
243
+
244
+ // Filter translation comes last: it rewrites the query in place, so
245
+ // running it before validation would validate a value the service
246
+ // never sees.
247
+ if (service.filtering !== false && func === 'find') {
248
+ parameters[0] = addQuerySupport(...parameters, func)
225
249
  }
226
250
 
227
251
  const response = await service[func](...parameters)
@@ -262,7 +286,13 @@ export async function registerServices(app: Application, auth?: IAuth, database?
262
286
  }
263
287
  app.set('services', services)
264
288
 
265
- app.use(`/${serviceName}`, router);
289
+ // `parent = 'agents'` mounts at /agents/:parentId/<service> instead of
290
+ // /<service>, so a child is only reachable through its parent.
291
+ const mountPath = service.parent
292
+ ? `/${service.parent}/:parentId/${serviceName}`
293
+ : `/${serviceName}`;
294
+
295
+ app.use(mountPath, router);
266
296
  }
267
297
  return services;
268
298
  }
@@ -41,6 +41,15 @@ export class XitkovService<T, U extends Dialect = DefaultDialect> implements Int
41
41
  private Model: ModelType<T, U>
42
42
  pagination?: boolean;
43
43
 
44
+ /**
45
+ * Mount beneath another service, by name.
46
+ *
47
+ * `parent = "agents"` serves this resource at
48
+ * `/agents/:parentId/<service>`, and the handler reads `req.params.parentId`.
49
+ * Unset means a top-level resource.
50
+ */
51
+ parent?: string;
52
+
44
53
  static defaultDialect: Dialect = 'mongodb';
45
54
 
46
55
  static setDefaultDialect(dialect: Dialect) {