@kollors/deep-json-server 1.0.0-alpha.1 → 1.0.0-alpha.3
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 +104 -53
- package/README.ru.md +103 -50
- package/dist/index.d.ts +5 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/src/cli.d.ts +2 -2
- package/dist/src/cli.js +97 -48
- package/dist/src/cli.js.map +1 -1
- package/dist/src/config.d.ts +14 -1
- package/dist/src/config.js +56 -8
- package/dist/src/config.js.map +1 -1
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/constants.js +1 -0
- package/dist/src/constants.js.map +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 +21 -10
- package/dist/src/engine.js +77 -144
- package/dist/src/engine.js.map +1 -1
- package/dist/src/errors.d.ts +6 -0
- package/dist/src/errors.js +9 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/features.d.ts +8 -0
- package/dist/src/features.js +18 -0
- package/dist/src/features.js.map +1 -0
- 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 +28 -18
- 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 -0
- package/dist/src/graphql/preflight.js +30 -0
- package/dist/src/graphql/preflight.js.map +1 -0
- 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.d.ts +4 -0
- package/dist/src/graphql/routes.js +27 -0
- package/dist/src/graphql/routes.js.map +1 -0
- 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 +24 -34
- 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 +2 -3
- package/dist/src/model.js +54 -12
- package/dist/src/model.js.map +1 -1
- package/dist/src/openapi/document.js +36 -29
- 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/contract.d.ts +3 -0
- package/dist/src/query/contract.js +19 -0
- package/dist/src/query/contract.js.map +1 -0
- package/dist/src/query/filter.d.ts +3 -1
- package/dist/src/query/filter.js +78 -76
- package/dist/src/query/filter.js.map +1 -1
- package/dist/src/query/options.d.ts +1 -14
- package/dist/src/query/options.js +6 -109
- package/dist/src/query/options.js.map +1 -1
- 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 +14 -0
- package/dist/src/rest/options.js +108 -0
- package/dist/src/rest/options.js.map +1 -0
- package/dist/src/rest/projection.d.ts +6 -0
- package/dist/src/rest/projection.js +38 -0
- package/dist/src/rest/projection.js.map +1 -0
- package/dist/src/rest/routes.d.ts +3 -0
- package/dist/src/rest/routes.js +48 -0
- package/dist/src/rest/routes.js.map +1 -0
- package/dist/src/schema.d.ts +8 -0
- package/dist/src/schema.js +13 -0
- package/dist/src/schema.js.map +1 -0
- 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 +5 -7
- package/dist/src/server.js +86 -143
- 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
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { domainError } from '../errors.js';
|
|
2
|
+
import { parseRestOptions } from './options.js';
|
|
3
|
+
import { project, validateRest } from './projection.js';
|
|
4
|
+
export function registerRestRoutes(server, engine) {
|
|
5
|
+
server.get('/', async () => ({ resources: engine.model.entities.map((entity) => entity.collection) }));
|
|
6
|
+
for (const initial of engine.model.entities) {
|
|
7
|
+
const path = `/${initial.collection}`;
|
|
8
|
+
const itemPath = `${path}/:${initial.primary}`;
|
|
9
|
+
server.get(path, async (request) => {
|
|
10
|
+
const context = await engine.context();
|
|
11
|
+
const entity = context.model.byCollection.get(initial.collection);
|
|
12
|
+
const options = parseRestOptions(request.query, true);
|
|
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, options.nested, '', plans)), total: page.total };
|
|
16
|
+
});
|
|
17
|
+
server.get(itemPath, async (request) => {
|
|
18
|
+
const context = await engine.context();
|
|
19
|
+
const entity = context.model.byCollection.get(initial.collection);
|
|
20
|
+
const options = parseRestOptions(request.query, false);
|
|
21
|
+
const plans = validateRest(engine, entity, options);
|
|
22
|
+
const ref = engine.find(context, entity, request.params[entity.primary]);
|
|
23
|
+
if (!ref)
|
|
24
|
+
throw domainError('NOT_FOUND', 'Record not found');
|
|
25
|
+
return project(engine, ref, options.scope, options.nested, '', plans);
|
|
26
|
+
});
|
|
27
|
+
for (const [method, mode] of [
|
|
28
|
+
['POST', 'create'],
|
|
29
|
+
['PUT', 'replace'],
|
|
30
|
+
['PATCH', 'update'],
|
|
31
|
+
['DELETE', 'delete'],
|
|
32
|
+
]) {
|
|
33
|
+
server.route({
|
|
34
|
+
method,
|
|
35
|
+
url: mode === 'create' ? path : itemPath,
|
|
36
|
+
handler: async (request, reply) => {
|
|
37
|
+
const options = parseRestOptions(request.query, false);
|
|
38
|
+
const result = await engine.mutate(initial, mode, request.params[initial.primary], request.body, (ref) => {
|
|
39
|
+
const plans = validateRest(engine, ref.entity, options);
|
|
40
|
+
return project(engine, ref, options.scope, options.nested, '', plans);
|
|
41
|
+
});
|
|
42
|
+
return reply.code(mode === 'create' ? 201 : 200).send(result);
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/rest/routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
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>;
|
|
6
|
+
export declare function generateGraphql(schema: ModelSchema | string): Promise<string>;
|
|
7
|
+
export declare function writeOpenapi(document: OpenapiDocument, path: string): Promise<void>;
|
|
8
|
+
export declare function writeGraphql(sdl: string, path: string): Promise<void>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export async function generateOpenapi(schema, options) {
|
|
2
|
+
return (await import('./openapi/public.js')).generateOpenapi(schema, options);
|
|
3
|
+
}
|
|
4
|
+
export async function generateGraphql(schema) {
|
|
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);
|
|
9
|
+
}
|
|
10
|
+
export async function writeGraphql(sdl, path) {
|
|
11
|
+
return (await import('./graphql/write.js')).writeGraphql(sdl, path);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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,14 +1,12 @@
|
|
|
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
|
+
import { type ServerFeatures } from './features.js';
|
|
3
4
|
import type { OpenapiDocument } from './types.js';
|
|
4
5
|
export interface ServerFacade {
|
|
5
6
|
fastify(): FastifyInstance;
|
|
6
7
|
openapi(): Promise<OpenapiDocument>;
|
|
7
8
|
graphql(): Promise<string>;
|
|
8
9
|
}
|
|
9
|
-
export
|
|
10
|
-
files?: boolean;
|
|
11
|
-
graphql?: boolean;
|
|
12
|
-
}
|
|
13
|
-
/** Creates REST, GraphQL and independent schema exporters from a shared model. */
|
|
10
|
+
export type { ServerFeatures } from './features.js';
|
|
14
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,165 +1,108 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { Engine, makeContext } from './engine.js';
|
|
10
|
-
import { FILE_HEADERS } from './files/contract.js';
|
|
11
|
-
import { createFileStore, registerFileRoutes } from './files/index.js';
|
|
12
|
-
import { buildGraphql } from './graphql.js';
|
|
13
|
-
import { assertApi, inferModel, loadModel } from './model.js';
|
|
14
|
-
import { buildOpenapiDocument } from './openapi/document.js';
|
|
15
|
-
import { createOpenapi, writeOpenapi } from './openapi/index.js';
|
|
16
|
-
import { parseRestOptions } from './query/options.js';
|
|
17
|
-
import { createHttpError, isObject } from './utils.js';
|
|
1
|
+
import { configSourcePath, normalizeServerConfig } from './config.js';
|
|
2
|
+
import { DEFAULT_HOST, DEFAULT_MAX_FILE_SIZE, DEFAULT_PORT } from './constants.js';
|
|
3
|
+
import { DomainError } from './errors.js';
|
|
4
|
+
import { resolveFeatures, validateEndpoints } from './features.js';
|
|
5
|
+
import { domainStatus } from './http/errors.js';
|
|
6
|
+
import { normalizePagination } from './pagination.js';
|
|
7
|
+
import { inputPaths } from './paths.js';
|
|
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
|
-
/** Creates REST, GraphQL and independent schema exporters from a shared model. */
|
|
24
14
|
export async function createServer(config, features = {}) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
getGraphql();
|
|
15
|
+
return createConfiguredServer(normalizeServerConfig(config), features);
|
|
16
|
+
}
|
|
17
|
+
export async function createConfiguredServer(normalized, features = {}) {
|
|
18
|
+
const enabled = resolveFeatures(normalized, features);
|
|
19
|
+
const { loadModel, inferModel } = await import('./model.js');
|
|
20
|
+
const explicitModel = await loadModel(normalized.database.schema);
|
|
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
|
+
let instance;
|
|
49
38
|
const getFastify = () => {
|
|
50
|
-
if (
|
|
51
|
-
return
|
|
52
|
-
const
|
|
53
|
-
const originalListen =
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
const listenWithDefaults = (optionsOrCallback, callback) => {
|
|
39
|
+
if (instance)
|
|
40
|
+
return instance;
|
|
41
|
+
const server = Fastify({ ajv: { customOptions: { coerceTypes: false, removeAdditional: false } }, logger });
|
|
42
|
+
const originalListen = server.listen.bind(server);
|
|
43
|
+
const defaults = { host: normalized.server.host ?? DEFAULT_HOST, port: normalized.server.port ?? DEFAULT_PORT };
|
|
44
|
+
const listen = (optionsOrCallback, callback) => {
|
|
57
45
|
if (typeof optionsOrCallback === 'function') {
|
|
58
|
-
originalListen(
|
|
59
|
-
return
|
|
46
|
+
originalListen(defaults, optionsOrCallback);
|
|
47
|
+
return;
|
|
60
48
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return undefined;
|
|
49
|
+
if (callback) {
|
|
50
|
+
originalListen({ ...defaults, ...optionsOrCallback }, callback);
|
|
51
|
+
return;
|
|
65
52
|
}
|
|
66
|
-
return originalListen(
|
|
53
|
+
return originalListen({ ...defaults, ...optionsOrCallback });
|
|
67
54
|
};
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
for (const [header, value] of Object.entries(CORS_HEADERS))
|
|
72
|
-
reply.header(header, value);
|
|
73
|
-
});
|
|
74
|
-
fastify.options('/', async (_request, reply) => reply.code(204).send());
|
|
75
|
-
fastify.options('/*', async (_request, reply) => reply.code(204).send());
|
|
76
|
-
}
|
|
77
|
-
const resources = model.entities.map((e) => e.collection);
|
|
78
|
-
fastify.get('/', async () => ({ resources }));
|
|
79
|
-
for (const initialEntity of model.entities) {
|
|
80
|
-
const collection = initialEntity.collection;
|
|
81
|
-
const path = `/${collection}`;
|
|
82
|
-
const itemPath = `${path}/:${initialEntity.primary}`;
|
|
83
|
-
if (graphqlEnabled && path === (normalizedConfig.graphql.endpoint ?? '/graphql'))
|
|
84
|
-
throw new Error('GraphQL endpoint conflicts with collection');
|
|
85
|
-
fastify.get(path, async (request) => {
|
|
86
|
-
const context = await engine.context();
|
|
87
|
-
const entity = engine.entity(collection);
|
|
88
|
-
const options = parseRestOptions(request.query, true);
|
|
89
|
-
engine.validateRest(entity, options);
|
|
90
|
-
const page = engine.list(engine.records(context, entity), entity.root, options);
|
|
91
|
-
return { data: page.data.map((ref) => engine.project(ref, options.scope, options.nested)), total: page.total };
|
|
92
|
-
});
|
|
93
|
-
fastify.get(itemPath, async (request) => {
|
|
94
|
-
const context = await engine.context();
|
|
95
|
-
const entity = engine.entity(collection);
|
|
96
|
-
const options = parseRestOptions(request.query, false);
|
|
97
|
-
engine.validateRest(entity, options);
|
|
98
|
-
const ref = engine.find(context, entity, request.params[entity.primary]);
|
|
99
|
-
if (!ref)
|
|
100
|
-
throw createHttpError(404, 'Record not found');
|
|
101
|
-
return engine.project(ref, options.scope, options.nested);
|
|
102
|
-
});
|
|
103
|
-
for (const [method, mode] of [
|
|
104
|
-
['POST', 'create'],
|
|
105
|
-
['PUT', 'replace'],
|
|
106
|
-
['PATCH', 'update'],
|
|
107
|
-
['DELETE', 'delete'],
|
|
108
|
-
]) {
|
|
109
|
-
fastify.route({
|
|
110
|
-
method,
|
|
111
|
-
url: mode === 'create' ? path : itemPath,
|
|
112
|
-
handler: async (request, reply) => {
|
|
113
|
-
const entity = engine.entity(collection);
|
|
114
|
-
const options = parseRestOptions(request.query, false);
|
|
115
|
-
engine.validateRest(entity, options);
|
|
116
|
-
const ref = await engine.mutate(entity, mode, request.params[entity.primary], request.body);
|
|
117
|
-
// Re-infer schemaless response fields after successful writes.
|
|
118
|
-
if (!model.explicit) {
|
|
119
|
-
const refreshed = inferModel(ref.context.data);
|
|
120
|
-
ref.context = makeContext(ref.context.data, refreshed);
|
|
121
|
-
ref.entity = refreshed.byCollection.get(collection);
|
|
122
|
-
ref.node = ref.entity.root;
|
|
123
|
-
}
|
|
124
|
-
return reply.code(mode === 'create' ? 201 : 200).send(engine.project(ref, options.scope, options.nested));
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (graphqlEnabled)
|
|
130
|
-
fastify.register(mercurius, { schema: getGraphql(), path: normalizedConfig.graphql.endpoint ?? '/graphql', queryDepth: 32, context: async () => ({ snapshot: await engine.context() }) });
|
|
131
|
-
if (filesEnabled)
|
|
132
|
-
registerFileRoutes(fastify, { getStore: getFileStore, maxFileSize });
|
|
133
|
-
fastify.setErrorHandler((error, request, reply) => {
|
|
134
|
-
const candidate = isObject(error) ? error.statusCode : undefined;
|
|
55
|
+
server.listen = listen;
|
|
56
|
+
server.setErrorHandler((error, request, reply) => {
|
|
57
|
+
const candidate = error instanceof DomainError ? domainStatus[error.code] : isObject(error) ? error.statusCode : undefined;
|
|
135
58
|
const status = typeof candidate === 'number' && Number.isInteger(candidate) && candidate >= 400 && candidate <= 599 ? candidate : 500;
|
|
136
59
|
if (status === 500)
|
|
137
60
|
request.log.error(error);
|
|
138
61
|
return reply.code(status).send({ error: status === 500 ? 'Внутренняя ошибка сервера' : error instanceof Error ? error.message : String(error) });
|
|
139
62
|
});
|
|
140
|
-
|
|
141
|
-
|
|
63
|
+
if (cors) {
|
|
64
|
+
server.addHook('onRequest', async (_request, reply) => {
|
|
65
|
+
for (const [key, value] of Object.entries(corsHeaders))
|
|
66
|
+
reply.header(key, value);
|
|
67
|
+
});
|
|
68
|
+
server.options('/', async (_request, reply) => reply.code(204).send());
|
|
69
|
+
server.options('/*', async (_request, reply) => reply.code(204).send());
|
|
70
|
+
}
|
|
71
|
+
server.register(async (app) => {
|
|
72
|
+
const [{ createDatabaseStore }, { Engine }, { registerRestRoutes }] = await Promise.all([import('./database.js'), import('./engine.js'), import('./rest/routes.js')]);
|
|
73
|
+
const keys = explicitModel ? new Map(explicitModel.entities.map((e) => [e.collection, e.primary])) : undefined;
|
|
74
|
+
const store = await createDatabaseStore(normalized.database, keys);
|
|
75
|
+
const model = explicitModel ?? inferModel(store.database.data);
|
|
76
|
+
const engine = new Engine(store, model, pageSize, maxPageSize);
|
|
77
|
+
engine.validateData(store.database.data);
|
|
78
|
+
const graphqlPath = normalized.graphql.endpoint ?? '/graphql';
|
|
79
|
+
const openapiPath = normalized.openapi.endpoint ?? '/openapi.json';
|
|
80
|
+
validateEndpoints(model.entities.map((entity) => entity.collection), [...(enabled.graphql ? [graphqlPath] : []), ...(enabled.openapi ? [openapiPath] : [])]);
|
|
81
|
+
registerRestRoutes(app, engine);
|
|
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
|
+
}
|
|
86
|
+
if (enabled.openapi) {
|
|
87
|
+
const document = await openapi();
|
|
88
|
+
document.servers = [{ url: '/' }];
|
|
89
|
+
app.get(openapiPath, async () => document);
|
|
90
|
+
}
|
|
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
|
+
}
|
|
97
|
+
});
|
|
98
|
+
instance = server;
|
|
99
|
+
return server;
|
|
142
100
|
};
|
|
143
101
|
return {
|
|
144
102
|
fastify: getFastify,
|
|
145
|
-
openapi
|
|
146
|
-
assertApi(explicitModel, 'openapi');
|
|
147
|
-
const document = createOpenapi({
|
|
148
|
-
document: buildOpenapiDocument({ model: explicitModel, files: filesEnabled, pageSize, maxPageSize, info: normalizedConfig.openapi.info }),
|
|
149
|
-
host: normalizedConfig.server.host,
|
|
150
|
-
port: normalizedConfig.server.port,
|
|
151
|
-
});
|
|
152
|
-
if (normalizedConfig.openapi.path)
|
|
153
|
-
await writeOpenapi(document, normalizedConfig.openapi.path);
|
|
154
|
-
return document;
|
|
155
|
-
},
|
|
103
|
+
openapi,
|
|
156
104
|
graphql: async () => {
|
|
157
|
-
|
|
158
|
-
if (normalizedConfig.graphql.path) {
|
|
159
|
-
await mkdir(dirname(normalizedConfig.graphql.path), { recursive: true });
|
|
160
|
-
await writeFile(normalizedConfig.graphql.path, `${sdl}\n`, 'utf8');
|
|
161
|
-
}
|
|
162
|
-
return sdl;
|
|
105
|
+
return (await import('./graphql/public.js')).graphqlFromModel(explicitModel);
|
|
163
106
|
},
|
|
164
107
|
};
|
|
165
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;
|
package/dist/src/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC,CAAC;AAEvE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAa,EAAE,IAAiB,EAAE,IAAY,EAAQ,EAAE;IACtF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAEpE,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,IAAI,UAAU,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC,CAAC;AAEF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,EAAE;IACpC,IAAI,KAAK,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAC;IAEhD,OAAO,CAAI,SAA+B,EAAc,EAAE;QACxD,MAAM,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE/C,kDAAkD;QAClD,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAEhD,OAAO,gBAAgB,CAAC;IAC1B,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,wDAAwD;AACxD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAA+B,EAAU,EAAE;IACxE,IAAI,EAAU,CAAC;IAEf,GAAG,CAAC;QACF,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC5C,CAAC,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;IAErB,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACnJ,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAW,EAAW,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACzE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAc,EAAkC,EAAE,CAAC,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,CAAC;AAE3H,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAa,EAAE,KAAc,EAAW,EAAE;IAChE,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACpG,CAAC;IAED,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAErC,OAAO,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,YAAoB,EAAU,EAAE;IAClE,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,KAAK,EAAE,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,OAAO,CAAC,YAAY,CAAC,CAAC;AAC/B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAEhF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAa,EAAU,EAAE,CACpD,KAAK;KACF,KAAK,CAAC,eAAe,CAAC;KACtB,MAAM,CAAC,OAAO,CAAC;KACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;KACzD,IAAI,CAAC,EAAE,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kollors/deep-json-server",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.3",
|
|
4
4
|
"description": "JSON mock server with schema-driven REST, GraphQL, nested queries and OpenAPI generation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -12,6 +12,18 @@
|
|
|
12
12
|
".": {
|
|
13
13
|
"types": "./dist/index.d.ts",
|
|
14
14
|
"import": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./server": {
|
|
17
|
+
"types": "./dist/src/server/public.d.ts",
|
|
18
|
+
"import": "./dist/src/server/public.js"
|
|
19
|
+
},
|
|
20
|
+
"./openapi": {
|
|
21
|
+
"types": "./dist/src/openapi/entry.d.ts",
|
|
22
|
+
"import": "./dist/src/openapi/entry.js"
|
|
23
|
+
},
|
|
24
|
+
"./graphql": {
|
|
25
|
+
"types": "./dist/src/graphql/entry.d.ts",
|
|
26
|
+
"import": "./dist/src/graphql/entry.js"
|
|
15
27
|
}
|
|
16
28
|
},
|
|
17
29
|
"files": [
|