@kollors/deep-json-server 1.0.0-alpha.2 → 1.0.0-alpha.4
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 +103 -19
- package/README.ru.md +103 -19
- package/dist/index.d.ts +2 -1
- package/dist/index.js.map +1 -1
- package/dist/src/cli.d.ts +2 -2
- package/dist/src/cli.js +22 -15
- package/dist/src/cli.js.map +1 -1
- package/dist/src/config.d.ts +12 -1
- package/dist/src/config.js +40 -5
- package/dist/src/config.js.map +1 -1
- package/dist/src/constants.d.ts +1 -1
- package/dist/src/constants.js +1 -1
- package/dist/src/database.d.ts +0 -1
- package/dist/src/database.js +12 -10
- package/dist/src/database.js.map +1 -1
- package/dist/src/engine.d.ts +16 -26
- package/dist/src/engine.js +36 -149
- package/dist/src/engine.js.map +1 -1
- package/dist/src/errors.d.ts +1 -1
- package/dist/src/files/contract.d.ts +0 -30
- package/dist/src/files/contract.js +6 -47
- package/dist/src/files/contract.js.map +1 -1
- package/dist/src/files/disk-store.d.ts +2 -1
- package/dist/src/files/disk-store.js +24 -14
- package/dist/src/files/disk-store.js.map +1 -1
- package/dist/src/files/http.d.ts +31 -0
- package/dist/src/files/http.js +44 -0
- package/dist/src/files/http.js.map +1 -0
- package/dist/src/files/index.d.ts +1 -1
- package/dist/src/files/index.js +1 -1
- package/dist/src/files/index.js.map +1 -1
- package/dist/src/files/memory-store.js +8 -7
- package/dist/src/files/memory-store.js.map +1 -1
- package/dist/src/files/openapi.js +2 -4
- package/dist/src/files/openapi.js.map +1 -1
- package/dist/src/files/routes.js +3 -2
- package/dist/src/files/routes.js.map +1 -1
- package/dist/src/graphql/entry.d.ts +3 -0
- package/dist/src/graphql/entry.js +3 -0
- package/dist/src/graphql/entry.js.map +1 -0
- package/dist/src/graphql/preflight.d.ts +3 -3
- package/dist/src/graphql/preflight.js +4 -2
- package/dist/src/graphql/preflight.js.map +1 -1
- package/dist/src/graphql/public.d.ts +3 -0
- package/dist/src/graphql/public.js +11 -0
- package/dist/src/graphql/public.js.map +1 -0
- package/dist/src/graphql/resolvers.d.ts +8 -0
- package/dist/src/graphql/resolvers.js +38 -0
- package/dist/src/graphql/resolvers.js.map +1 -0
- package/dist/src/graphql/routes.js +3 -4
- package/dist/src/graphql/routes.js.map +1 -1
- package/dist/src/graphql/write.d.ts +1 -0
- package/dist/src/graphql/write.js +7 -0
- package/dist/src/graphql/write.js.map +1 -0
- package/dist/src/graphql.d.ts +1 -2
- package/dist/src/graphql.js +18 -27
- package/dist/src/graphql.js.map +1 -1
- package/dist/src/http/errors.d.ts +6 -0
- package/dist/src/http/errors.js +3 -0
- package/dist/src/http/errors.js.map +1 -0
- package/dist/src/model.d.ts +6 -3
- package/dist/src/model.js +51 -14
- package/dist/src/model.js.map +1 -1
- package/dist/src/mutations/write.d.ts +25 -0
- package/dist/src/mutations/write.js +270 -0
- package/dist/src/mutations/write.js.map +1 -0
- package/dist/src/openapi/document.js +58 -12
- package/dist/src/openapi/document.js.map +1 -1
- package/dist/src/openapi/entry.d.ts +3 -0
- package/dist/src/openapi/entry.js +2 -0
- package/dist/src/openapi/entry.js.map +1 -0
- package/dist/src/openapi/helpers.d.ts +17 -0
- package/dist/src/openapi/helpers.js +4 -0
- package/dist/src/openapi/helpers.js.map +1 -0
- package/dist/src/openapi/index.js +6 -4
- package/dist/src/openapi/index.js.map +1 -1
- package/dist/src/openapi/public.d.ts +17 -0
- package/dist/src/openapi/public.js +18 -0
- package/dist/src/openapi/public.js.map +1 -0
- package/dist/src/pagination.d.ts +7 -0
- package/dist/src/pagination.js +12 -0
- package/dist/src/pagination.js.map +1 -0
- package/dist/src/paths.d.ts +6 -0
- package/dist/src/paths.js +47 -0
- package/dist/src/paths.js.map +1 -0
- package/dist/src/query/filter.d.ts +1 -2
- package/dist/src/query/filter.js +2 -0
- package/dist/src/query/filter.js.map +1 -1
- package/dist/src/query/options.js +4 -2
- package/dist/src/query/options.js.map +1 -1
- package/dist/src/records.d.ts +25 -0
- package/dist/src/records.js +50 -0
- package/dist/src/records.js.map +1 -0
- package/dist/src/relation-metadata.d.ts +0 -1
- package/dist/src/relation-metadata.js +0 -1
- package/dist/src/relation-metadata.js.map +1 -1
- package/dist/src/rest/options.d.ts +3 -3
- package/dist/src/rest/options.js +22 -52
- package/dist/src/rest/options.js.map +1 -1
- package/dist/src/rest/projection.d.ts +3 -3
- package/dist/src/rest/projection.js +11 -10
- package/dist/src/rest/projection.js.map +1 -1
- package/dist/src/rest/routes.js +6 -6
- package/dist/src/rest/routes.js.map +1 -1
- package/dist/src/schema.d.ts +6 -15
- package/dist/src/schema.js +7 -17
- package/dist/src/schema.js.map +1 -1
- package/dist/src/server/public.d.ts +3 -0
- package/dist/src/server/public.js +2 -0
- package/dist/src/server/public.js.map +1 -0
- package/dist/src/server.d.ts +3 -2
- package/dist/src/server.js +43 -36
- package/dist/src/server.js.map +1 -1
- package/dist/src/utils.d.ts +0 -7
- package/dist/src/utils.js +0 -4
- package/dist/src/utils.js.map +1 -1
- package/package.json +13 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relation-metadata.js","sourceRoot":"","sources":["../../src/relation-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAU3E,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"relation-metadata.js","sourceRoot":"","sources":["../../src/relation-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAU3E,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,aAAuB,EAAE,QAAgB,EAAE,cAAsB,EAAsB,EAAE;IAC/H,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,KAAK,QAAQ,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,WAAW,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC,CAAC;IAEjK,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QACrB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,aAAa,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7G,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,GAAW,EAAE,aAAuB,EAAE,cAAsB,EAAgC,EAAE;IAChI,yEAAyE;IACzE,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAE1C,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,KAAK,KAAK,CAAC;IAChC,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,IAAI,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAClI,MAAM,cAAc,GAAG,uBAAuB,CAAC,aAAa,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;IAE5F,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;QAC3B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,MAAM;QACN,YAAY;QACZ,mBAAmB,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc;QAC/F,cAAc;QACd,cAAc;KACf,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { Node } from '../model.js';
|
|
2
2
|
import { type ListOptions } from '../query/options.js';
|
|
3
3
|
export interface Scope {
|
|
4
|
-
[key: string]: Scope |
|
|
4
|
+
[key: string]: Scope | true;
|
|
5
5
|
}
|
|
6
6
|
export interface RestOptions extends ListOptions {
|
|
7
7
|
scope: Scope;
|
|
8
8
|
nested: Record<string, ListOptions>;
|
|
9
9
|
}
|
|
10
10
|
export declare const ownScope: Scope;
|
|
11
|
-
export declare function
|
|
11
|
+
export declare function scopeFor(scope: Scope, key: string): Scope;
|
|
12
12
|
export declare function parseRestOptions(query: unknown, list: boolean): RestOptions;
|
|
13
|
-
export declare function validateScope(node: Node, scope:
|
|
13
|
+
export declare function validateScope(node: Node, scope: unknown, depth?: number): asserts scope is Scope;
|
|
14
14
|
export declare function validateNested(root: Node, scope: Scope, nested: Record<string, ListOptions>): void;
|
package/dist/src/rest/options.js
CHANGED
|
@@ -1,51 +1,10 @@
|
|
|
1
1
|
import { pathParts } from '../model.js';
|
|
2
2
|
import { badQuery, childrenOf, nodeAt } from '../query/options.js';
|
|
3
|
-
import { isObject } from '../utils.js';
|
|
4
|
-
export const ownScope = { '*':
|
|
5
|
-
export function
|
|
6
|
-
|
|
7
|
-
|
|
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;
|
|
3
|
+
import { isObject, isSafeKey } from '../utils.js';
|
|
4
|
+
export const ownScope = { '*': true };
|
|
5
|
+
export function scopeFor(scope, key) {
|
|
6
|
+
const selection = Object.hasOwn(scope, key) ? scope[key] : true;
|
|
7
|
+
return selection === true ? ownScope : selection;
|
|
49
8
|
}
|
|
50
9
|
export function parseRestOptions(query, list) {
|
|
51
10
|
if (!isObject(query))
|
|
@@ -54,12 +13,14 @@ export function parseRestOptions(query, list) {
|
|
|
54
13
|
for (const key of Object.keys(query))
|
|
55
14
|
if (!allowed.includes(key))
|
|
56
15
|
badQuery(`Unknown query parameter ${key}`);
|
|
57
|
-
const result = { scope:
|
|
58
|
-
for (const key of ['where', 'order', 'pager', 'nested']) {
|
|
16
|
+
const result = { scope: ownScope, nested: {} };
|
|
17
|
+
for (const key of ['scope', 'where', 'order', 'pager', 'nested']) {
|
|
59
18
|
if (query[key] === undefined)
|
|
60
19
|
continue;
|
|
61
20
|
if (typeof query[key] !== 'string')
|
|
62
21
|
badQuery(`${key} must occur once and contain JSON`);
|
|
22
|
+
if (key === 'scope' && query[key].length > 10000)
|
|
23
|
+
badQuery('scope must contain at most 10000 characters');
|
|
63
24
|
try {
|
|
64
25
|
result[key] = JSON.parse(query[key]);
|
|
65
26
|
}
|
|
@@ -72,15 +33,24 @@ export function parseRestOptions(query, list) {
|
|
|
72
33
|
return result;
|
|
73
34
|
}
|
|
74
35
|
export function validateScope(node, scope, depth = 0) {
|
|
36
|
+
if (!isObject(scope))
|
|
37
|
+
badQuery('scope must be a JSON object');
|
|
75
38
|
if (depth > 32)
|
|
76
39
|
badQuery('scope is too deep');
|
|
77
40
|
for (const [key, selection] of Object.entries(scope)) {
|
|
78
|
-
if (key === '*')
|
|
41
|
+
if (key === '*') {
|
|
42
|
+
if (selection !== true)
|
|
43
|
+
badQuery('scope wildcard must be true');
|
|
79
44
|
continue;
|
|
45
|
+
}
|
|
46
|
+
if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(key) || !isSafeKey(key))
|
|
47
|
+
badQuery(`Invalid scope field ${key}`);
|
|
48
|
+
if (selection !== true && !isObject(selection))
|
|
49
|
+
badQuery(`scope.${key} must be true or an object`);
|
|
80
50
|
const child = childrenOf(node)[key];
|
|
81
|
-
if (!
|
|
51
|
+
if (!Object.hasOwn(childrenOf(node), key) || child.writeOnly)
|
|
82
52
|
badQuery(`Unknown or inaccessible scope field ${key}`);
|
|
83
|
-
if (selection) {
|
|
53
|
+
if (selection !== true) {
|
|
84
54
|
if (!child.relation && child.base !== 'object')
|
|
85
55
|
badQuery(`Scalar field ${key} cannot have a selection`);
|
|
86
56
|
validateScope(child, selection, depth + 1);
|
|
@@ -100,7 +70,7 @@ export function validateNested(root, scope, nested) {
|
|
|
100
70
|
const child = childrenOf(current)[key];
|
|
101
71
|
if (!Object.hasOwn(selection, key) && !(Object.hasOwn(selection, '*') && !child.relation))
|
|
102
72
|
badQuery(`nested path ${path} is not selected by scope`);
|
|
103
|
-
selection =
|
|
73
|
+
selection = scopeFor(selection, key);
|
|
104
74
|
current = child;
|
|
105
75
|
}
|
|
106
76
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/rest/options.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAoB,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/rest/options.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type Engine, type Ref } from '../engine.js';
|
|
1
|
+
import { type Engine, type PreparedList, type Ref } from '../engine.js';
|
|
2
2
|
import type { Entity } from '../model.js';
|
|
3
3
|
import type { JsonObject } from '../types.js';
|
|
4
4
|
import { type RestOptions, type Scope } from './options.js';
|
|
5
|
-
export declare function validateRest(engine: Engine, entity: Entity, options: RestOptions):
|
|
6
|
-
export declare function project(engine: Engine, ref: Ref, scope?: Scope, nested?: RestOptions['nested'], prefix?: string): JsonObject;
|
|
5
|
+
export declare function validateRest(engine: Engine, entity: Entity, options: RestOptions): Map<string, PreparedList>;
|
|
6
|
+
export declare function project(engine: Engine, ref: Ref, scope?: Scope, nested?: RestOptions['nested'], prefix?: string, plans?: Map<string, PreparedList>): JsonObject;
|
|
@@ -1,34 +1,35 @@
|
|
|
1
1
|
import { isRef, resolveField } from '../engine.js';
|
|
2
2
|
import { childrenOf, nodeAt } from '../query/options.js';
|
|
3
|
-
import { ownScope, validateNested, validateScope } from './options.js';
|
|
3
|
+
import { ownScope, scopeFor, validateNested, validateScope } from './options.js';
|
|
4
4
|
export function validateRest(engine, entity, options) {
|
|
5
5
|
validateScope(entity.root, options.scope);
|
|
6
6
|
validateNested(entity.root, options.scope, options.nested);
|
|
7
|
-
|
|
8
|
-
engine.validateOptions(nodeAt(entity.root, path), nested);
|
|
7
|
+
return new Map(Object.entries(options.nested).map(([path, nested]) => [path, engine.prepareOptions(nodeAt(entity.root, path), nested)]));
|
|
9
8
|
}
|
|
10
|
-
export function project(engine, ref, scope = ownScope, nested = {}, prefix = '') {
|
|
9
|
+
export function project(engine, ref, scope = ownScope, nested = {}, prefix = '', plans = new Map()) {
|
|
11
10
|
const output = Object.create(null);
|
|
12
11
|
const children = childrenOf(ref.node);
|
|
13
12
|
for (const [key, node] of Object.entries(children)) {
|
|
14
13
|
if (node.writeOnly || (!Object.hasOwn(scope, key) && !(Object.hasOwn(scope, '*') && !node.relation)))
|
|
15
14
|
continue;
|
|
16
15
|
const value = resolveField(ref, node);
|
|
17
|
-
const selection =
|
|
16
|
+
const selection = scopeFor(scope, key);
|
|
18
17
|
const path = prefix + key;
|
|
19
18
|
if (value === undefined)
|
|
20
19
|
continue;
|
|
21
20
|
if (isRef(value))
|
|
22
|
-
output[key] = project(engine, value, selection, nested, `${path}
|
|
23
|
-
else if (
|
|
24
|
-
const
|
|
25
|
-
|
|
21
|
+
output[key] = project(engine, value, selection, nested, `${path}.`, plans);
|
|
22
|
+
else if (Array.isArray(value) && value.every(isRef) && (value.length > 0 || node.relation || node.base === 'object')) {
|
|
23
|
+
const prepared = plans.get(path) ?? engine.prepareOptions(node, nested[path]);
|
|
24
|
+
plans.set(path, prepared);
|
|
25
|
+
const page = engine.list(value, node, nested[path], prepared);
|
|
26
|
+
output[key] = { data: page.data.map((v) => project(engine, v, selection, nested, `${path}.`, plans)), total: page.total };
|
|
26
27
|
}
|
|
27
28
|
else
|
|
28
29
|
output[key] = structuredClone(value);
|
|
29
30
|
}
|
|
30
31
|
// Schemaless REST includes all raw fields, including fields absent in earlier records.
|
|
31
|
-
if (!ref.context.model.explicit && scope['*'] ===
|
|
32
|
+
if (!ref.context.model.explicit && scope['*'] === true)
|
|
32
33
|
for (const [key, value] of Object.entries(ref.value))
|
|
33
34
|
if (!Object.hasOwn(output, key) && !children[key]?.relation)
|
|
34
35
|
output[key] = structuredClone(value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projection.js","sourceRoot":"","sources":["../../../src/rest/projection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,
|
|
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
|
@@ -10,19 +10,19 @@ export function registerRestRoutes(server, engine) {
|
|
|
10
10
|
const context = await engine.context();
|
|
11
11
|
const entity = context.model.byCollection.get(initial.collection);
|
|
12
12
|
const options = parseRestOptions(request.query, true);
|
|
13
|
-
validateRest(engine, entity, options);
|
|
13
|
+
const plans = validateRest(engine, entity, options);
|
|
14
14
|
const page = engine.list(engine.records(context, entity), entity.root, options);
|
|
15
|
-
return { data: page.data.map((ref) => project(engine, ref, options.scope, options.nested)), total: page.total };
|
|
15
|
+
return { data: page.data.map((ref) => project(engine, ref, options.scope, options.nested, '', 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
20
|
const options = parseRestOptions(request.query, false);
|
|
21
|
-
validateRest(engine, entity, options);
|
|
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, options.nested);
|
|
25
|
+
return project(engine, ref, options.scope, options.nested, '', plans);
|
|
26
26
|
});
|
|
27
27
|
for (const [method, mode] of [
|
|
28
28
|
['POST', 'create'],
|
|
@@ -36,8 +36,8 @@ export function registerRestRoutes(server, engine) {
|
|
|
36
36
|
handler: async (request, reply) => {
|
|
37
37
|
const options = parseRestOptions(request.query, false);
|
|
38
38
|
const result = await engine.mutate(initial, mode, request.params[initial.primary], request.body, (ref) => {
|
|
39
|
-
validateRest(engine, ref.entity, options);
|
|
40
|
-
return project(engine, ref, options.scope, options.nested);
|
|
39
|
+
const plans = validateRest(engine, ref.entity, options);
|
|
40
|
+
return project(engine, ref, options.scope, options.nested, '', 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,EAAE,IAAI,CAAC,CAAC;YACtD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/rest/routes.ts"],"names":[],"mappings":"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"}
|
package/dist/src/schema.d.ts
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
pageSize?: number;
|
|
7
|
-
maxPageSize?: number;
|
|
8
|
-
info?: {
|
|
9
|
-
title: string;
|
|
10
|
-
version: string;
|
|
11
|
-
description?: string;
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
export declare function generateOpenapi(schema: ModelSchema | string, options?: OpenapiOptions): Promise<import("./types.js").OpenapiDocument>;
|
|
1
|
+
import type { ModelSchema } from './model.js';
|
|
2
|
+
import type { OpenapiOptions } from './openapi/public.js';
|
|
3
|
+
import type { OpenapiDocument } from './types.js';
|
|
4
|
+
export type { OpenapiOptions } from './openapi/public.js';
|
|
5
|
+
export declare function generateOpenapi(schema: ModelSchema | string, options?: OpenapiOptions): Promise<OpenapiDocument>;
|
|
15
6
|
export declare function generateGraphql(schema: ModelSchema | string): Promise<string>;
|
|
7
|
+
export declare function writeOpenapi(document: OpenapiDocument, path: string): Promise<void>;
|
|
16
8
|
export declare function writeGraphql(sdl: string, path: string): Promise<void>;
|
|
17
|
-
export { writeOpenapi } from './openapi/index.js';
|
package/dist/src/schema.js
CHANGED
|
@@ -1,23 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { printSchema } from 'graphql';
|
|
4
|
-
import { buildGraphql } from './graphql.js';
|
|
5
|
-
import { assertApi, loadModel } from './model.js';
|
|
6
|
-
import { buildOpenapiDocument } from './openapi/document.js';
|
|
7
|
-
import { createOpenapi } from './openapi/index.js';
|
|
8
|
-
export async function generateOpenapi(schema, options = {}) {
|
|
9
|
-
const model = await loadModel(schema);
|
|
10
|
-
assertApi(model, 'openapi');
|
|
11
|
-
return createOpenapi({ document: buildOpenapiDocument({ model, ...options }), host: options.host, port: options.port });
|
|
1
|
+
export async function generateOpenapi(schema, options) {
|
|
2
|
+
return (await import('./openapi/public.js')).generateOpenapi(schema, options);
|
|
12
3
|
}
|
|
13
4
|
export async function generateGraphql(schema) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
return (await import('./graphql/public.js')).generateGraphql(schema);
|
|
6
|
+
}
|
|
7
|
+
export async function writeOpenapi(document, path) {
|
|
8
|
+
return (await import('./openapi/index.js')).writeOpenapi(document, path);
|
|
17
9
|
}
|
|
18
10
|
export async function writeGraphql(sdl, path) {
|
|
19
|
-
await
|
|
20
|
-
await writeFile(path, `${sdl}\n`, 'utf8');
|
|
11
|
+
return (await import('./graphql/write.js')).writeGraphql(sdl, path);
|
|
21
12
|
}
|
|
22
|
-
export { writeOpenapi } from './openapi/index.js';
|
|
23
13
|
//# sourceMappingURL=schema.js.map
|
package/dist/src/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/schema.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAA4B,EAAE,OAAwB;IAC1F,OAAO,CAAC,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAChF,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAA4B;IAChE,OAAO,CAAC,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;AACvE,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAyB,EAAE,IAAY;IACxE,OAAO,CAAC,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC3E,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,IAAY;IAC1D,OAAO,CAAC,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/server/public.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAqB,MAAM,cAAc,CAAC"}
|
package/dist/src/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { type DeepJsonServerConfig } from './config.js';
|
|
1
|
+
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
import { type DeepJsonServerConfig, type NormalizedServerConfig } from './config.js';
|
|
3
3
|
import { type ServerFeatures } from './features.js';
|
|
4
4
|
import type { OpenapiDocument } from './types.js';
|
|
5
5
|
export interface ServerFacade {
|
|
@@ -9,3 +9,4 @@ export interface ServerFacade {
|
|
|
9
9
|
}
|
|
10
10
|
export type { ServerFeatures } from './features.js';
|
|
11
11
|
export declare function createServer(config: DeepJsonServerConfig, features?: ServerFeatures): Promise<ServerFacade>;
|
|
12
|
+
export declare function createConfiguredServer(normalized: NormalizedServerConfig, features?: ServerFeatures): Promise<ServerFacade>;
|
package/dist/src/server.js
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { normalizeServerConfig } from './config.js';
|
|
4
|
-
import { DEFAULT_HOST, DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_PAGE_SIZE, DEFAULT_PORT } from './constants.js';
|
|
5
|
-
import { createDatabaseStore } from './database.js';
|
|
6
|
-
import { Engine } from './engine.js';
|
|
1
|
+
import { configSourcePath, normalizeServerConfig } from './config.js';
|
|
2
|
+
import { DEFAULT_HOST, DEFAULT_MAX_FILE_SIZE, DEFAULT_PORT } from './constants.js';
|
|
7
3
|
import { DomainError } from './errors.js';
|
|
8
4
|
import { resolveFeatures, validateEndpoints } from './features.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { buildGraphql } from './graphql.js';
|
|
13
|
-
import { assertApi, inferModel, loadModel } from './model.js';
|
|
14
|
-
import { buildOpenapiDocument } from './openapi/document.js';
|
|
15
|
-
import { createOpenapi } from './openapi/index.js';
|
|
16
|
-
import { registerRestRoutes } from './rest/routes.js';
|
|
5
|
+
import { domainStatus } from './http/errors.js';
|
|
6
|
+
import { normalizePagination } from './pagination.js';
|
|
7
|
+
import { inputPaths } from './paths.js';
|
|
17
8
|
import { isObject } from './utils.js';
|
|
18
9
|
const CORS_HEADERS = {
|
|
19
|
-
'Access-Control-Allow-Headers':
|
|
10
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
20
11
|
'Access-Control-Allow-Methods': 'DELETE, GET, OPTIONS, PATCH, POST, PUT',
|
|
21
12
|
'Access-Control-Allow-Origin': '*',
|
|
22
13
|
};
|
|
23
14
|
export async function createServer(config, features = {}) {
|
|
24
|
-
|
|
15
|
+
return createConfiguredServer(normalizeServerConfig(config), features);
|
|
16
|
+
}
|
|
17
|
+
export async function createConfiguredServer(normalized, features = {}) {
|
|
25
18
|
const enabled = resolveFeatures(normalized, features);
|
|
19
|
+
const { loadModel, inferModel } = await import('./model.js');
|
|
26
20
|
const explicitModel = await loadModel(normalized.database.schema);
|
|
27
|
-
const {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
21
|
+
const { default: Fastify } = await import('fastify');
|
|
22
|
+
const corsHeaders = { ...CORS_HEADERS };
|
|
23
|
+
if (enabled.files) {
|
|
24
|
+
const { FILE_HEADERS } = await import('./files/http.js');
|
|
25
|
+
corsHeaders['Access-Control-Allow-Headers'] = [...Object.values(FILE_HEADERS).map(({ name }) => name), 'Content-Type'].join(', ');
|
|
26
|
+
}
|
|
27
|
+
const { cors = true, logger = true, maxFileSize = DEFAULT_MAX_FILE_SIZE } = normalized.server;
|
|
28
|
+
const { pageSize, maxPageSize } = normalizePagination(normalized.server);
|
|
29
|
+
const openapi = async () => (await import('./openapi/public.js')).openapiFromModel(explicitModel, {
|
|
30
|
+
files: enabled.files,
|
|
31
|
+
pageSize,
|
|
32
|
+
maxPageSize,
|
|
33
|
+
info: normalized.openapi.info,
|
|
34
|
+
host: normalized.server.host,
|
|
35
|
+
port: normalized.server.port,
|
|
36
|
+
});
|
|
37
37
|
let instance;
|
|
38
38
|
const getFastify = () => {
|
|
39
39
|
if (instance)
|
|
@@ -47,14 +47,14 @@ export async function createServer(config, features = {}) {
|
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
49
|
if (callback) {
|
|
50
|
-
originalListen(
|
|
50
|
+
originalListen({ ...defaults, ...optionsOrCallback }, callback);
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
|
-
return originalListen(optionsOrCallback
|
|
53
|
+
return originalListen({ ...defaults, ...optionsOrCallback });
|
|
54
54
|
};
|
|
55
55
|
server.listen = listen;
|
|
56
56
|
server.setErrorHandler((error, request, reply) => {
|
|
57
|
-
const candidate = error instanceof DomainError ?
|
|
57
|
+
const candidate = error instanceof DomainError ? domainStatus[error.code] : isObject(error) ? error.statusCode : undefined;
|
|
58
58
|
const status = typeof candidate === 'number' && Number.isInteger(candidate) && candidate >= 400 && candidate <= 599 ? candidate : 500;
|
|
59
59
|
if (status === 500)
|
|
60
60
|
request.log.error(error);
|
|
@@ -62,13 +62,14 @@ export async function createServer(config, features = {}) {
|
|
|
62
62
|
});
|
|
63
63
|
if (cors) {
|
|
64
64
|
server.addHook('onRequest', async (_request, reply) => {
|
|
65
|
-
for (const [key, value] of Object.entries(
|
|
65
|
+
for (const [key, value] of Object.entries(corsHeaders))
|
|
66
66
|
reply.header(key, value);
|
|
67
67
|
});
|
|
68
68
|
server.options('/', async (_request, reply) => reply.code(204).send());
|
|
69
69
|
server.options('/*', async (_request, reply) => reply.code(204).send());
|
|
70
70
|
}
|
|
71
71
|
server.register(async (app) => {
|
|
72
|
+
const [{ createDatabaseStore }, { Engine }, { registerRestRoutes }] = await Promise.all([import('./database.js'), import('./engine.js'), import('./rest/routes.js')]);
|
|
72
73
|
const keys = explicitModel ? new Map(explicitModel.entities.map((e) => [e.collection, e.primary])) : undefined;
|
|
73
74
|
const store = await createDatabaseStore(normalized.database, keys);
|
|
74
75
|
const model = explicitModel ?? inferModel(store.database.data);
|
|
@@ -78,14 +79,21 @@ export async function createServer(config, features = {}) {
|
|
|
78
79
|
const openapiPath = normalized.openapi.endpoint ?? '/openapi.json';
|
|
79
80
|
validateEndpoints(model.entities.map((entity) => entity.collection), [...(enabled.graphql ? [graphqlPath] : []), ...(enabled.openapi ? [openapiPath] : [])]);
|
|
80
81
|
registerRestRoutes(app, engine);
|
|
81
|
-
if (enabled.graphql)
|
|
82
|
-
registerGraphqlRoutes
|
|
82
|
+
if (enabled.graphql) {
|
|
83
|
+
const [{ registerGraphqlRoutes }, { buildGraphql }] = await Promise.all([import('./graphql/routes.js'), import('./graphql.js')]);
|
|
84
|
+
registerGraphqlRoutes(app, buildGraphql(model), engine, graphqlPath);
|
|
85
|
+
}
|
|
83
86
|
if (enabled.openapi) {
|
|
84
87
|
const document = await openapi();
|
|
88
|
+
document.servers = [{ url: '/' }];
|
|
85
89
|
app.get(openapiPath, async () => document);
|
|
86
90
|
}
|
|
87
|
-
|
|
88
|
-
|
|
91
|
+
const files = normalized.files;
|
|
92
|
+
if (enabled.files && files) {
|
|
93
|
+
const { createFileStore, registerFileRoutes } = await import('./files/index.js');
|
|
94
|
+
const protectedPaths = inputPaths({ database: normalized.database }, '.', configSourcePath(normalized));
|
|
95
|
+
registerFileRoutes(app, { getStore: () => createFileStore(files, protectedPaths), maxFileSize });
|
|
96
|
+
}
|
|
89
97
|
});
|
|
90
98
|
instance = server;
|
|
91
99
|
return server;
|
|
@@ -94,8 +102,7 @@ export async function createServer(config, features = {}) {
|
|
|
94
102
|
fastify: getFastify,
|
|
95
103
|
openapi,
|
|
96
104
|
graphql: async () => {
|
|
97
|
-
|
|
98
|
-
return printSchema(buildGraphql(explicitModel));
|
|
105
|
+
return (await import('./graphql/public.js')).graphqlFromModel(explicitModel);
|
|
99
106
|
},
|
|
100
107
|
};
|
|
101
108
|
}
|
package/dist/src/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
export interface HttpError extends Error {
|
|
2
|
-
statusCode: number;
|
|
3
|
-
}
|
|
4
1
|
export declare const assertKnownKeys: (value: object, keys: Set<string>, path: string) => void;
|
|
5
|
-
export declare const createHttpError: (statusCode: number, message: string) => HttpError;
|
|
6
2
|
/** Creates a scheduler that runs mutations sequentially. */
|
|
7
3
|
export declare const createSerialQueue: () => <T>(operation: () => Promise<T> | T) => Promise<T>;
|
|
8
4
|
/** Creates a random ID that is not currently in use. */
|
|
9
5
|
export declare const createUniqueId: (isUsed: (id: string) => boolean) => string;
|
|
10
|
-
export declare const getResourceNames: (data: object) => string[];
|
|
11
6
|
export declare const isObject: (value: unknown) => value is Record<string, unknown>;
|
|
12
7
|
export declare const isSafeKey: (key: string) => boolean;
|
|
13
8
|
export declare const isSystemError: (error: unknown) => error is NodeJS.ErrnoException;
|
|
14
|
-
/** Converts a single value or an array to an array. */
|
|
15
|
-
export declare const toArray: <T>(value: T | T[]) => T[];
|
|
16
9
|
export declare const isEqual: (left: unknown, right: unknown) => boolean;
|
|
17
10
|
export declare const resolveDatabasePath: (databasePath: string) => string;
|
|
18
11
|
export declare const singularize: (value: string) => string;
|
package/dist/src/utils.js
CHANGED
|
@@ -8,7 +8,6 @@ export const assertKnownKeys = (value, keys, path) => {
|
|
|
8
8
|
throw new Error(`Неизвестный ключ ${path}.${unknownKey}`);
|
|
9
9
|
}
|
|
10
10
|
};
|
|
11
|
-
export const createHttpError = (statusCode, message) => Object.assign(new Error(message), { statusCode });
|
|
12
11
|
/** Creates a scheduler that runs mutations sequentially. */
|
|
13
12
|
export const createSerialQueue = () => {
|
|
14
13
|
let queue = Promise.resolve();
|
|
@@ -27,12 +26,9 @@ export const createUniqueId = (isUsed) => {
|
|
|
27
26
|
} while (isUsed(id));
|
|
28
27
|
return id;
|
|
29
28
|
};
|
|
30
|
-
export const getResourceNames = (data) => Object.keys(data);
|
|
31
29
|
export const isObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
32
30
|
export const isSafeKey = (key) => !UNSAFE_KEYS.has(key);
|
|
33
31
|
export const isSystemError = (error) => error instanceof Error && 'code' in error;
|
|
34
|
-
/** Converts a single value or an array to an array. */
|
|
35
|
-
export const toArray = (value) => (Array.isArray(value) ? value : [value]);
|
|
36
32
|
export const isEqual = (left, right) => {
|
|
37
33
|
if (Object.is(left, right)) {
|
|
38
34
|
return true;
|