@kollors/deep-json-server 1.0.0-alpha.3 → 1.0.0-alpha.5
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/README.md +95 -20
- package/README.ru.md +95 -20
- package/dist/src/constants.d.ts +1 -1
- package/dist/src/constants.js +1 -1
- package/dist/src/engine.d.ts +2 -24
- package/dist/src/engine.js +12 -126
- package/dist/src/engine.js.map +1 -1
- package/dist/src/graphql/preflight.js +9 -0
- package/dist/src/graphql/preflight.js.map +1 -1
- package/dist/src/graphql/resolvers.d.ts +2 -1
- package/dist/src/graphql/resolvers.js +1 -1
- package/dist/src/graphql/resolvers.js.map +1 -1
- package/dist/src/graphql.js +19 -8
- package/dist/src/graphql.js.map +1 -1
- package/dist/src/model.d.ts +9 -3
- package/dist/src/model.js +58 -15
- package/dist/src/model.js.map +1 -1
- package/dist/src/mutations/write.d.ts +26 -0
- package/dist/src/mutations/write.js +274 -0
- package/dist/src/mutations/write.js.map +1 -0
- package/dist/src/openapi/document.js +61 -31
- package/dist/src/openapi/document.js.map +1 -1
- package/dist/src/records.d.ts +25 -0
- package/dist/src/records.js +48 -0
- package/dist/src/records.js.map +1 -0
- package/dist/src/rest/options.d.ts +7 -8
- package/dist/src/rest/options.js +42 -94
- package/dist/src/rest/options.js.map +1 -1
- package/dist/src/rest/projection.d.ts +5 -4
- package/dist/src/rest/projection.js +36 -19
- package/dist/src/rest/projection.js.map +1 -1
- package/dist/src/rest/routes.js +8 -8
- package/dist/src/rest/routes.js.map +1 -1
- package/package.json +1 -1
package/dist/src/rest/options.js
CHANGED
|
@@ -1,108 +1,56 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return ownScope;
|
|
8
|
-
if (typeof value !== 'string' || !value.length || value.length > 10000)
|
|
9
|
-
badQuery('scope must be a nonempty string of at most 10000 characters');
|
|
10
|
-
let index = 0;
|
|
11
|
-
function parse(depth) {
|
|
12
|
-
if (depth > 32)
|
|
13
|
-
badQuery('scope is too deep');
|
|
14
|
-
const result = Object.create(null);
|
|
15
|
-
while (index < value.length) {
|
|
16
|
-
const match = /^(\*|[A-Za-z][A-Za-z0-9_]*)/.exec(value.slice(index));
|
|
17
|
-
if (!match)
|
|
18
|
-
badQuery('Invalid scope syntax');
|
|
19
|
-
const key = match[1];
|
|
20
|
-
if (key !== '*')
|
|
21
|
-
pathParts(key);
|
|
22
|
-
index += key.length;
|
|
23
|
-
let child = null;
|
|
24
|
-
if (value[index] === '(') {
|
|
25
|
-
if (key === '*')
|
|
26
|
-
badQuery('Wildcard cannot have a selection');
|
|
27
|
-
index++;
|
|
28
|
-
child = parse(depth + 1);
|
|
29
|
-
if (value[index++] !== ')')
|
|
30
|
-
badQuery('Unclosed scope selection');
|
|
31
|
-
}
|
|
32
|
-
if (Object.hasOwn(result, key))
|
|
33
|
-
badQuery(`Duplicate scope field ${key}`);
|
|
34
|
-
result[key] = child;
|
|
35
|
-
if (value[index] !== ',')
|
|
36
|
-
break;
|
|
37
|
-
index++;
|
|
38
|
-
if (index === value.length)
|
|
39
|
-
badQuery('Trailing scope comma');
|
|
40
|
-
}
|
|
41
|
-
if (!Object.keys(result).length)
|
|
42
|
-
badQuery('Empty scope selection');
|
|
43
|
-
return result;
|
|
44
|
-
}
|
|
45
|
-
const result = parse(0);
|
|
46
|
-
if (index !== value.length)
|
|
47
|
-
badQuery('Invalid scope syntax');
|
|
48
|
-
return result;
|
|
1
|
+
import { badQuery, childrenOf } from '../query/options.js';
|
|
2
|
+
import { isObject, isSafeKey } from '../utils.js';
|
|
3
|
+
export const ownScope = [{ '*': true }];
|
|
4
|
+
export function scopeFor(scope, key) {
|
|
5
|
+
const selection = Object.hasOwn(scope[0], key) ? scope[0][key] : true;
|
|
6
|
+
return selection === true ? ownScope : selection;
|
|
49
7
|
}
|
|
50
|
-
export function parseRestOptions(query
|
|
8
|
+
export function parseRestOptions(query) {
|
|
51
9
|
if (!isObject(query))
|
|
52
10
|
badQuery('Invalid query');
|
|
53
|
-
const allowed = list ? ['scope', 'nested', 'where', 'order', 'pager'] : ['scope', 'nested'];
|
|
54
11
|
for (const key of Object.keys(query))
|
|
55
|
-
if (
|
|
12
|
+
if (key !== 'scope')
|
|
56
13
|
badQuery(`Unknown query parameter ${key}`);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
14
|
+
if (query.scope === undefined)
|
|
15
|
+
return { scope: ownScope };
|
|
16
|
+
if (typeof query.scope !== 'string')
|
|
17
|
+
badQuery('scope must occur once and contain JSON');
|
|
18
|
+
if (query.scope.length > 10000)
|
|
19
|
+
badQuery('scope must contain at most 10000 characters');
|
|
20
|
+
try {
|
|
21
|
+
return { scope: JSON.parse(query.scope) };
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
badQuery('Invalid JSON in scope');
|
|
69
25
|
}
|
|
70
|
-
if (!isObject(result.nested))
|
|
71
|
-
badQuery('nested must be an object');
|
|
72
|
-
return result;
|
|
73
26
|
}
|
|
74
|
-
export function validateScope(node, scope, depth = 0) {
|
|
27
|
+
export function validateScope(node, scope, list = false, depth = 0) {
|
|
75
28
|
if (depth > 32)
|
|
76
29
|
badQuery('scope is too deep');
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (!child.relation && child.base !== 'object')
|
|
85
|
-
badQuery(`Scalar field ${key} cannot have a selection`);
|
|
86
|
-
validateScope(child, selection, depth + 1);
|
|
87
|
-
}
|
|
30
|
+
if (!Array.isArray(scope) || scope.length < 1 || scope.length > 2 || !isObject(scope[0]))
|
|
31
|
+
badQuery('scope must be [fields, arguments?]');
|
|
32
|
+
if (scope.length === 2) {
|
|
33
|
+
if (!list || node.mixed)
|
|
34
|
+
badQuery('scope arguments require a list with consistent object types');
|
|
35
|
+
if (!isObject(scope[1]) || Object.keys(scope[1]).some((key) => !['where', 'order', 'pager'].includes(key)))
|
|
36
|
+
badQuery('Invalid scope arguments');
|
|
88
37
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (!isObject(options) || Object.keys(options).some((k) => !['where', 'order', 'pager'].includes(k)))
|
|
96
|
-
badQuery(`Invalid nested options at ${path}`);
|
|
97
|
-
let current = root;
|
|
98
|
-
let selection = scope;
|
|
99
|
-
for (const key of pathParts(path)) {
|
|
100
|
-
const child = childrenOf(current)[key];
|
|
101
|
-
if (!Object.hasOwn(selection, key) && !(Object.hasOwn(selection, '*') && !child.relation))
|
|
102
|
-
badQuery(`nested path ${path} is not selected by scope`);
|
|
103
|
-
selection = Object.hasOwn(selection, key) ? (selection[key] ?? ownScope) : ownScope;
|
|
104
|
-
current = child;
|
|
38
|
+
const children = childrenOf(node);
|
|
39
|
+
for (const [key, selection] of Object.entries(scope[0])) {
|
|
40
|
+
if (key === '*') {
|
|
41
|
+
if (selection !== true)
|
|
42
|
+
badQuery('scope wildcard must be true');
|
|
43
|
+
continue;
|
|
105
44
|
}
|
|
45
|
+
if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(key) || !isSafeKey(key))
|
|
46
|
+
badQuery(`Invalid scope field ${key}`);
|
|
47
|
+
const child = children[key];
|
|
48
|
+
if (!Object.hasOwn(children, key) || child.writeOnly)
|
|
49
|
+
badQuery(`Unknown or inaccessible scope field ${key}`);
|
|
50
|
+
if (child.relation || child.base === 'object')
|
|
51
|
+
validateScope(child, selection, child.many, depth + 1);
|
|
52
|
+
else if (selection !== true)
|
|
53
|
+
badQuery(`Scalar field ${key} must be true`);
|
|
106
54
|
}
|
|
107
55
|
}
|
|
108
56
|
//# sourceMappingURL=options.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/rest/options.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/rest/options.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { Entity } from '../model.js';
|
|
1
|
+
import type { Engine, PreparedList } from '../engine.js';
|
|
2
|
+
import type { Entity, Node } from '../model.js';
|
|
3
|
+
import { type Ref } from '../records.js';
|
|
3
4
|
import type { JsonObject } from '../types.js';
|
|
4
5
|
import { type RestOptions, type Scope } from './options.js';
|
|
5
|
-
export declare function validateRest(engine: Engine, entity: Entity, options: RestOptions): Map<
|
|
6
|
-
export declare function project(engine: Engine, ref: Ref, scope?: Scope,
|
|
6
|
+
export declare function validateRest(engine: Engine, entity: Entity, options: RestOptions, list?: boolean): Map<Scope | Node, PreparedList>;
|
|
7
|
+
export declare function project(engine: Engine, ref: Ref, scope?: Scope, plans?: Map<Node | Scope, PreparedList>): JsonObject;
|
|
@@ -1,35 +1,52 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { ownScope,
|
|
4
|
-
export function validateRest(engine, entity, options) {
|
|
5
|
-
validateScope(entity.root, options.scope);
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { childrenOf } from '../query/options.js';
|
|
2
|
+
import { isRef, resolveField } from '../records.js';
|
|
3
|
+
import { ownScope, scopeFor, validateScope } from './options.js';
|
|
4
|
+
export function validateRest(engine, entity, options, list = false) {
|
|
5
|
+
validateScope(entity.root, options.scope, list);
|
|
6
|
+
const plans = new Map();
|
|
7
|
+
if (list)
|
|
8
|
+
plans.set(options.scope, engine.prepareOptions(entity.root, options.scope[1]));
|
|
9
|
+
const visit = (node, scope) => {
|
|
10
|
+
for (const [key, selection] of Object.entries(scope[0])) {
|
|
11
|
+
if (selection === true)
|
|
12
|
+
continue;
|
|
13
|
+
const child = childrenOf(node)[key];
|
|
14
|
+
if (selection[1])
|
|
15
|
+
plans.set(selection, engine.prepareOptions(child, selection[1]));
|
|
16
|
+
visit(child, selection);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
visit(entity.root, options.scope);
|
|
20
|
+
return plans;
|
|
8
21
|
}
|
|
9
|
-
export function project(engine, ref, scope = ownScope,
|
|
22
|
+
export function project(engine, ref, scope = ownScope, plans = new Map()) {
|
|
10
23
|
const output = Object.create(null);
|
|
11
24
|
const children = childrenOf(ref.node);
|
|
12
25
|
for (const [key, node] of Object.entries(children)) {
|
|
13
|
-
if (node.writeOnly || (!Object.hasOwn(scope, key) && !(Object.hasOwn(scope, '*') && !node.relation)))
|
|
26
|
+
if (node.writeOnly || (!Object.hasOwn(scope[0], key) && !(Object.hasOwn(scope[0], '*') && !node.relation)))
|
|
14
27
|
continue;
|
|
15
28
|
const value = resolveField(ref, node);
|
|
16
|
-
const selection =
|
|
17
|
-
const path = prefix + key;
|
|
29
|
+
const selection = scopeFor(scope, key);
|
|
18
30
|
if (value === undefined)
|
|
19
31
|
continue;
|
|
20
32
|
if (isRef(value))
|
|
21
|
-
output[key] = project(engine, value, selection,
|
|
22
|
-
else if (Array.isArray(value)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
output[key] = project(engine, value, selection, plans);
|
|
34
|
+
else if (Array.isArray(value)) {
|
|
35
|
+
if (value.every(isRef) && (value.length > 0 || node.relation || node.base === 'object')) {
|
|
36
|
+
const planKey = selection === ownScope ? node : selection;
|
|
37
|
+
const prepared = plans.get(planKey) ?? engine.prepareOptions(node, selection[1]);
|
|
38
|
+
plans.set(planKey, prepared);
|
|
39
|
+
const page = engine.list(value, node, selection[1], prepared);
|
|
40
|
+
output[key] = { data: page.data.map((v) => project(engine, v, selection, plans)), total: page.total };
|
|
41
|
+
}
|
|
42
|
+
else
|
|
43
|
+
output[key] = value.map((item) => (isRef(item) ? project(engine, item, selection, plans) : structuredClone(item)));
|
|
27
44
|
}
|
|
28
45
|
else
|
|
29
46
|
output[key] = structuredClone(value);
|
|
30
47
|
}
|
|
31
|
-
// Schemaless REST includes
|
|
32
|
-
if (!ref.context.model.explicit && scope['*'] ===
|
|
48
|
+
// Schemaless REST includes raw fields absent from the inferred model.
|
|
49
|
+
if (!ref.context.model.explicit && scope[0]['*'] === true)
|
|
33
50
|
for (const [key, value] of Object.entries(ref.value))
|
|
34
51
|
if (!Object.hasOwn(output, key) && !children[key]?.relation)
|
|
35
52
|
output[key] = structuredClone(value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projection.js","sourceRoot":"","sources":["../../../src/rest/projection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"projection.js","sourceRoot":"","sources":["../../../src/rest/projection.ts"],"names":[],"mappings":"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"}
|
package/dist/src/rest/routes.js
CHANGED
|
@@ -9,20 +9,20 @@ export function registerRestRoutes(server, engine) {
|
|
|
9
9
|
server.get(path, async (request) => {
|
|
10
10
|
const context = await engine.context();
|
|
11
11
|
const entity = context.model.byCollection.get(initial.collection);
|
|
12
|
-
const options = parseRestOptions(request.query
|
|
13
|
-
const plans = validateRest(engine, entity, options);
|
|
14
|
-
const page = engine.list(engine.records(context, entity), entity.root, options);
|
|
15
|
-
return { data: page.data.map((ref) => project(engine, ref, options.scope,
|
|
12
|
+
const options = parseRestOptions(request.query);
|
|
13
|
+
const plans = validateRest(engine, entity, options, true);
|
|
14
|
+
const page = engine.list(engine.records(context, entity), entity.root, undefined, plans.get(options.scope));
|
|
15
|
+
return { data: page.data.map((ref) => project(engine, ref, options.scope, plans)), total: page.total };
|
|
16
16
|
});
|
|
17
17
|
server.get(itemPath, async (request) => {
|
|
18
18
|
const context = await engine.context();
|
|
19
19
|
const entity = context.model.byCollection.get(initial.collection);
|
|
20
|
-
const options = parseRestOptions(request.query
|
|
20
|
+
const options = parseRestOptions(request.query);
|
|
21
21
|
const plans = validateRest(engine, entity, options);
|
|
22
22
|
const ref = engine.find(context, entity, request.params[entity.primary]);
|
|
23
23
|
if (!ref)
|
|
24
24
|
throw domainError('NOT_FOUND', 'Record not found');
|
|
25
|
-
return project(engine, ref, options.scope,
|
|
25
|
+
return project(engine, ref, options.scope, plans);
|
|
26
26
|
});
|
|
27
27
|
for (const [method, mode] of [
|
|
28
28
|
['POST', 'create'],
|
|
@@ -34,10 +34,10 @@ export function registerRestRoutes(server, engine) {
|
|
|
34
34
|
method,
|
|
35
35
|
url: mode === 'create' ? path : itemPath,
|
|
36
36
|
handler: async (request, reply) => {
|
|
37
|
-
const options = parseRestOptions(request.query
|
|
37
|
+
const options = parseRestOptions(request.query);
|
|
38
38
|
const result = await engine.mutate(initial, mode, request.params[initial.primary], request.body, (ref) => {
|
|
39
39
|
const plans = validateRest(engine, ref.entity, options);
|
|
40
|
-
return project(engine, ref, options.scope,
|
|
40
|
+
return project(engine, ref, options.scope, plans);
|
|
41
41
|
});
|
|
42
42
|
return reply.code(mode === 'create' ? 201 : 200).send(result);
|
|
43
43
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/rest/routes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACxD,MAAM,UAAU,kBAAkB,CAAC,MAAuB,EAAE,MAAc;IACxE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;IACvG,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,GAAG,IAAI,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;QAC/C,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACjC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAE,CAAC;YACnE,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/rest/routes.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED