@feathersjs/schema 5.0.0-pre.22 → 5.0.0-pre.23
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.
- package/CHANGELOG.md +17 -0
- package/lib/hooks/index.js.map +1 -1
- package/lib/hooks/resolve.d.ts +1 -0
- package/lib/hooks/resolve.js +22 -18
- package/lib/hooks/resolve.js.map +1 -1
- package/lib/hooks/validate.js +3 -3
- package/lib/hooks/validate.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/query.d.ts +9 -9
- package/lib/query.js +32 -26
- package/lib/query.js.map +1 -1
- package/lib/resolver.js +4 -8
- package/lib/resolver.js.map +1 -1
- package/lib/schema.js +1 -1
- package/lib/schema.js.map +1 -1
- package/package.json +10 -9
- package/src/hooks/index.ts +2 -2
- package/src/hooks/resolve.ts +78 -72
- package/src/hooks/validate.ts +18 -18
- package/src/index.ts +8 -8
- package/src/query.ts +73 -64
- package/src/resolver.ts +61 -59
- package/src/schema.ts +27 -27
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,23 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [5.0.0-pre.23](https://github.com/feathersjs/feathers/compare/v5.0.0-pre.22...v5.0.0-pre.23) (2022-06-06)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **schema:** Always resolve dispatch in resolveAll and add getDispatch method ([#2645](https://github.com/feathersjs/feathers/issues/2645)) ([145b366](https://github.com/feathersjs/feathers/commit/145b366435695438fbc8db9fdb161162ca9049ad))
|
|
12
|
+
* **schema:** remove `default` from queryProperty schemas ([#2646](https://github.com/feathersjs/feathers/issues/2646)) ([940a2b6](https://github.com/feathersjs/feathers/commit/940a2b6868d2f77f81edb1661f6417ec2ea6e372))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **core:** Rename async hooks to around hooks, allow usual registration format ([#2652](https://github.com/feathersjs/feathers/issues/2652)) ([2a485a0](https://github.com/feathersjs/feathers/commit/2a485a07929184261f27437fc0fdfe5a44694834))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
6
23
|
# [5.0.0-pre.22](https://github.com/feathersjs/feathers/compare/v5.0.0-pre.21...v5.0.0-pre.22) (2022-05-24)
|
|
7
24
|
|
|
8
25
|
|
package/lib/hooks/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAAyB;AACzB,6CAA0B"}
|
package/lib/hooks/resolve.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export declare type ResolveAllSettings<H extends HookContext> = {
|
|
|
13
13
|
dispatch?: Resolver<any, H>;
|
|
14
14
|
};
|
|
15
15
|
export declare const DISPATCH: unique symbol;
|
|
16
|
+
export declare const getDispatch: (value: any) => any;
|
|
16
17
|
export declare const resolveQuery: <T, H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(...resolvers: Resolver<T, H>[]) => (context: H, next?: NextFunction) => Promise<any>;
|
|
17
18
|
export declare const resolveData: <H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(settings: DataResolvers<H> | Resolver<any, H>) => (context: H, next?: NextFunction) => Promise<any>;
|
|
18
19
|
export declare const resolveResult: <T, H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(...resolvers: Resolver<T, H>[]) => (context: H, next?: NextFunction) => Promise<void>;
|
package/lib/hooks/resolve.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveAll = exports.resolveDispatch = exports.resolveResult = exports.resolveData = exports.resolveQuery = exports.DISPATCH = void 0;
|
|
3
|
+
exports.resolveAll = exports.resolveDispatch = exports.resolveResult = exports.resolveData = exports.resolveQuery = exports.getDispatch = exports.DISPATCH = void 0;
|
|
4
4
|
const hooks_1 = require("@feathersjs/hooks");
|
|
5
5
|
const resolver_1 = require("../resolver");
|
|
6
6
|
const getContext = (context) => {
|
|
@@ -20,11 +20,15 @@ const getData = (context) => {
|
|
|
20
20
|
const runResolvers = async (resolvers, data, ctx, status) => {
|
|
21
21
|
let current = data;
|
|
22
22
|
for (const resolver of resolvers) {
|
|
23
|
-
|
|
23
|
+
if (resolver && typeof resolver.resolve === 'function') {
|
|
24
|
+
current = await resolver.resolve(current, ctx, status);
|
|
25
|
+
}
|
|
24
26
|
}
|
|
25
27
|
return current;
|
|
26
28
|
};
|
|
27
29
|
exports.DISPATCH = Symbol('@feathersjs/schema/dispatch');
|
|
30
|
+
const getDispatch = (value) => typeof value === 'object' && value !== null && value[exports.DISPATCH] !== undefined ? value[exports.DISPATCH] : value;
|
|
31
|
+
exports.getDispatch = getDispatch;
|
|
28
32
|
const resolveQuery = (...resolvers) => async (context, next) => {
|
|
29
33
|
var _a;
|
|
30
34
|
const ctx = getContext(context);
|
|
@@ -48,7 +52,7 @@ const resolveData = (settings) => async (context, next) => {
|
|
|
48
52
|
originalContext: context
|
|
49
53
|
};
|
|
50
54
|
if (Array.isArray(data)) {
|
|
51
|
-
context.data = await Promise.all(data.map(current => runResolvers(resolvers, current, ctx, status)));
|
|
55
|
+
context.data = await Promise.all(data.map((current) => runResolvers(resolvers, current, ctx, status)));
|
|
52
56
|
}
|
|
53
57
|
else {
|
|
54
58
|
context.data = await runResolvers(resolvers, data, ctx, status);
|
|
@@ -78,9 +82,9 @@ const resolveResult = (...resolvers) => async (context, next) => {
|
|
|
78
82
|
const ctx = getContext(context);
|
|
79
83
|
const status = context.params.resolve;
|
|
80
84
|
const { isPaginated, data } = getData(context);
|
|
81
|
-
const result = Array.isArray(data)
|
|
82
|
-
await Promise.all(data.map(async (current) => runResolvers(resolvers, current, ctx, status)))
|
|
83
|
-
await runResolvers(resolvers, data, ctx, status);
|
|
85
|
+
const result = Array.isArray(data)
|
|
86
|
+
? await Promise.all(data.map(async (current) => runResolvers(resolvers, current, ctx, status)))
|
|
87
|
+
: await runResolvers(resolvers, data, ctx, status);
|
|
84
88
|
if (isPaginated) {
|
|
85
89
|
context.result.data = result;
|
|
86
90
|
}
|
|
@@ -96,20 +100,22 @@ const resolveDispatch = (...resolvers) => async (context, next) => {
|
|
|
96
100
|
const ctx = getContext(context);
|
|
97
101
|
const status = context.params.resolve;
|
|
98
102
|
const { isPaginated, data } = getData(context);
|
|
99
|
-
const
|
|
103
|
+
const resolveAndGetDispatch = async (current) => {
|
|
100
104
|
const resolved = await runResolvers(resolvers, current, ctx, status);
|
|
101
105
|
return Object.keys(resolved).reduce((res, key) => {
|
|
102
|
-
|
|
103
|
-
const hasDispatch = typeof value === 'object' && value !== null && value[exports.DISPATCH] !== undefined;
|
|
104
|
-
res[key] = hasDispatch ? value[exports.DISPATCH] : value;
|
|
106
|
+
res[key] = (0, exports.getDispatch)(current[key]);
|
|
105
107
|
return res;
|
|
106
108
|
}, {});
|
|
107
109
|
};
|
|
108
|
-
const result = await (Array.isArray(data)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
const result = await (Array.isArray(data)
|
|
111
|
+
? Promise.all(data.map(resolveAndGetDispatch))
|
|
112
|
+
: resolveAndGetDispatch(data));
|
|
113
|
+
const dispatch = isPaginated
|
|
114
|
+
? {
|
|
115
|
+
...context.result,
|
|
116
|
+
data: result
|
|
117
|
+
}
|
|
118
|
+
: result;
|
|
113
119
|
context.dispatch = dispatch;
|
|
114
120
|
Object.defineProperty(context.result, exports.DISPATCH, {
|
|
115
121
|
value: dispatch,
|
|
@@ -120,9 +126,7 @@ const resolveDispatch = (...resolvers) => async (context, next) => {
|
|
|
120
126
|
exports.resolveDispatch = resolveDispatch;
|
|
121
127
|
const resolveAll = (map) => {
|
|
122
128
|
const middleware = [];
|
|
123
|
-
|
|
124
|
-
middleware.push((0, exports.resolveDispatch)(map.dispatch));
|
|
125
|
-
}
|
|
129
|
+
middleware.push((0, exports.resolveDispatch)(map.dispatch));
|
|
126
130
|
if (map.result) {
|
|
127
131
|
middleware.push((0, exports.resolveResult)(map.result));
|
|
128
132
|
}
|
package/lib/hooks/resolve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/hooks/resolve.ts"],"names":[],"mappings":";;;AACA,
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/hooks/resolve.ts"],"names":[],"mappings":"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"}
|
package/lib/hooks/validate.js
CHANGED
|
@@ -16,7 +16,7 @@ const validateQuery = (schema) => async (context, next) => {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
catch (error) {
|
|
19
|
-
throw
|
|
19
|
+
throw error.ajv ? new lib_1.BadRequest(error.message, error.errors) : error;
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
exports.validateQuery = validateQuery;
|
|
@@ -24,14 +24,14 @@ const validateData = (schema) => async (context, next) => {
|
|
|
24
24
|
const data = context.data;
|
|
25
25
|
try {
|
|
26
26
|
if (Array.isArray(data)) {
|
|
27
|
-
context.data = await Promise.all(data.map(current => schema.validate(current)));
|
|
27
|
+
context.data = await Promise.all(data.map((current) => schema.validate(current)));
|
|
28
28
|
}
|
|
29
29
|
else {
|
|
30
30
|
context.data = await schema.validate(data);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
catch (error) {
|
|
34
|
-
throw
|
|
34
|
+
throw error.ajv ? new lib_1.BadRequest(error.message, error.errors) : error;
|
|
35
35
|
}
|
|
36
36
|
if (typeof next === 'function') {
|
|
37
37
|
return next();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/hooks/validate.ts"],"names":[],"mappings":";;;AACA,
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/hooks/validate.ts"],"names":[],"mappings":";;;AACA,6CAAgD;AAGzC,MAAM,aAAa,GACxB,CAAwB,MAAmB,EAAE,EAAE,CAC/C,KAAK,EAAE,OAAU,EAAE,IAAmB,EAAE,EAAE;;IACxC,MAAM,IAAI,GAAG,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,0CAAE,KAAK,KAAI,EAAE,CAAA;IAEzC,IAAI;QACF,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAEzC,OAAO,CAAC,MAAM,GAAG;YACf,GAAG,OAAO,CAAC,MAAM;YACjB,KAAK;SACN,CAAA;QAED,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE;YAC9B,OAAO,IAAI,EAAE,CAAA;SACd;KACF;IAAC,OAAO,KAAU,EAAE;QACnB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,gBAAU,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;KACtE;AACH,CAAC,CAAA;AAnBU,QAAA,aAAa,iBAmBvB;AAEI,MAAM,YAAY,GACvB,CAAwB,MAAmB,EAAE,EAAE,CAC/C,KAAK,EAAE,OAAU,EAAE,IAAmB,EAAE,EAAE;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IAEzB,IAAI;QACF,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACvB,OAAO,CAAC,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;SAClF;aAAM;YACL,OAAO,CAAC,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;SAC3C;KACF;IAAC,OAAO,KAAU,EAAE;QACnB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,gBAAU,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;KACtE;IAED,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE;QAC9B,OAAO,IAAI,EAAE,CAAA;KACd;AACH,CAAC,CAAA;AAlBU,QAAA,YAAY,gBAkBtB"}
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAEA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAEA,2CAAwB;AACxB,6CAA0B;AAC1B,0CAAuB;AACvB,0CAAuB"}
|
package/lib/query.d.ts
CHANGED
|
@@ -23,23 +23,23 @@ export declare type PropertyQuery<D extends JSONSchema> = {
|
|
|
23
23
|
}
|
|
24
24
|
];
|
|
25
25
|
};
|
|
26
|
-
export declare const queryProperty: <T extends import("json-schema-to-ts").JSONSchema7>(
|
|
27
|
-
readonly anyOf: readonly [
|
|
26
|
+
export declare const queryProperty: <T extends import("json-schema-to-ts").JSONSchema7>(def: T) => {
|
|
27
|
+
readonly anyOf: readonly [any, {
|
|
28
28
|
readonly type: "object";
|
|
29
29
|
readonly additionalProperties: false;
|
|
30
30
|
readonly properties: {
|
|
31
|
-
readonly $gt:
|
|
32
|
-
readonly $gte:
|
|
33
|
-
readonly $lt:
|
|
34
|
-
readonly $lte:
|
|
35
|
-
readonly $ne:
|
|
31
|
+
readonly $gt: any;
|
|
32
|
+
readonly $gte: any;
|
|
33
|
+
readonly $lt: any;
|
|
34
|
+
readonly $lte: any;
|
|
35
|
+
readonly $ne: any;
|
|
36
36
|
readonly $in: {
|
|
37
37
|
readonly type: "array";
|
|
38
|
-
readonly items:
|
|
38
|
+
readonly items: any;
|
|
39
39
|
};
|
|
40
40
|
readonly $nin: {
|
|
41
41
|
readonly type: "array";
|
|
42
|
-
readonly items:
|
|
42
|
+
readonly items: any;
|
|
43
43
|
};
|
|
44
44
|
};
|
|
45
45
|
}];
|
package/lib/query.js
CHANGED
|
@@ -1,34 +1,39 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.querySyntax = exports.queryProperties = exports.queryProperty = void 0;
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
4
|
+
const commons_1 = require("@feathersjs/commons");
|
|
5
|
+
const queryProperty = (def) => {
|
|
6
|
+
const definition = commons_1._.omit(def, 'default');
|
|
7
|
+
return {
|
|
8
|
+
anyOf: [
|
|
9
|
+
definition,
|
|
10
|
+
{
|
|
11
|
+
type: 'object',
|
|
12
|
+
additionalProperties: false,
|
|
13
|
+
properties: {
|
|
14
|
+
$gt: definition,
|
|
15
|
+
$gte: definition,
|
|
16
|
+
$lt: definition,
|
|
17
|
+
$lte: definition,
|
|
18
|
+
$ne: definition,
|
|
19
|
+
$in: {
|
|
20
|
+
type: 'array',
|
|
21
|
+
items: definition
|
|
22
|
+
},
|
|
23
|
+
$nin: {
|
|
24
|
+
type: 'array',
|
|
25
|
+
items: definition
|
|
26
|
+
}
|
|
23
27
|
}
|
|
24
28
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
29
|
+
]
|
|
30
|
+
};
|
|
31
|
+
};
|
|
28
32
|
exports.queryProperty = queryProperty;
|
|
29
33
|
const queryProperties = (definition) => Object.keys(definition).reduce((res, key) => {
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
const result = res;
|
|
35
|
+
result[key] = (0, exports.queryProperty)(definition[key]);
|
|
36
|
+
return result;
|
|
32
37
|
}, {});
|
|
33
38
|
exports.queryProperties = queryProperties;
|
|
34
39
|
const querySyntax = (definition) => ({
|
|
@@ -43,11 +48,12 @@ const querySyntax = (definition) => ({
|
|
|
43
48
|
$sort: {
|
|
44
49
|
type: 'object',
|
|
45
50
|
properties: Object.keys(definition).reduce((res, key) => {
|
|
46
|
-
|
|
51
|
+
const result = res;
|
|
52
|
+
result[key] = {
|
|
47
53
|
type: 'number',
|
|
48
54
|
enum: [1, -1]
|
|
49
55
|
};
|
|
50
|
-
return
|
|
56
|
+
return result;
|
|
51
57
|
}, {})
|
|
52
58
|
},
|
|
53
59
|
$select: {
|
package/lib/query.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":";;;AAAA,iDAAuC;AA4BhC,MAAM,aAAa,GAAG,CAAuB,GAAM,EAAE,EAAE;IAC5D,MAAM,UAAU,GAAG,WAAC,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;IACzC,OAAO;QACL,KAAK,EAAE;YACL,UAAU;YACV;gBACE,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;oBACV,GAAG,EAAE,UAAU;oBACf,IAAI,EAAE,UAAU;oBAChB,GAAG,EAAE,UAAU;oBACf,IAAI,EAAE,UAAU;oBAChB,GAAG,EAAE,UAAU;oBACf,GAAG,EAAE;wBACH,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,UAAU;qBAClB;oBACD,IAAI,EAAE;wBACJ,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,UAAU;qBAClB;iBACF;aACF;SACF;KACO,CAAA;AACZ,CAAC,CAAA;AA1BY,QAAA,aAAa,iBA0BzB;AAEM,MAAM,eAAe,GAAG,CAA0C,UAAa,EAAE,EAAE,CACxF,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IAC1C,MAAM,MAAM,GAAG,GAAU,CAAA;IAEzB,MAAM,CAAC,GAAG,CAAC,GAAG,IAAA,qBAAa,EAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;IAE5C,OAAO,MAAM,CAAA;AACf,CAAC,EAAE,EAA6C,CAAC,CAAA;AAPtC,QAAA,eAAe,mBAOuB;AAE5C,MAAM,WAAW,GAAG,CAA0C,UAAa,EAAE,EAAE,CACpF,CAAC;IACC,MAAM,EAAE;QACN,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,CAAC;KACX;IACD,KAAK,EAAE;QACL,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,CAAC;KACX;IACD,KAAK,EAAE;QACL,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACtD,MAAM,MAAM,GAAG,GAAU,CAAA;YAEzB,MAAM,CAAC,GAAG,CAAC,GAAG;gBACZ,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;aACd,CAAA;YAED,OAAO,MAAM,CAAA;QACf,CAAC,EAAE,EAA6E,CAAC;KAClF;IACD,OAAO,EAAE;QACP,IAAI,EAAE,OAAO;QACb,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAuB;SACpD;KACF;IACD,GAAG,IAAA,uBAAe,EAAC,UAAU,CAAC;CACrB,CAAA,CAAA;AA/BA,QAAA,WAAW,eA+BX"}
|
package/lib/resolver.js
CHANGED
|
@@ -34,8 +34,8 @@ class Resolver {
|
|
|
34
34
|
const data = schema && validate === 'before' ? await schema.validate(payload) : payload;
|
|
35
35
|
const propertyList = (Array.isArray(status === null || status === void 0 ? void 0 : status.properties)
|
|
36
36
|
? status === null || status === void 0 ? void 0 : status.properties
|
|
37
|
-
// By default get all data and resolver keys but remove duplicates
|
|
38
|
-
|
|
37
|
+
: // By default get all data and resolver keys but remove duplicates
|
|
38
|
+
[...new Set(Object.keys(data).concat(Object.keys(resolvers)))]);
|
|
39
39
|
const result = {};
|
|
40
40
|
const errors = {};
|
|
41
41
|
let hasErrors = false;
|
|
@@ -51,9 +51,7 @@ class Resolver {
|
|
|
51
51
|
}
|
|
52
52
|
catch (error) {
|
|
53
53
|
// TODO add error stacks
|
|
54
|
-
const convertedError = typeof error.toJSON === 'function'
|
|
55
|
-
? error.toJSON()
|
|
56
|
-
: { message: error.message || error };
|
|
54
|
+
const convertedError = typeof error.toJSON === 'function' ? error.toJSON() : { message: error.message || error };
|
|
57
55
|
errors[name] = convertedError;
|
|
58
56
|
hasErrors = true;
|
|
59
57
|
}
|
|
@@ -66,9 +64,7 @@ class Resolver {
|
|
|
66
64
|
const propertyName = (status === null || status === void 0 ? void 0 : status.properties) ? ` ${status.properties.join('.')}` : '';
|
|
67
65
|
throw new errors_1.BadRequest('Error resolving data' + (propertyName ? ` ${propertyName}` : ''), errors);
|
|
68
66
|
}
|
|
69
|
-
return schema && validate === 'after'
|
|
70
|
-
? await schema.validate(result)
|
|
71
|
-
: result;
|
|
67
|
+
return schema && validate === 'after' ? await schema.validate(result) : result;
|
|
72
68
|
}
|
|
73
69
|
}
|
|
74
70
|
exports.Resolver = Resolver;
|
package/lib/resolver.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":";;;AAAA,+
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
|
package/lib/schema.js
CHANGED
package/lib/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":";;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":";;;;;;AAAA,8CAAkE;AAQzD,cARF,aAAG,CAQE;AANZ,+CAA+C;AAElC,QAAA,WAAW,GAAG,IAAI,aAAG,CAAC;IACjC,WAAW,EAAE,IAAI;CAClB,CAAC,CAAA;AAeF,MAAa,aAAa;IAKxB,YAAmB,UAAa,EAAE,MAAW,mBAAW;QAArC,eAAU,GAAV,UAAU,CAAG;QAC9B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;YAChC,MAAM,EAAE,IAAI;YACZ,GAAI,IAAI,CAAC,UAAkB;SAC5B,CAA0B,CAAA;IAC7B,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,UAAU,CAAC,UAA6B,CAAA;IACtD,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,UAAU,CAAC,QAAyB,CAAA;IAClD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAoB,GAAG,IAAqC;QACxE,IAAI;YACF,MAAM,SAAS,GAAG,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAM,CAAA;YAEtD,OAAO,SAAS,CAAA;SACjB;QAAC,OAAO,KAAU,EAAE;YACnB,MAAM,IAAI,mBAAU,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;SAClD;IACH,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;CACF;AAlCD,sCAkCC;AAED,SAAgB,MAAM,CAAiC,UAAa,EAAE,MAAW,mBAAW;IAC1F,OAAO,IAAI,aAAa,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;AAC3C,CAAC;AAFD,wBAEC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@feathersjs/schema",
|
|
3
3
|
"description": "A common data schema definition format",
|
|
4
|
-
"version": "5.0.0-pre.
|
|
4
|
+
"version": "5.0.0-pre.23",
|
|
5
5
|
"homepage": "https://feathersjs.com",
|
|
6
6
|
"main": "lib/",
|
|
7
7
|
"types": "lib/",
|
|
@@ -53,22 +53,23 @@
|
|
|
53
53
|
"access": "public"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@feathersjs/
|
|
57
|
-
"@feathersjs/
|
|
58
|
-
"@feathersjs/
|
|
56
|
+
"@feathersjs/commons": "^5.0.0-pre.23",
|
|
57
|
+
"@feathersjs/errors": "^5.0.0-pre.23",
|
|
58
|
+
"@feathersjs/feathers": "^5.0.0-pre.23",
|
|
59
|
+
"@feathersjs/hooks": "^0.7.5",
|
|
59
60
|
"@types/json-schema": "^7.0.11",
|
|
60
61
|
"ajv": "^8.11.0",
|
|
61
62
|
"json-schema": "^0.4.0",
|
|
62
|
-
"json-schema-to-ts": "^2.3
|
|
63
|
+
"json-schema-to-ts": "^2.5.3"
|
|
63
64
|
},
|
|
64
65
|
"devDependencies": {
|
|
65
|
-
"@feathersjs/memory": "^5.0.0-pre.
|
|
66
|
+
"@feathersjs/memory": "^5.0.0-pre.23",
|
|
66
67
|
"@types/mocha": "^9.1.1",
|
|
67
|
-
"@types/node": "^17.0.
|
|
68
|
+
"@types/node": "^17.0.40",
|
|
68
69
|
"ajv-formats": "^2.1.1",
|
|
69
70
|
"mocha": "^10.0.0",
|
|
70
71
|
"shx": "^0.3.4",
|
|
71
|
-
"typescript": "^4.
|
|
72
|
+
"typescript": "^4.7.3"
|
|
72
73
|
},
|
|
73
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "a60910bd730b88053ca6648337095f1ca1e3b39f"
|
|
74
75
|
}
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './resolve'
|
|
2
|
-
export * from './validate'
|
|
1
|
+
export * from './resolve'
|
|
2
|
+
export * from './validate'
|
package/src/hooks/resolve.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { HookContext, NextFunction } from '@feathersjs/feathers'
|
|
2
|
-
import { compose } from '@feathersjs/hooks'
|
|
3
|
-
import { Resolver, ResolverStatus } from '../resolver'
|
|
1
|
+
import { HookContext, NextFunction } from '@feathersjs/feathers'
|
|
2
|
+
import { compose } from '@feathersjs/hooks'
|
|
3
|
+
import { Resolver, ResolverStatus } from '../resolver'
|
|
4
4
|
|
|
5
|
-
const getContext = <H extends HookContext>
|
|
5
|
+
const getContext = <H extends HookContext>(context: H) => {
|
|
6
6
|
return {
|
|
7
7
|
...context,
|
|
8
8
|
params: {
|
|
@@ -12,29 +12,31 @@ const getContext = <H extends HookContext> (context: H) => {
|
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const getData = <H extends HookContext>
|
|
16
|
-
const isPaginated = context.method === 'find' && context.result.data
|
|
17
|
-
const data = isPaginated ? context.result.data : context.result
|
|
15
|
+
const getData = <H extends HookContext>(context: H) => {
|
|
16
|
+
const isPaginated = context.method === 'find' && context.result.data
|
|
17
|
+
const data = isPaginated ? context.result.data : context.result
|
|
18
18
|
|
|
19
|
-
return { isPaginated, data }
|
|
19
|
+
return { isPaginated, data }
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const runResolvers = async <T, H extends HookContext>
|
|
22
|
+
const runResolvers = async <T, H extends HookContext>(
|
|
23
23
|
resolvers: Resolver<T, H>[],
|
|
24
24
|
data: any,
|
|
25
25
|
ctx: H,
|
|
26
26
|
status?: Partial<ResolverStatus<T, H>>
|
|
27
27
|
) => {
|
|
28
|
-
let current: any = data
|
|
28
|
+
let current: any = data
|
|
29
29
|
|
|
30
30
|
for (const resolver of resolvers) {
|
|
31
|
-
|
|
31
|
+
if (resolver && typeof resolver.resolve === 'function') {
|
|
32
|
+
current = await resolver.resolve(current, ctx, status)
|
|
33
|
+
}
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
return current as T
|
|
36
|
+
return current as T
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
export type ResolverSetting<H extends HookContext> = Resolver<any, H
|
|
39
|
+
export type ResolverSetting<H extends HookContext> = Resolver<any, H> | Resolver<any, H>[]
|
|
38
40
|
|
|
39
41
|
export type DataResolvers<H extends HookContext> = {
|
|
40
42
|
create: Resolver<any, H>
|
|
@@ -49,13 +51,17 @@ export type ResolveAllSettings<H extends HookContext> = {
|
|
|
49
51
|
dispatch?: Resolver<any, H>
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
export const DISPATCH = Symbol('@feathersjs/schema/dispatch')
|
|
54
|
+
export const DISPATCH = Symbol('@feathersjs/schema/dispatch')
|
|
55
|
+
|
|
56
|
+
export const getDispatch = (value: any) =>
|
|
57
|
+
typeof value === 'object' && value !== null && value[DISPATCH] !== undefined ? value[DISPATCH] : value
|
|
53
58
|
|
|
54
|
-
export const resolveQuery =
|
|
59
|
+
export const resolveQuery =
|
|
60
|
+
<T, H extends HookContext>(...resolvers: Resolver<T, H>[]) =>
|
|
55
61
|
async (context: H, next?: NextFunction) => {
|
|
56
|
-
const ctx = getContext(context)
|
|
57
|
-
const data = context?.params?.query || {}
|
|
58
|
-
const query = await runResolvers(resolvers, data, ctx)
|
|
62
|
+
const ctx = getContext(context)
|
|
63
|
+
const data = context?.params?.query || {}
|
|
64
|
+
const query = await runResolvers(resolvers, data, ctx)
|
|
59
65
|
|
|
60
66
|
context.params = {
|
|
61
67
|
...context.params,
|
|
@@ -63,44 +69,44 @@ export const resolveQuery = <T, H extends HookContext> (...resolvers: Resolver<T
|
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
if (typeof next === 'function') {
|
|
66
|
-
return next()
|
|
72
|
+
return next()
|
|
67
73
|
}
|
|
68
|
-
}
|
|
74
|
+
}
|
|
69
75
|
|
|
70
|
-
export const resolveData =
|
|
76
|
+
export const resolveData =
|
|
77
|
+
<H extends HookContext>(settings: DataResolvers<H> | Resolver<any, H>) =>
|
|
71
78
|
async (context: H, next?: NextFunction) => {
|
|
72
79
|
if (context.method === 'create' || context.method === 'patch' || context.method === 'update') {
|
|
73
|
-
const resolvers = settings instanceof Resolver ? [
|
|
74
|
-
const ctx = getContext(context)
|
|
75
|
-
const data = context.data
|
|
80
|
+
const resolvers = settings instanceof Resolver ? [settings] : [settings[context.method]]
|
|
81
|
+
const ctx = getContext(context)
|
|
82
|
+
const data = context.data
|
|
76
83
|
|
|
77
84
|
const status = {
|
|
78
85
|
originalContext: context
|
|
79
|
-
}
|
|
86
|
+
}
|
|
80
87
|
|
|
81
88
|
if (Array.isArray(data)) {
|
|
82
|
-
context.data = await Promise.all(data.map(current =>
|
|
83
|
-
runResolvers(resolvers, current, ctx, status)
|
|
84
|
-
));
|
|
89
|
+
context.data = await Promise.all(data.map((current) => runResolvers(resolvers, current, ctx, status)))
|
|
85
90
|
} else {
|
|
86
|
-
context.data = await runResolvers(resolvers, data, ctx, status)
|
|
91
|
+
context.data = await runResolvers(resolvers, data, ctx, status)
|
|
87
92
|
}
|
|
88
93
|
}
|
|
89
94
|
|
|
90
95
|
if (typeof next === 'function') {
|
|
91
|
-
return next()
|
|
96
|
+
return next()
|
|
92
97
|
}
|
|
93
|
-
}
|
|
98
|
+
}
|
|
94
99
|
|
|
95
|
-
export const resolveResult =
|
|
100
|
+
export const resolveResult =
|
|
101
|
+
<T, H extends HookContext>(...resolvers: Resolver<T, H>[]) =>
|
|
96
102
|
async (context: H, next?: NextFunction) => {
|
|
97
103
|
if (typeof next === 'function') {
|
|
98
|
-
const { $resolve: properties, ...query } = context.params?.query || {}
|
|
104
|
+
const { $resolve: properties, ...query } = context.params?.query || {}
|
|
99
105
|
const resolve = {
|
|
100
106
|
originalContext: context,
|
|
101
107
|
...context.params.resolve,
|
|
102
108
|
properties
|
|
103
|
-
}
|
|
109
|
+
}
|
|
104
110
|
|
|
105
111
|
context.params = {
|
|
106
112
|
...context.params,
|
|
@@ -108,78 +114,78 @@ export const resolveResult = <T, H extends HookContext> (...resolvers: Resolver<
|
|
|
108
114
|
query
|
|
109
115
|
}
|
|
110
116
|
|
|
111
|
-
await next()
|
|
117
|
+
await next()
|
|
112
118
|
}
|
|
113
119
|
|
|
114
|
-
const ctx = getContext(context)
|
|
115
|
-
const status = context.params.resolve
|
|
116
|
-
const { isPaginated, data } = getData(context)
|
|
120
|
+
const ctx = getContext(context)
|
|
121
|
+
const status = context.params.resolve
|
|
122
|
+
const { isPaginated, data } = getData(context)
|
|
117
123
|
|
|
118
|
-
const result = Array.isArray(data)
|
|
119
|
-
await Promise.all(data.map(async current => runResolvers(resolvers, current, ctx, status)))
|
|
120
|
-
await runResolvers(resolvers, data, ctx, status)
|
|
124
|
+
const result = Array.isArray(data)
|
|
125
|
+
? await Promise.all(data.map(async (current) => runResolvers(resolvers, current, ctx, status)))
|
|
126
|
+
: await runResolvers(resolvers, data, ctx, status)
|
|
121
127
|
|
|
122
128
|
if (isPaginated) {
|
|
123
|
-
context.result.data = result
|
|
129
|
+
context.result.data = result
|
|
124
130
|
} else {
|
|
125
|
-
context.result = result
|
|
131
|
+
context.result = result
|
|
126
132
|
}
|
|
127
|
-
}
|
|
133
|
+
}
|
|
128
134
|
|
|
129
|
-
export const resolveDispatch =
|
|
135
|
+
export const resolveDispatch =
|
|
136
|
+
<T, H extends HookContext>(...resolvers: Resolver<T, H>[]) =>
|
|
130
137
|
async (context: H, next?: NextFunction) => {
|
|
131
138
|
if (typeof next === 'function') {
|
|
132
|
-
await next()
|
|
139
|
+
await next()
|
|
133
140
|
}
|
|
134
141
|
|
|
135
|
-
const ctx = getContext(context)
|
|
136
|
-
const status = context.params.resolve
|
|
137
|
-
const { isPaginated, data } = getData(context)
|
|
138
|
-
const
|
|
142
|
+
const ctx = getContext(context)
|
|
143
|
+
const status = context.params.resolve
|
|
144
|
+
const { isPaginated, data } = getData(context)
|
|
145
|
+
const resolveAndGetDispatch = async (current: any) => {
|
|
139
146
|
const resolved = await runResolvers(resolvers, current, ctx, status)
|
|
140
147
|
|
|
141
148
|
return Object.keys(resolved).reduce((res, key) => {
|
|
142
|
-
|
|
143
|
-
const hasDispatch = typeof value === 'object' && value !== null && value[DISPATCH] !== undefined;
|
|
144
|
-
|
|
145
|
-
res[key] = hasDispatch ? value[DISPATCH] : value;
|
|
149
|
+
res[key] = getDispatch(current[key])
|
|
146
150
|
|
|
147
151
|
return res
|
|
148
152
|
}, {} as any)
|
|
149
153
|
}
|
|
150
154
|
|
|
151
|
-
const result = await (Array.isArray(data)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
const result = await (Array.isArray(data)
|
|
156
|
+
? Promise.all(data.map(resolveAndGetDispatch))
|
|
157
|
+
: resolveAndGetDispatch(data))
|
|
158
|
+
const dispatch = isPaginated
|
|
159
|
+
? {
|
|
160
|
+
...context.result,
|
|
161
|
+
data: result
|
|
162
|
+
}
|
|
163
|
+
: result
|
|
164
|
+
|
|
165
|
+
context.dispatch = dispatch
|
|
158
166
|
Object.defineProperty(context.result, DISPATCH, {
|
|
159
167
|
value: dispatch,
|
|
160
168
|
enumerable: false,
|
|
161
169
|
configurable: false
|
|
162
|
-
})
|
|
163
|
-
}
|
|
170
|
+
})
|
|
171
|
+
}
|
|
164
172
|
|
|
165
|
-
export const resolveAll = <H extends HookContext>
|
|
166
|
-
const middleware = []
|
|
173
|
+
export const resolveAll = <H extends HookContext>(map: ResolveAllSettings<H>) => {
|
|
174
|
+
const middleware = []
|
|
167
175
|
|
|
168
|
-
|
|
169
|
-
middleware.push(resolveDispatch(map.dispatch));
|
|
170
|
-
}
|
|
176
|
+
middleware.push(resolveDispatch(map.dispatch))
|
|
171
177
|
|
|
172
178
|
if (map.result) {
|
|
173
|
-
middleware.push(resolveResult(map.result))
|
|
179
|
+
middleware.push(resolveResult(map.result))
|
|
174
180
|
}
|
|
175
181
|
|
|
176
182
|
if (map.query) {
|
|
177
|
-
middleware.push(resolveQuery(map.query))
|
|
183
|
+
middleware.push(resolveQuery(map.query))
|
|
178
184
|
}
|
|
179
185
|
|
|
180
186
|
if (map.data) {
|
|
181
|
-
middleware.push(resolveData(map.data))
|
|
187
|
+
middleware.push(resolveData(map.data))
|
|
182
188
|
}
|
|
183
189
|
|
|
184
|
-
return compose(middleware)
|
|
190
|
+
return compose(middleware)
|
|
185
191
|
}
|
package/src/hooks/validate.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { HookContext, NextFunction } from '@feathersjs/feathers'
|
|
2
|
-
import { BadRequest } from '../../../errors/lib'
|
|
3
|
-
import { Schema } from '../schema'
|
|
1
|
+
import { HookContext, NextFunction } from '@feathersjs/feathers'
|
|
2
|
+
import { BadRequest } from '../../../errors/lib'
|
|
3
|
+
import { Schema } from '../schema'
|
|
4
4
|
|
|
5
|
-
export const validateQuery =
|
|
5
|
+
export const validateQuery =
|
|
6
|
+
<H extends HookContext>(schema: Schema<any>) =>
|
|
6
7
|
async (context: H, next?: NextFunction) => {
|
|
7
|
-
const data = context?.params?.query || {}
|
|
8
|
+
const data = context?.params?.query || {}
|
|
8
9
|
|
|
9
10
|
try {
|
|
10
|
-
const query = await schema.validate(data)
|
|
11
|
+
const query = await schema.validate(data)
|
|
11
12
|
|
|
12
13
|
context.params = {
|
|
13
14
|
...context.params,
|
|
@@ -15,30 +16,29 @@ export const validateQuery = <H extends HookContext> (schema: Schema<any>) =>
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
if (typeof next === 'function') {
|
|
18
|
-
return next()
|
|
19
|
+
return next()
|
|
19
20
|
}
|
|
20
21
|
} catch (error: any) {
|
|
21
|
-
throw
|
|
22
|
+
throw error.ajv ? new BadRequest(error.message, error.errors) : error
|
|
22
23
|
}
|
|
23
|
-
}
|
|
24
|
+
}
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
export const validateData =
|
|
27
|
+
<H extends HookContext>(schema: Schema<any>) =>
|
|
26
28
|
async (context: H, next?: NextFunction) => {
|
|
27
|
-
const data = context.data
|
|
29
|
+
const data = context.data
|
|
28
30
|
|
|
29
31
|
try {
|
|
30
32
|
if (Array.isArray(data)) {
|
|
31
|
-
context.data = await Promise.all(data.map(current =>
|
|
32
|
-
schema.validate(current)
|
|
33
|
-
));
|
|
33
|
+
context.data = await Promise.all(data.map((current) => schema.validate(current)))
|
|
34
34
|
} else {
|
|
35
|
-
context.data = await schema.validate(data)
|
|
35
|
+
context.data = await schema.validate(data)
|
|
36
36
|
}
|
|
37
37
|
} catch (error: any) {
|
|
38
|
-
throw
|
|
38
|
+
throw error.ajv ? new BadRequest(error.message, error.errors) : error
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
if (typeof next === 'function') {
|
|
42
|
-
return next()
|
|
42
|
+
return next()
|
|
43
43
|
}
|
|
44
|
-
}
|
|
44
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { ResolverStatus
|
|
1
|
+
import { ResolverStatus } from './resolver'
|
|
2
2
|
|
|
3
|
-
export * from './schema'
|
|
4
|
-
export * from './resolver'
|
|
5
|
-
export * from './hooks'
|
|
6
|
-
export * from './query'
|
|
3
|
+
export * from './schema'
|
|
4
|
+
export * from './resolver'
|
|
5
|
+
export * from './hooks'
|
|
6
|
+
export * from './query'
|
|
7
7
|
|
|
8
|
-
export type Infer<S extends { _type: any }> = S['_type']
|
|
8
|
+
export type Infer<S extends { _type: any }> = S['_type']
|
|
9
9
|
|
|
10
|
-
export type Combine<S extends { _type: any }, U> = Pick<Infer<S>, Exclude<keyof Infer<S>, keyof U>> & U
|
|
10
|
+
export type Combine<S extends { _type: any }, U> = Pick<Infer<S>, Exclude<keyof Infer<S>, keyof U>> & U
|
|
11
11
|
|
|
12
12
|
declare module '@feathersjs/feathers/lib/declarations' {
|
|
13
13
|
interface Params {
|
|
14
|
-
resolve?: ResolverStatus<any, HookContext
|
|
14
|
+
resolve?: ResolverStatus<any, HookContext>
|
|
15
15
|
}
|
|
16
16
|
}
|
package/src/query.ts
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ } from '@feathersjs/commons'
|
|
2
|
+
import { JSONSchema } from 'json-schema-to-ts'
|
|
2
3
|
|
|
3
4
|
export type PropertyQuery<D extends JSONSchema> = {
|
|
4
5
|
anyOf: [
|
|
5
6
|
D,
|
|
6
7
|
{
|
|
7
|
-
type: 'object'
|
|
8
|
-
additionalProperties: false
|
|
8
|
+
type: 'object'
|
|
9
|
+
additionalProperties: false
|
|
9
10
|
properties: {
|
|
10
|
-
$gt: D
|
|
11
|
-
$gte: D
|
|
12
|
-
$lt: D
|
|
13
|
-
$lte: D
|
|
14
|
-
$ne: D
|
|
11
|
+
$gt: D
|
|
12
|
+
$gte: D
|
|
13
|
+
$lt: D
|
|
14
|
+
$lte: D
|
|
15
|
+
$ne: D
|
|
15
16
|
$in: {
|
|
16
|
-
type: 'array'
|
|
17
|
+
type: 'array'
|
|
17
18
|
items: D
|
|
18
|
-
}
|
|
19
|
+
}
|
|
19
20
|
$nin: {
|
|
20
|
-
type: 'array'
|
|
21
|
+
type: 'array'
|
|
21
22
|
items: D
|
|
22
23
|
}
|
|
23
24
|
}
|
|
@@ -25,64 +26,72 @@ export type PropertyQuery<D extends JSONSchema> = {
|
|
|
25
26
|
]
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
export const queryProperty = <T extends JSONSchema>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
29
|
+
export const queryProperty = <T extends JSONSchema>(def: T) => {
|
|
30
|
+
const definition = _.omit(def, 'default')
|
|
31
|
+
return {
|
|
32
|
+
anyOf: [
|
|
33
|
+
definition,
|
|
34
|
+
{
|
|
35
|
+
type: 'object',
|
|
36
|
+
additionalProperties: false,
|
|
37
|
+
properties: {
|
|
38
|
+
$gt: definition,
|
|
39
|
+
$gte: definition,
|
|
40
|
+
$lt: definition,
|
|
41
|
+
$lte: definition,
|
|
42
|
+
$ne: definition,
|
|
43
|
+
$in: {
|
|
44
|
+
type: 'array',
|
|
45
|
+
items: definition
|
|
46
|
+
},
|
|
47
|
+
$nin: {
|
|
48
|
+
type: 'array',
|
|
49
|
+
items: definition
|
|
50
|
+
}
|
|
47
51
|
}
|
|
48
52
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
53
|
+
]
|
|
54
|
+
} as const
|
|
55
|
+
}
|
|
52
56
|
|
|
53
|
-
export const queryProperties = <T extends { [key: string]: JSONSchema }>
|
|
57
|
+
export const queryProperties = <T extends { [key: string]: JSONSchema }>(definition: T) =>
|
|
54
58
|
Object.keys(definition).reduce((res, key) => {
|
|
55
|
-
|
|
59
|
+
const result = res as any
|
|
60
|
+
|
|
61
|
+
result[key] = queryProperty(definition[key])
|
|
56
62
|
|
|
57
|
-
return
|
|
63
|
+
return result
|
|
58
64
|
}, {} as { [K in keyof T]: PropertyQuery<T[K]> })
|
|
59
65
|
|
|
60
|
-
export const querySyntax = <T extends { [key: string]: JSONSchema }>
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
(res
|
|
73
|
-
|
|
74
|
-
enum: [1, -1]
|
|
75
|
-
}
|
|
66
|
+
export const querySyntax = <T extends { [key: string]: JSONSchema }>(definition: T) =>
|
|
67
|
+
({
|
|
68
|
+
$limit: {
|
|
69
|
+
type: 'number',
|
|
70
|
+
minimum: 0
|
|
71
|
+
},
|
|
72
|
+
$skip: {
|
|
73
|
+
type: 'number',
|
|
74
|
+
minimum: 0
|
|
75
|
+
},
|
|
76
|
+
$sort: {
|
|
77
|
+
type: 'object',
|
|
78
|
+
properties: Object.keys(definition).reduce((res, key) => {
|
|
79
|
+
const result = res as any
|
|
76
80
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
type: '
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
result[key] = {
|
|
82
|
+
type: 'number',
|
|
83
|
+
enum: [1, -1]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return result
|
|
87
|
+
}, {} as { [K in keyof T]: { readonly type: 'number'; readonly enum: [1, -1] } })
|
|
88
|
+
},
|
|
89
|
+
$select: {
|
|
90
|
+
type: 'array',
|
|
91
|
+
items: {
|
|
92
|
+
type: 'string',
|
|
93
|
+
enum: Object.keys(definition) as any as (keyof T)[]
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
...queryProperties(definition)
|
|
97
|
+
} as const)
|
package/src/resolver.ts
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
import { BadRequest } from '@feathersjs/errors'
|
|
2
|
-
import { Schema } from './schema'
|
|
1
|
+
import { BadRequest } from '@feathersjs/errors'
|
|
2
|
+
import { Schema } from './schema'
|
|
3
3
|
|
|
4
4
|
export type PropertyResolver<T, V, C> = (
|
|
5
|
-
value: V|undefined,
|
|
5
|
+
value: V | undefined,
|
|
6
6
|
obj: T,
|
|
7
7
|
context: C,
|
|
8
8
|
status: ResolverStatus<T, C>
|
|
9
|
-
) => Promise<V|undefined
|
|
9
|
+
) => Promise<V | undefined>
|
|
10
10
|
|
|
11
11
|
export type PropertyResolverMap<T, C> = {
|
|
12
12
|
[key in keyof T]?: PropertyResolver<T, T[key], C>
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export type ResolverConverter<T, C> = (
|
|
16
|
-
|
|
15
|
+
export type ResolverConverter<T, C> = (
|
|
16
|
+
obj: any,
|
|
17
|
+
context: C,
|
|
18
|
+
status: ResolverStatus<T, C>
|
|
19
|
+
) => Promise<T | undefined>
|
|
17
20
|
|
|
18
21
|
export interface ResolverConfig<T, C> {
|
|
19
|
-
schema?: Schema<T
|
|
20
|
-
validate?: 'before'|'after'|false
|
|
22
|
+
schema?: Schema<T>
|
|
23
|
+
validate?: 'before' | 'after' | false
|
|
21
24
|
properties: PropertyResolverMap<T, C>
|
|
22
25
|
converter?: ResolverConverter<T, C>
|
|
23
26
|
}
|
|
@@ -30,24 +33,23 @@ export interface ResolverStatus<T, C> {
|
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
export class Resolver<T, C> {
|
|
33
|
-
readonly _type!: T
|
|
36
|
+
readonly _type!: T
|
|
34
37
|
|
|
35
|
-
constructor
|
|
36
|
-
}
|
|
38
|
+
constructor(public options: ResolverConfig<T, C>) {}
|
|
37
39
|
|
|
38
|
-
async resolveProperty<D, K extends keyof T>
|
|
40
|
+
async resolveProperty<D, K extends keyof T>(
|
|
39
41
|
name: K,
|
|
40
42
|
data: D,
|
|
41
43
|
context: C,
|
|
42
44
|
status: Partial<ResolverStatus<T, C>> = {}
|
|
43
45
|
): Promise<T[K]> {
|
|
44
|
-
const resolver = this.options.properties[name]
|
|
45
|
-
const value = (data as any)[name]
|
|
46
|
-
const { path = [], stack = [] } = status || {}
|
|
46
|
+
const resolver = this.options.properties[name]
|
|
47
|
+
const value = (data as any)[name]
|
|
48
|
+
const { path = [], stack = [] } = status || {}
|
|
47
49
|
|
|
48
50
|
// This prevents circular dependencies
|
|
49
51
|
if (stack.includes(resolver)) {
|
|
50
|
-
return undefined
|
|
52
|
+
return undefined
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
const resolverStatus = {
|
|
@@ -56,10 +58,10 @@ export class Resolver<T, C> {
|
|
|
56
58
|
stack: [...stack, resolver]
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
return resolver(value, data as any, context, resolverStatus)
|
|
61
|
+
return resolver(value, data as any, context, resolverStatus)
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
async convert
|
|
64
|
+
async convert<D>(data: D, context: C, status?: Partial<ResolverStatus<T, C>>) {
|
|
63
65
|
if (this.options.converter) {
|
|
64
66
|
const { path = [], stack = [] } = status || {}
|
|
65
67
|
|
|
@@ -69,57 +71,57 @@ export class Resolver<T, C> {
|
|
|
69
71
|
return data
|
|
70
72
|
}
|
|
71
73
|
|
|
72
|
-
async resolve<D>
|
|
73
|
-
const { properties: resolvers, schema, validate } = this.options
|
|
74
|
-
const payload = await this.convert(_data, context, status)
|
|
75
|
-
const data = schema && validate === 'before' ? await schema.validate(payload) : payload
|
|
76
|
-
const propertyList = (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
|
|
74
|
+
async resolve<D>(_data: D, context: C, status?: Partial<ResolverStatus<T, C>>): Promise<T> {
|
|
75
|
+
const { properties: resolvers, schema, validate } = this.options
|
|
76
|
+
const payload = await this.convert(_data, context, status)
|
|
77
|
+
const data = schema && validate === 'before' ? await schema.validate(payload) : payload
|
|
78
|
+
const propertyList = (
|
|
79
|
+
Array.isArray(status?.properties)
|
|
80
|
+
? status?.properties
|
|
81
|
+
: // By default get all data and resolver keys but remove duplicates
|
|
82
|
+
[...new Set(Object.keys(data).concat(Object.keys(resolvers)))]
|
|
83
|
+
) as (keyof T)[]
|
|
84
|
+
|
|
85
|
+
const result: any = {}
|
|
86
|
+
const errors: any = {}
|
|
87
|
+
let hasErrors = false
|
|
85
88
|
|
|
86
89
|
// Not the most elegant but better performance
|
|
87
|
-
await Promise.all(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
await Promise.all(
|
|
91
|
+
propertyList.map(async (name) => {
|
|
92
|
+
const value = (data as any)[name]
|
|
93
|
+
|
|
94
|
+
if (resolvers[name]) {
|
|
95
|
+
try {
|
|
96
|
+
const resolved = await this.resolveProperty(name, data, context, status)
|
|
97
|
+
|
|
98
|
+
if (resolved !== undefined) {
|
|
99
|
+
result[name] = resolved
|
|
100
|
+
}
|
|
101
|
+
} catch (error: any) {
|
|
102
|
+
// TODO add error stacks
|
|
103
|
+
const convertedError =
|
|
104
|
+
typeof error.toJSON === 'function' ? error.toJSON() : { message: error.message || error }
|
|
105
|
+
|
|
106
|
+
errors[name] = convertedError
|
|
107
|
+
hasErrors = true
|
|
96
108
|
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const convertedError = typeof error.toJSON === 'function'
|
|
100
|
-
? error.toJSON()
|
|
101
|
-
: { message: error.message || error };
|
|
102
|
-
|
|
103
|
-
errors[name] = convertedError;
|
|
104
|
-
hasErrors = true;
|
|
109
|
+
} else if (value !== undefined) {
|
|
110
|
+
result[name] = value
|
|
105
111
|
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
}));
|
|
112
|
+
})
|
|
113
|
+
)
|
|
110
114
|
|
|
111
115
|
if (hasErrors) {
|
|
112
|
-
const propertyName = status?.properties ? ` ${status.properties.join('.')}` : ''
|
|
116
|
+
const propertyName = status?.properties ? ` ${status.properties.join('.')}` : ''
|
|
113
117
|
|
|
114
|
-
throw new BadRequest('Error resolving data' + (propertyName ? ` ${propertyName}` : ''), errors)
|
|
118
|
+
throw new BadRequest('Error resolving data' + (propertyName ? ` ${propertyName}` : ''), errors)
|
|
115
119
|
}
|
|
116
120
|
|
|
117
|
-
return schema && validate === 'after'
|
|
118
|
-
? await schema.validate(result)
|
|
119
|
-
: result;
|
|
121
|
+
return schema && validate === 'after' ? await schema.validate(result) : result
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
|
|
123
|
-
export function resolve
|
|
124
|
-
return new Resolver<T, C>(options)
|
|
125
|
+
export function resolve<T, C>(options: ResolverConfig<T, C>) {
|
|
126
|
+
return new Resolver<T, C>(options)
|
|
125
127
|
}
|
package/src/schema.ts
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
import Ajv, { AsyncValidateFunction, ValidateFunction } from 'ajv'
|
|
2
|
-
import { FromSchema, JSONSchema } from 'json-schema-to-ts'
|
|
3
|
-
import { BadRequest } from '@feathersjs/errors'
|
|
1
|
+
import Ajv, { AsyncValidateFunction, ValidateFunction } from 'ajv'
|
|
2
|
+
import { FromSchema, JSONSchema } from 'json-schema-to-ts'
|
|
3
|
+
import { BadRequest } from '@feathersjs/errors'
|
|
4
4
|
|
|
5
5
|
export const DEFAULT_AJV = new Ajv({
|
|
6
6
|
coerceTypes: true
|
|
7
|
-
})
|
|
7
|
+
})
|
|
8
8
|
|
|
9
|
-
export { Ajv }
|
|
9
|
+
export { Ajv }
|
|
10
10
|
|
|
11
11
|
export type JSONSchemaDefinition = JSONSchema & {
|
|
12
|
-
$id: string
|
|
13
|
-
$async?: boolean
|
|
12
|
+
$id: string
|
|
13
|
+
$async?: boolean
|
|
14
14
|
properties?: { [key: string]: JSONSchema }
|
|
15
15
|
required?: readonly string[]
|
|
16
|
-
}
|
|
16
|
+
}
|
|
17
17
|
|
|
18
18
|
export interface Schema<T> {
|
|
19
|
-
validate
|
|
19
|
+
validate<X = T>(...args: Parameters<ValidateFunction<X>>): Promise<X>
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export class SchemaWrapper<S extends JSONSchemaDefinition> implements Schema<FromSchema<S>> {
|
|
23
|
-
ajv: Ajv
|
|
24
|
-
validator: AsyncValidateFunction
|
|
25
|
-
readonly _type!: FromSchema<S
|
|
23
|
+
ajv: Ajv
|
|
24
|
+
validator: AsyncValidateFunction
|
|
25
|
+
readonly _type!: FromSchema<S>
|
|
26
26
|
|
|
27
|
-
constructor
|
|
28
|
-
this.ajv = ajv
|
|
27
|
+
constructor(public definition: S, ajv: Ajv = DEFAULT_AJV) {
|
|
28
|
+
this.ajv = ajv
|
|
29
29
|
this.validator = this.ajv.compile({
|
|
30
30
|
$async: true,
|
|
31
31
|
...(this.definition as any)
|
|
32
|
-
}) as AsyncValidateFunction
|
|
32
|
+
}) as AsyncValidateFunction
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
get properties
|
|
36
|
-
return this.definition.properties as S['properties']
|
|
35
|
+
get properties() {
|
|
36
|
+
return this.definition.properties as S['properties']
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
get required
|
|
40
|
-
return this.definition.required as S['required']
|
|
39
|
+
get required() {
|
|
40
|
+
return this.definition.required as S['required']
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
async validate
|
|
43
|
+
async validate<T = FromSchema<S>>(...args: Parameters<ValidateFunction<T>>) {
|
|
44
44
|
try {
|
|
45
|
-
const validated = await this.validator(...args) as T
|
|
45
|
+
const validated = (await this.validator(...args)) as T
|
|
46
46
|
|
|
47
|
-
return validated
|
|
47
|
+
return validated
|
|
48
48
|
} catch (error: any) {
|
|
49
|
-
throw new BadRequest(error.message, error.errors)
|
|
49
|
+
throw new BadRequest(error.message, error.errors)
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
toJSON
|
|
54
|
-
return this.definition
|
|
53
|
+
toJSON() {
|
|
54
|
+
return this.definition
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
export function schema
|
|
59
|
-
return new SchemaWrapper(definition, ajv)
|
|
58
|
+
export function schema<S extends JSONSchemaDefinition>(definition: S, ajv: Ajv = DEFAULT_AJV) {
|
|
59
|
+
return new SchemaWrapper(definition, ajv)
|
|
60
60
|
}
|