@kollors/deep-json-server 0.9.0 → 1.0.0-alpha.2
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 +313 -403
- package/README.ru.md +307 -397
- package/dist/index.d.ts +5 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/src/cli.js +95 -66
- package/dist/src/cli.js.map +1 -1
- package/dist/src/config.d.ts +18 -2
- package/dist/src/config.js +39 -10
- package/dist/src/config.js.map +1 -1
- package/dist/src/constants.d.ts +2 -1
- package/dist/src/constants.js +2 -1
- package/dist/src/constants.js.map +1 -1
- package/dist/src/database.d.ts +4 -3
- package/dist/src/database.js +32 -19
- package/dist/src/database.js.map +1 -1
- package/dist/src/engine.d.ts +47 -0
- package/dist/src/engine.js +371 -0
- package/dist/src/engine.js.map +1 -0
- 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/disk-store.js +17 -6
- package/dist/src/files/disk-store.js.map +1 -1
- package/dist/src/files/openapi.d.ts +3 -0
- package/dist/src/files/openapi.js +86 -0
- package/dist/src/files/openapi.js.map +1 -0
- package/dist/src/graphql/preflight.d.ts +3 -0
- package/dist/src/graphql/preflight.js +28 -0
- package/dist/src/graphql/preflight.js.map +1 -0
- package/dist/src/graphql/routes.d.ts +4 -0
- package/dist/src/graphql/routes.js +28 -0
- package/dist/src/graphql/routes.js.map +1 -0
- package/dist/src/graphql.d.ts +4 -0
- package/dist/src/graphql.js +227 -0
- package/dist/src/graphql.js.map +1 -0
- package/dist/src/model.d.ts +65 -0
- package/dist/src/model.js +345 -0
- package/dist/src/model.js.map +1 -0
- package/dist/src/openapi/document.d.ts +7 -7
- package/dist/src/openapi/document.js +237 -320
- package/dist/src/openapi/document.js.map +1 -1
- package/dist/src/openapi/index.d.ts +3 -6
- package/dist/src/openapi/index.js +2 -3
- package/dist/src/openapi/index.js.map +1 -1
- 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 -5
- package/dist/src/query/filter.js +76 -240
- package/dist/src/query/filter.js.map +1 -1
- package/dist/src/query/options.d.ts +18 -0
- package/dist/src/query/options.js +30 -0
- package/dist/src/query/options.js.map +1 -0
- 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 +37 -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 +17 -0
- package/dist/src/schema.js +23 -0
- package/dist/src/schema.js.map +1 -0
- package/dist/src/server.d.ts +3 -5
- package/dist/src/server.js +76 -162
- package/dist/src/server.js.map +1 -1
- package/dist/src/types.d.ts +1 -3
- package/dist/src/utils.d.ts +0 -1
- package/dist/src/utils.js +0 -1
- package/dist/src/utils.js.map +1 -1
- package/package.json +9 -4
- package/dist/src/openapi/config.d.ts +0 -11
- package/dist/src/openapi/config.js +0 -204
- package/dist/src/openapi/config.js.map +0 -1
- package/dist/src/openapi/inference.d.ts +0 -14
- package/dist/src/openapi/inference.js +0 -145
- package/dist/src/openapi/inference.js.map +0 -1
- package/dist/src/query/index.d.ts +0 -3
- package/dist/src/query/index.js +0 -4
- package/dist/src/query/index.js.map +0 -1
- package/dist/src/query/pagination.d.ts +0 -11
- package/dist/src/query/pagination.js +0 -28
- package/dist/src/query/pagination.js.map +0 -1
- package/dist/src/query/sort.d.ts +0 -1
- package/dist/src/query/sort.js +0 -54
- package/dist/src/query/sort.js.map +0 -1
- package/dist/src/relations.d.ts +0 -12
- package/dist/src/relations.js +0 -155
- package/dist/src/relations.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
export type { DatabaseConfig, DeepJsonServerConfig, FilesConfig, MemoryFile, OpenapiConfig, ServerConfig } from './src/config.js';
|
|
1
|
+
export type { DatabaseConfig, DeepJsonServerConfig, FilesConfig, GraphqlConfig, MemoryFile, OpenapiConfig, ServerConfig } from './src/config.js';
|
|
2
|
+
export type { ServerFeatures } from './src/features.js';
|
|
2
3
|
export type { FileMetadata, FileUpdate } from './src/files/contract.js';
|
|
4
|
+
export type { EntityDefinition, Field, ModelSchema } from './src/model.js';
|
|
5
|
+
export type { OpenapiOptions } from './src/schema.js';
|
|
6
|
+
export { generateGraphql, generateOpenapi, writeGraphql, writeOpenapi } from './src/schema.js';
|
|
3
7
|
export type { ServerFacade } from './src/server.js';
|
|
4
8
|
export { createServer } from './src/server.js';
|
|
5
9
|
export type { OpenapiDocument } from './src/types.js';
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/F,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/src/cli.js
CHANGED
|
@@ -1,80 +1,109 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
|
-
import { readServerConfig } from './config.js';
|
|
3
|
-
import { DEFAULT_HOST, DEFAULT_PORT } from './constants.js';
|
|
2
|
+
import { normalizeServerConfig, readServerConfig } from './config.js';
|
|
3
|
+
import { DEFAULT_HOST, DEFAULT_PORT, VERSION } from './constants.js';
|
|
4
|
+
import { resolveFeatures } from './features.js';
|
|
5
|
+
import { generateGraphql, generateOpenapi, writeGraphql, writeOpenapi } from './schema.js';
|
|
4
6
|
import { createServer } from './server.js';
|
|
5
7
|
const HELP_TEXT = `Deep JSON Server
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
deep-json-server [
|
|
9
|
+
Usage:
|
|
10
|
+
deep-json-server [options] <server.config.js>
|
|
11
|
+
deep-json-server generate <openapi|graphql|openapi,graphql> <server.config.js>
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
--
|
|
12
|
-
--openapi
|
|
13
|
-
--
|
|
14
|
-
--
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (argument === '--files') {
|
|
20
|
-
options.files = true;
|
|
21
|
-
}
|
|
22
|
-
else if (argument === '--openapi') {
|
|
23
|
-
if (options.openapiMode !== 'none') {
|
|
24
|
-
throw new Error('Параметры --openapi и --openapi-only нельзя использовать одновременно');
|
|
25
|
-
}
|
|
26
|
-
options.openapiMode = 'generate';
|
|
27
|
-
}
|
|
28
|
-
else if (argument === '--openapi-only') {
|
|
29
|
-
if (options.openapiMode !== 'none') {
|
|
30
|
-
throw new Error('Параметры --openapi и --openapi-only нельзя использовать одновременно');
|
|
31
|
-
}
|
|
32
|
-
options.openapiMode = 'only';
|
|
33
|
-
}
|
|
34
|
-
else if (argument.startsWith('-')) {
|
|
35
|
-
throw new Error(`Неизвестный параметр: ${argument}`);
|
|
36
|
-
}
|
|
37
|
-
else if (configPath == null) {
|
|
38
|
-
configPath = argument;
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
throw new Error('Можно указать только один файл конфигурации');
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
if (configPath == null) {
|
|
45
|
-
throw new Error('Укажите путь к файлу конфигурации');
|
|
46
|
-
}
|
|
47
|
-
return { configPath, ...options };
|
|
48
|
-
};
|
|
49
|
-
const validateModeConfig = (config, { files, openapiMode }) => {
|
|
50
|
-
if (openapiMode !== 'none' && config.openapi.path == null) {
|
|
51
|
-
throw new Error(`Для --openapi${openapiMode === 'only' ? '-only' : ''} укажите ключ config.openapi.path`);
|
|
52
|
-
}
|
|
53
|
-
if (files && config.files == null) {
|
|
54
|
-
throw new Error('Для --files укажите секцию config.files');
|
|
55
|
-
}
|
|
56
|
-
};
|
|
13
|
+
--files Enable file routes
|
|
14
|
+
--graphql Enable the GraphQL endpoint
|
|
15
|
+
--openapi Enable the OpenAPI endpoint
|
|
16
|
+
--host <host> Server address
|
|
17
|
+
--port <port> Server port
|
|
18
|
+
--help, -h Show help
|
|
19
|
+
--version, -v Show version
|
|
20
|
+
|
|
21
|
+
Files are enabled when configured. Generate writes schemas to the configured paths.`;
|
|
57
22
|
export async function runCli(args = process.argv.slice(2), services = { createServer }) {
|
|
58
|
-
if (args.includes('--help')) {
|
|
23
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
59
24
|
process.stdout.write(`${HELP_TEXT}\n`);
|
|
60
25
|
return;
|
|
61
26
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const port = config.server.port ?? Number(process.env.PORT ?? DEFAULT_PORT);
|
|
66
|
-
validateModeConfig(config, { files, openapiMode });
|
|
67
|
-
const runtimeConfig = { ...config, server: { ...config.server, host, port } };
|
|
68
|
-
const serverFacade = await services.createServer(runtimeConfig, { files });
|
|
69
|
-
if (openapiMode !== 'none') {
|
|
70
|
-
await serverFacade.openapi();
|
|
71
|
-
process.stdout.write(`OpenAPI-схема сохранена в ${config.openapi.path}\n`);
|
|
27
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
28
|
+
process.stdout.write(`${VERSION}\n`);
|
|
29
|
+
return;
|
|
72
30
|
}
|
|
73
|
-
|
|
31
|
+
const positional = [];
|
|
32
|
+
const seen = new Set();
|
|
33
|
+
const features = {};
|
|
34
|
+
let host;
|
|
35
|
+
let port;
|
|
36
|
+
for (let index = 0; index < args.length; index++) {
|
|
37
|
+
const arg = args[index];
|
|
38
|
+
if (!arg.startsWith('-')) {
|
|
39
|
+
positional.push(arg);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (!['--files', '--graphql', '--openapi', '--host', '--port'].includes(arg) || seen.has(arg))
|
|
43
|
+
throw new Error(`Неизвестный параметр или повтор: ${arg}`);
|
|
44
|
+
seen.add(arg);
|
|
45
|
+
if (arg === '--host' || arg === '--port') {
|
|
46
|
+
const value = args[++index];
|
|
47
|
+
if (!value || value.startsWith('-'))
|
|
48
|
+
throw new Error(`Укажите значение ${arg}`);
|
|
49
|
+
if (arg === '--host')
|
|
50
|
+
host = value;
|
|
51
|
+
else {
|
|
52
|
+
if (!/^\d+$/.test(value))
|
|
53
|
+
throw new Error('Invalid --port');
|
|
54
|
+
port = Number(value);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else
|
|
58
|
+
features[arg.slice(2)] = true;
|
|
59
|
+
}
|
|
60
|
+
const generate = positional[0] === 'generate';
|
|
61
|
+
const configPath = positional[generate ? 2 : 0];
|
|
62
|
+
if (!configPath)
|
|
63
|
+
throw new Error('Укажите путь к файлу конфигурации');
|
|
64
|
+
if (positional.length !== (generate ? 3 : 1))
|
|
65
|
+
throw new Error('Можно указать только один файл конфигурации');
|
|
66
|
+
const formats = generate ? positional[1].split(',') : [];
|
|
67
|
+
if (generate && (formats.some((format) => !['openapi', 'graphql'].includes(format)) || new Set(formats).size !== formats.length))
|
|
68
|
+
throw new Error('Invalid generation format');
|
|
69
|
+
if (generate && (features.graphql || features.openapi))
|
|
70
|
+
throw new Error('Endpoint flags are only available when starting the server');
|
|
71
|
+
const source = await readServerConfig(configPath);
|
|
72
|
+
const config = normalizeServerConfig({
|
|
73
|
+
...source,
|
|
74
|
+
server: { ...source.server, host: host ?? source.server.host ?? process.env.HOST ?? DEFAULT_HOST, port: port ?? source.server.port ?? Number(process.env.PORT ?? DEFAULT_PORT) },
|
|
75
|
+
});
|
|
76
|
+
const enabled = resolveFeatures(config, features);
|
|
77
|
+
if (generate) {
|
|
78
|
+
if (!config.database.schema)
|
|
79
|
+
throw new Error('Generation requires an explicit model schema');
|
|
80
|
+
// Validate all destinations before writing either document.
|
|
81
|
+
for (const format of formats)
|
|
82
|
+
if (!config[format].path)
|
|
83
|
+
throw new Error(`Укажите config.${format}.path`);
|
|
84
|
+
const openapi = formats.includes('openapi')
|
|
85
|
+
? await generateOpenapi(config.database.schema, {
|
|
86
|
+
files: enabled.files,
|
|
87
|
+
host: config.server.host,
|
|
88
|
+
port: config.server.port,
|
|
89
|
+
pageSize: config.server.pageSize ?? Math.min(10, config.server.maxPageSize ?? 100),
|
|
90
|
+
maxPageSize: config.server.maxPageSize,
|
|
91
|
+
info: config.openapi.info,
|
|
92
|
+
})
|
|
93
|
+
: undefined;
|
|
94
|
+
const graphql = formats.includes('graphql') ? await generateGraphql(config.database.schema) : undefined;
|
|
95
|
+
if (openapi) {
|
|
96
|
+
await writeOpenapi(openapi, config.openapi.path);
|
|
97
|
+
process.stdout.write(`OpenAPI: ${config.openapi.path}\n`);
|
|
98
|
+
}
|
|
99
|
+
if (graphql) {
|
|
100
|
+
await writeGraphql(graphql, config.graphql.path);
|
|
101
|
+
process.stdout.write(`GraphQL: ${config.graphql.path}\n`);
|
|
102
|
+
}
|
|
74
103
|
return;
|
|
75
104
|
}
|
|
76
|
-
const
|
|
77
|
-
await
|
|
78
|
-
|
|
105
|
+
const server = (await services.createServer(config, enabled)).fastify();
|
|
106
|
+
await server.listen();
|
|
107
|
+
server.log.info('Deep JSON Server started');
|
|
79
108
|
}
|
|
80
109
|
//# sourceMappingURL=cli.js.map
|
package/dist/src/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/src/config.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { FastifyServerOptions } from 'fastify';
|
|
2
|
-
import type {
|
|
3
|
-
|
|
2
|
+
import type { ModelSchema } from './model.js';
|
|
3
|
+
import type { DatabaseData } from './types.js';
|
|
4
|
+
export type DatabaseSchema = ModelSchema;
|
|
4
5
|
export type DatabaseConfig = {
|
|
5
6
|
data: DatabaseData;
|
|
6
7
|
path?: never;
|
|
@@ -26,7 +27,19 @@ export type FilesConfig = {
|
|
|
26
27
|
metadata: string;
|
|
27
28
|
};
|
|
28
29
|
export interface OpenapiConfig {
|
|
30
|
+
enabled?: boolean;
|
|
31
|
+
endpoint?: string;
|
|
29
32
|
path?: string;
|
|
33
|
+
info?: {
|
|
34
|
+
title: string;
|
|
35
|
+
version: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export interface GraphqlConfig {
|
|
40
|
+
path?: string;
|
|
41
|
+
enabled?: boolean;
|
|
42
|
+
endpoint?: string;
|
|
30
43
|
}
|
|
31
44
|
export interface ServerConfig {
|
|
32
45
|
cors?: boolean;
|
|
@@ -34,18 +47,21 @@ export interface ServerConfig {
|
|
|
34
47
|
logger?: FastifyServerOptions['logger'];
|
|
35
48
|
maxFileSize?: number;
|
|
36
49
|
maxPageSize?: number;
|
|
50
|
+
pageSize?: number;
|
|
37
51
|
port?: number;
|
|
38
52
|
}
|
|
39
53
|
export interface DeepJsonServerConfig {
|
|
40
54
|
database: DatabaseConfig;
|
|
41
55
|
files?: FilesConfig;
|
|
42
56
|
openapi?: OpenapiConfig;
|
|
57
|
+
graphql?: GraphqlConfig;
|
|
43
58
|
server?: ServerConfig;
|
|
44
59
|
}
|
|
45
60
|
export interface NormalizedServerConfig {
|
|
46
61
|
database: DatabaseConfig;
|
|
47
62
|
files?: FilesConfig;
|
|
48
63
|
openapi: OpenapiConfig;
|
|
64
|
+
graphql: GraphqlConfig;
|
|
49
65
|
server: ServerConfig;
|
|
50
66
|
}
|
|
51
67
|
/** Validates configuration and resolves relative paths. */
|
package/dist/src/config.js
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { dirname, resolve } from 'node:path';
|
|
2
2
|
import { pathToFileURL } from 'node:url';
|
|
3
3
|
import { assertKnownKeys, isObject } from './utils.js';
|
|
4
|
-
const CONFIG_KEYS = new Set(['database', 'files', 'openapi', 'server']);
|
|
4
|
+
const CONFIG_KEYS = new Set(['database', 'files', 'openapi', 'graphql', 'server']);
|
|
5
5
|
const DATABASE_KEYS = new Set(['data', 'path', 'schema']);
|
|
6
6
|
const FILES_KEYS = new Set(['data', 'directory', 'metadata']);
|
|
7
|
-
const OPENAPI_KEYS = new Set(['path']);
|
|
8
|
-
const
|
|
7
|
+
const OPENAPI_KEYS = new Set(['path', 'info', 'enabled', 'endpoint']);
|
|
8
|
+
const GRAPHQL_KEYS = new Set(['path', 'enabled', 'endpoint']);
|
|
9
|
+
const SERVER_KEYS = new Set(['cors', 'host', 'logger', 'maxFileSize', 'maxPageSize', 'pageSize', 'port']);
|
|
9
10
|
let configImportIndex = 0;
|
|
11
|
+
const copyInput = (value) => {
|
|
12
|
+
try {
|
|
13
|
+
return structuredClone(value);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
throw new Error('Input must contain JSON data or binary file content', { cause: error });
|
|
17
|
+
}
|
|
18
|
+
};
|
|
10
19
|
function getObject(value, path, required = false) {
|
|
11
20
|
if (value == null && !required) {
|
|
12
21
|
return undefined;
|
|
@@ -40,7 +49,7 @@ const normalizeSchema = (schema, directoryPath) => {
|
|
|
40
49
|
return undefined;
|
|
41
50
|
}
|
|
42
51
|
if (typeof schema === 'string') {
|
|
43
|
-
return
|
|
52
|
+
return resolve(directoryPath, getString(schema, 'config.database.schema', true));
|
|
44
53
|
}
|
|
45
54
|
return getObject(schema, 'config.database.schema', true);
|
|
46
55
|
};
|
|
@@ -54,9 +63,9 @@ const normalizeDatabase = (value, directoryPath) => {
|
|
|
54
63
|
}
|
|
55
64
|
const schema = normalizeSchema(database.schema, directoryPath);
|
|
56
65
|
if (hasData) {
|
|
57
|
-
return { data: getObject(database.data, 'config.database.data', true), schema };
|
|
66
|
+
return { data: copyInput(getObject(database.data, 'config.database.data', true)), schema };
|
|
58
67
|
}
|
|
59
|
-
return { path:
|
|
68
|
+
return { path: resolve(directoryPath, getString(database.path, 'config.database.path', true)), schema };
|
|
60
69
|
};
|
|
61
70
|
const normalizeFiles = (value, directoryPath) => {
|
|
62
71
|
const files = getObject(value, 'config.files');
|
|
@@ -73,11 +82,11 @@ const normalizeFiles = (value, directoryPath) => {
|
|
|
73
82
|
if (!Array.isArray(files.data)) {
|
|
74
83
|
throw new Error('Ключ config.files.data должен содержать массив');
|
|
75
84
|
}
|
|
76
|
-
return { data: files.data };
|
|
85
|
+
return { data: copyInput(files.data) };
|
|
77
86
|
}
|
|
78
87
|
return {
|
|
79
|
-
directory:
|
|
80
|
-
metadata:
|
|
88
|
+
directory: resolve(directoryPath, getString(files.directory, 'config.files.directory', true)),
|
|
89
|
+
metadata: resolve(directoryPath, getString(files.metadata, 'config.files.metadata', true)),
|
|
81
90
|
};
|
|
82
91
|
};
|
|
83
92
|
const normalizeConfig = (config, directoryPath = '.') => {
|
|
@@ -88,8 +97,23 @@ const normalizeConfig = (config, directoryPath = '.') => {
|
|
|
88
97
|
const database = normalizeDatabase(config.database, directoryPath);
|
|
89
98
|
const files = normalizeFiles(config.files, directoryPath);
|
|
90
99
|
const openapi = getObject(config.openapi, 'config.openapi') ?? {};
|
|
100
|
+
const graphql = getObject(config.graphql, 'config.graphql') ?? {};
|
|
91
101
|
const server = getObject(config.server, 'config.server') ?? {};
|
|
92
102
|
assertKnownKeys(openapi, OPENAPI_KEYS, 'config.openapi');
|
|
103
|
+
assertKnownKeys(graphql, GRAPHQL_KEYS, 'config.graphql');
|
|
104
|
+
if (openapi.enabled !== undefined && typeof openapi.enabled !== 'boolean')
|
|
105
|
+
throw new Error('config.openapi.enabled must be boolean');
|
|
106
|
+
const openapiEndpoint = getString(openapi.endpoint, 'config.openapi.endpoint');
|
|
107
|
+
if (openapiEndpoint && !/^\/[A-Za-z][A-Za-z0-9_./-]*$/.test(openapiEndpoint))
|
|
108
|
+
throw new Error('Invalid OpenAPI endpoint');
|
|
109
|
+
if (graphql.enabled !== undefined && typeof graphql.enabled !== 'boolean')
|
|
110
|
+
throw new Error('config.graphql.enabled must be boolean');
|
|
111
|
+
const endpoint = getString(graphql.endpoint, 'config.graphql.endpoint');
|
|
112
|
+
if (endpoint && (!/^\/[A-Za-z][A-Za-z0-9_/-]*$/.test(endpoint) || endpoint === '/'))
|
|
113
|
+
throw new Error('Invalid GraphQL endpoint');
|
|
114
|
+
const info = getObject(openapi.info, 'config.openapi.info');
|
|
115
|
+
if (info && (typeof info.title !== 'string' || typeof info.version !== 'string'))
|
|
116
|
+
throw new Error('OpenAPI info requires title and version');
|
|
93
117
|
assertKnownKeys(server, SERVER_KEYS, 'config.server');
|
|
94
118
|
const openapiPath = getString(openapi.path, 'config.openapi.path');
|
|
95
119
|
const cors = server.cors;
|
|
@@ -97,6 +121,9 @@ const normalizeConfig = (config, directoryPath = '.') => {
|
|
|
97
121
|
const logger = server.logger;
|
|
98
122
|
const maxFileSize = getPositiveInteger(server.maxFileSize, 'config.server.maxFileSize');
|
|
99
123
|
const maxPageSize = getPositiveInteger(server.maxPageSize, 'config.server.maxPageSize');
|
|
124
|
+
const pageSize = getPositiveInteger(server.pageSize, 'config.server.pageSize');
|
|
125
|
+
if (pageSize !== undefined && pageSize > (maxPageSize ?? 100))
|
|
126
|
+
throw new Error('pageSize exceeds maxPageSize');
|
|
100
127
|
const port = server.port;
|
|
101
128
|
if (port != null && (typeof port !== 'number' || !Number.isInteger(port) || port < 0 || port > 65_535)) {
|
|
102
129
|
throw new Error('Ключ config.server.port должен быть целым числом от 0 до 65535');
|
|
@@ -110,13 +137,15 @@ const normalizeConfig = (config, directoryPath = '.') => {
|
|
|
110
137
|
return {
|
|
111
138
|
database,
|
|
112
139
|
files,
|
|
113
|
-
openapi: { path: resolveConfigPath(openapiPath, directoryPath) },
|
|
140
|
+
openapi: { enabled: openapi.enabled, endpoint: openapiEndpoint, path: resolveConfigPath(openapiPath, directoryPath), ...(info && { info: info }) },
|
|
141
|
+
graphql: { path: resolveConfigPath(getString(graphql.path, 'config.graphql.path'), directoryPath), enabled: graphql.enabled, endpoint },
|
|
114
142
|
server: {
|
|
115
143
|
cors: cors,
|
|
116
144
|
host,
|
|
117
145
|
logger: logger,
|
|
118
146
|
maxFileSize,
|
|
119
147
|
maxPageSize,
|
|
148
|
+
pageSize,
|
|
120
149
|
port: port,
|
|
121
150
|
},
|
|
122
151
|
};
|
package/dist/src/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAIzC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEvD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;AACnF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC1D,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;AAC9D,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;AACtE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;AAC9D,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;AAC1G,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAC1B,MAAM,SAAS,GAAG,CAAI,KAAQ,EAAK,EAAE;IACnC,IAAI,CAAC;QACH,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,qDAAqD,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC,CAAC;AAgDF,SAAS,SAAS,CAAC,KAAc,EAAE,IAAY,EAAE,QAAQ,GAAG,KAAK;IAC/D,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC/B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,4BAA4B,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAID,SAAS,SAAS,CAAC,KAAc,EAAE,IAAY,EAAE,QAAQ,GAAG,KAAK;IAC/D,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC/B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,mCAAmC,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,iBAAiB,GAAG,CAAC,KAAyB,EAAE,aAAqB,EAAsB,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC;AAEhK,MAAM,kBAAkB,GAAG,CAAC,KAAc,EAAE,IAAY,EAAsB,EAAE;IAC9E,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,yCAAyC,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,MAAe,EAAE,aAAqB,EAAuC,EAAE;IACtG,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,MAAM,EAAE,wBAAwB,EAAE,IAAI,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,SAAS,CAAC,MAAM,EAAE,wBAAwB,EAAE,IAAI,CAAmB,CAAC;AAC7E,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,KAAc,EAAE,aAAqB,EAAkB,EAAE;IAClF,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,EAAE,iBAAiB,EAAE,IAAI,CAAC,CAAC;IAE3D,eAAe,CAAC,QAAQ,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAC;IAE5D,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC;IACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC;IAEtC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;IAC9F,CAAC;IAED,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAE/D,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,sBAAsB,EAAE,IAAI,CAAC,CAAiB,EAAE,MAAM,EAAE,CAAC;IAC7G,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,sBAAsB,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;AAC1G,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,KAAc,EAAE,aAAqB,EAA2B,EAAE;IACxF,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAE/C,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;IAEnD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC;IACnC,MAAM,cAAc,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC;IAEzE,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,0FAA0F,CAAC,CAAC;IAC9G,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,CAAiB,EAAE,CAAC;IACzD,CAAC;IAED,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE,wBAAwB,EAAE,IAAI,CAAC,CAAC;QAC7F,QAAQ,EAAE,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,uBAAuB,EAAE,IAAI,CAAC,CAAC;KAC3F,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,MAAe,EAAE,aAAa,GAAG,GAAG,EAA0B,EAAE;IACvF,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IAE/C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,gBAAgB,CAAC,IAAI,EAAE,CAAC;IAClE,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,gBAAgB,CAAC,IAAI,EAAE,CAAC;IAClE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,IAAI,EAAE,CAAC;IAE/D,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC;IACzD,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IACrI,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,yBAAyB,CAAC,CAAC;IAC/E,IAAI,eAAe,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,eAAe,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC1H,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IACrI,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,yBAAyB,CAAC,CAAC;IACxE,IAAI,QAAQ,IAAI,CAAC,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACjI,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;IAC5D,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7I,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;IAEtD,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,WAAW,EAAE,2BAA2B,CAAC,CAAC;IACxF,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,WAAW,EAAE,2BAA2B,CAAC,CAAC;IACxF,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,QAAQ,EAAE,wBAAwB,CAAC,CAAC;IAC/E,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC/G,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IAEzB,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC;QACvG,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IAED,IAAI,MAAM,IAAI,IAAI,IAAI,OAAO,MAAM,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;IAED,IAAI,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IAED,OAAO;QACL,QAAQ;QACR,KAAK;QACL,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAA8B,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,iBAAiB,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,IAAI,EAAE,IAA6B,EAAE,CAAC,EAAE;QAClM,OAAO,EAAE,EAAE,IAAI,EAAE,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,qBAAqB,CAAC,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAA8B,EAAE,QAAQ,EAAE;QAC9J,MAAM,EAAE;YACN,IAAI,EAAE,IAA2B;YACjC,IAAI;YACJ,MAAM,EAAE,MAAgC;YACxC,WAAW;YACX,WAAW;YACX,QAAQ;YACR,IAAI,EAAE,IAA0B;SACjC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,2DAA2D;AAC3D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAA4B,EAAE,aAAsB,EAA0B,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAE9J,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,UAAkB;IACvD,MAAM,kBAAkB,GAAG,OAAO,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;IAC1E,IAAI,MAAe,CAAC;IAEpB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAAC;QAEpD,mEAAmE;QACnE,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,yBAAyB,EAAE,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;QACnF,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEvE,MAAM,IAAI,KAAK,CAAC,qCAAqC,kBAAkB,KAAK,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3G,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;IACjG,CAAC;IAED,OAAO,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAC9D,CAAC"}
|
package/dist/src/constants.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const DEFAULT_HOST = "127.0.0.1";
|
|
2
2
|
export declare const DEFAULT_MAX_FILE_SIZE: number;
|
|
3
|
-
export declare const DEFAULT_MAX_PAGE_SIZE =
|
|
3
|
+
export declare const DEFAULT_MAX_PAGE_SIZE = 100;
|
|
4
4
|
export declare const DEFAULT_PAGE_SIZE = 10;
|
|
5
5
|
export declare const DEFAULT_PORT = 4001;
|
|
6
|
+
export declare const VERSION = "1.0.0-alpha.2";
|
package/dist/src/constants.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export const DEFAULT_HOST = '127.0.0.1';
|
|
2
2
|
export const DEFAULT_MAX_FILE_SIZE = 100 * 1024 * 1024;
|
|
3
|
-
export const DEFAULT_MAX_PAGE_SIZE =
|
|
3
|
+
export const DEFAULT_MAX_PAGE_SIZE = 100;
|
|
4
4
|
export const DEFAULT_PAGE_SIZE = 10;
|
|
5
5
|
export const DEFAULT_PORT = 4001;
|
|
6
|
+
export const VERSION = '1.0.0-alpha.2';
|
|
6
7
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AACxC,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AACvD,MAAM,CAAC,MAAM,qBAAqB,GAAG,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AACxC,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AACvD,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AACzC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC;AACjC,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC"}
|
package/dist/src/database.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { DatabaseConfig } from './config.js';
|
|
|
2
2
|
import type { DatabaseData, DatabaseRecord } from './types.js';
|
|
3
3
|
export interface DatabaseContainer {
|
|
4
4
|
data: DatabaseData;
|
|
5
|
+
counters?: Record<string, number>;
|
|
5
6
|
}
|
|
6
7
|
export interface DatabaseStore {
|
|
7
8
|
database: DatabaseContainer;
|
|
@@ -10,11 +11,11 @@ export interface DatabaseStore {
|
|
|
10
11
|
update<T>(operation: (database: DatabaseContainer) => T): Promise<T>;
|
|
11
12
|
}
|
|
12
13
|
export declare const validateJsonValue: (value: unknown, path: string, ancestors?: WeakSet<object>) => void;
|
|
13
|
-
export declare const validateDatabase: (data: unknown) => DatabaseData;
|
|
14
|
+
export declare const validateDatabase: (data: unknown, primaryKeys?: Map<string, string>) => DatabaseData;
|
|
14
15
|
export declare const readJsonObjectFile: (path: string, label: string) => Promise<Record<string, unknown>>;
|
|
15
|
-
export declare const readDatabaseFile: (databasePath: string) => Promise<DatabaseData>;
|
|
16
|
+
export declare const readDatabaseFile: (databasePath: string, keys?: Map<string, string>) => Promise<DatabaseData>;
|
|
16
17
|
/** Creates a disk- or memory-backed database with serialized updates. */
|
|
17
|
-
export declare const createDatabaseStore: (config: DatabaseConfig) => Promise<DatabaseStore>;
|
|
18
|
+
export declare const createDatabaseStore: (config: DatabaseConfig, keys?: Map<string, string>) => Promise<DatabaseStore>;
|
|
18
19
|
export declare const getCollection: (database: DatabaseContainer, resource: string) => DatabaseRecord[];
|
|
19
20
|
export declare const findItemIndex: (collection: DatabaseRecord[], id: unknown) => number;
|
|
20
21
|
export declare const createId: (collection: DatabaseRecord[]) => string;
|
package/dist/src/database.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { Low } from 'lowdb';
|
|
4
|
+
import { JSONFile } from 'lowdb/node';
|
|
4
5
|
import { createHttpError, createSerialQueue, createUniqueId, isObject, isSafeKey, isSystemError, resolveDatabasePath } from './utils.js';
|
|
5
6
|
const RESOURCE_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*$/;
|
|
6
7
|
export const validateJsonValue = (value, path, ancestors = new WeakSet()) => {
|
|
@@ -39,7 +40,7 @@ export const validateJsonValue = (value, path, ancestors = new WeakSet()) => {
|
|
|
39
40
|
}
|
|
40
41
|
ancestors.delete(value);
|
|
41
42
|
};
|
|
42
|
-
export const validateDatabase = (data) => {
|
|
43
|
+
export const validateDatabase = (data, primaryKeys) => {
|
|
43
44
|
if (!isObject(data)) {
|
|
44
45
|
throw new Error('База данных должна содержать JSON-объект');
|
|
45
46
|
}
|
|
@@ -51,18 +52,19 @@ export const validateDatabase = (data) => {
|
|
|
51
52
|
if (!Array.isArray(records)) {
|
|
52
53
|
throw new Error(`Ресурс «${resource}» должен содержать JSON-массив`);
|
|
53
54
|
}
|
|
55
|
+
const primary = primaryKeys?.get(resource) ?? 'id';
|
|
54
56
|
const ids = new Set();
|
|
55
57
|
records.forEach((record, index) => {
|
|
56
58
|
if (!isObject(record)) {
|
|
57
59
|
throw new Error(`Запись ${index} ресурса «${resource}» должна содержать JSON-объект`);
|
|
58
60
|
}
|
|
59
|
-
if (typeof record
|
|
61
|
+
if (typeof record[primary] !== 'string' && !(typeof record[primary] === 'number' && Number.isFinite(record[primary]))) {
|
|
60
62
|
throw new Error(`Запись ${index} ресурса «${resource}» должна содержать строковый или числовой id`);
|
|
61
63
|
}
|
|
62
|
-
if (String(record
|
|
64
|
+
if (String(record[primary]) === '') {
|
|
63
65
|
throw new Error(`Запись ${index} ресурса «${resource}» должна содержать непустой id`);
|
|
64
66
|
}
|
|
65
|
-
const id = String(record
|
|
67
|
+
const id = String(record[primary]);
|
|
66
68
|
if (ids.has(id)) {
|
|
67
69
|
throw new Error(`Ресурс «${resource}» содержит повторяющийся id «${id}»`);
|
|
68
70
|
}
|
|
@@ -89,41 +91,52 @@ export const readJsonObjectFile = async (path, label) => {
|
|
|
89
91
|
}
|
|
90
92
|
return value;
|
|
91
93
|
};
|
|
92
|
-
export const readDatabaseFile = async (databasePath) => validateDatabase(await readJsonObjectFile(databasePath, 'Файл базы данных'));
|
|
93
|
-
const createDiskDatabaseStore = async (databasePath) => {
|
|
94
|
+
export const readDatabaseFile = async (databasePath, keys) => validateDatabase(await readJsonObjectFile(databasePath, 'Файл базы данных'), keys);
|
|
95
|
+
const createDiskDatabaseStore = async (databasePath, keys) => {
|
|
94
96
|
const resolvedDatabasePath = resolveDatabasePath(databasePath);
|
|
95
|
-
const initialData = await readDatabaseFile(resolvedDatabasePath);
|
|
96
|
-
const database =
|
|
97
|
+
const initialData = await readDatabaseFile(resolvedDatabasePath, keys);
|
|
98
|
+
const database = new Low(new JSONFile(resolvedDatabasePath), initialData);
|
|
97
99
|
const schedule = createSerialQueue();
|
|
100
|
+
const counterStore = new Low(new JSONFile(`${resolvedDatabasePath}.counters.json`), {});
|
|
101
|
+
await counterStore.read();
|
|
98
102
|
const read = async () => {
|
|
99
|
-
database.data = await readDatabaseFile(resolvedDatabasePath);
|
|
103
|
+
database.data = await readDatabaseFile(resolvedDatabasePath, keys);
|
|
100
104
|
return database.data;
|
|
101
105
|
};
|
|
102
106
|
const update = (operation) => schedule(async () => {
|
|
103
107
|
await read();
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
await counterStore.read();
|
|
109
|
+
const draft = { data: structuredClone(database.data), counters: structuredClone(counterStore.data) };
|
|
110
|
+
const result = operation(draft);
|
|
111
|
+
validateDatabase(draft.data, keys);
|
|
112
|
+
// Reserve generated numbers first: failed data writes may leave gaps, never reused IDs.
|
|
113
|
+
if (JSON.stringify(draft.counters) !== JSON.stringify(counterStore.data)) {
|
|
114
|
+
counterStore.data = draft.counters;
|
|
115
|
+
await counterStore.write();
|
|
116
|
+
}
|
|
117
|
+
await database.adapter.write(draft.data);
|
|
118
|
+
database.data = draft.data;
|
|
107
119
|
return result;
|
|
108
120
|
});
|
|
109
121
|
return { database, path: resolvedDatabasePath, read, update };
|
|
110
122
|
};
|
|
111
|
-
const createMemoryDatabaseStore = (sourceData) => {
|
|
112
|
-
validateDatabase(sourceData);
|
|
113
|
-
const database = { data: structuredClone(sourceData) };
|
|
123
|
+
const createMemoryDatabaseStore = (sourceData, keys) => {
|
|
124
|
+
validateDatabase(sourceData, keys);
|
|
125
|
+
const database = { data: structuredClone(sourceData), counters: {} };
|
|
114
126
|
const schedule = createSerialQueue();
|
|
115
127
|
const read = async () => database.data;
|
|
116
128
|
const update = (operation) => schedule(() => {
|
|
117
|
-
const draft =
|
|
129
|
+
const draft = structuredClone(database);
|
|
118
130
|
const result = operation(draft);
|
|
119
|
-
validateDatabase(draft.data);
|
|
131
|
+
validateDatabase(draft.data, keys);
|
|
120
132
|
database.data = draft.data;
|
|
133
|
+
database.counters = draft.counters;
|
|
121
134
|
return result;
|
|
122
135
|
});
|
|
123
136
|
return { database, read, update };
|
|
124
137
|
};
|
|
125
138
|
/** Creates a disk- or memory-backed database with serialized updates. */
|
|
126
|
-
export const createDatabaseStore = async (config) =>
|
|
139
|
+
export const createDatabaseStore = async (config, keys) => config.data != null ? createMemoryDatabaseStore(config.data, keys) : createDiskDatabaseStore(config.path, keys);
|
|
127
140
|
export const getCollection = (database, resource) => {
|
|
128
141
|
const collection = isSafeKey(resource) ? database.data[resource] : undefined;
|
|
129
142
|
if (!Array.isArray(collection)) {
|
package/dist/src/database.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/database.ts"],"names":[],"mappings":"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"}
|