@kollors/deep-json-server 1.0.0-alpha.8 → 1.0.0-beta.1
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 +279 -217
- package/README.ru.md +282 -220
- package/dist/index.d.ts +1 -2
- package/dist/src/auth/contract.d.ts +3 -2
- package/dist/src/auth/contract.js.map +1 -1
- package/dist/src/auth/service.js +1 -1
- package/dist/src/auth/service.js.map +1 -1
- package/dist/src/auth/store.d.ts +1 -1
- package/dist/src/auth/store.js.map +1 -1
- package/dist/src/cli/index.d.ts +2 -2
- package/dist/src/cli/index.js +59 -80
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/core/constants.d.ts +1 -1
- package/dist/src/core/constants.js +1 -1
- package/dist/src/core/constants.js.map +1 -1
- package/dist/src/core/database.d.ts +6 -11
- package/dist/src/core/database.js +2 -2
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/core/engine.d.ts +3 -15
- package/dist/src/core/engine.js +10 -69
- package/dist/src/core/engine.js.map +1 -1
- package/dist/src/core/lifecycle/mutation.js +4 -4
- package/dist/src/core/lifecycle/mutation.js.map +1 -1
- package/dist/src/core/lifecycle/options.d.ts +15 -0
- package/dist/src/core/lifecycle/options.js +13 -0
- package/dist/src/core/lifecycle/options.js.map +1 -1
- package/dist/src/core/model.d.ts +17 -2
- package/dist/src/core/model.js +28 -7
- package/dist/src/core/model.js.map +1 -1
- package/dist/src/core/mutations/write.js +4 -0
- package/dist/src/core/mutations/write.js.map +1 -1
- package/dist/src/core/paths.d.ts +1 -1
- package/dist/src/core/paths.js +5 -5
- package/dist/src/core/paths.js.map +1 -1
- package/dist/src/core/query/execute.d.ts +25 -0
- package/dist/src/core/query/execute.js +82 -0
- package/dist/src/core/query/execute.js.map +1 -0
- package/dist/src/core/query/filter.js +1 -1
- package/dist/src/core/query/filter.js.map +1 -1
- package/dist/src/core/query/options.js +2 -2
- package/dist/src/core/query/options.js.map +1 -1
- package/dist/src/core/records.d.ts +2 -1
- package/dist/src/core/records.js +5 -2
- package/dist/src/core/records.js.map +1 -1
- package/dist/src/core/storage.d.ts +2 -0
- package/dist/src/core/storage.js +2 -0
- package/dist/src/core/storage.js.map +1 -0
- package/dist/src/files/contract.d.ts +6 -7
- package/dist/src/files/contract.js.map +1 -1
- package/dist/src/files/disk-metadata.d.ts +9 -0
- package/dist/src/files/disk-metadata.js +44 -0
- package/dist/src/files/disk-metadata.js.map +1 -0
- package/dist/src/files/disk-paths.d.ts +15 -0
- package/dist/src/files/disk-paths.js +100 -0
- package/dist/src/files/disk-paths.js.map +1 -0
- package/dist/src/files/disk-store.js +21 -165
- package/dist/src/files/disk-store.js.map +1 -1
- package/dist/src/files/index.d.ts +1 -1
- package/dist/src/files/index.js +5 -2
- package/dist/src/files/index.js.map +1 -1
- package/dist/src/files/memory-store.js +3 -3
- package/dist/src/files/memory-store.js.map +1 -1
- package/dist/src/graphql/generate.d.ts +3 -2
- package/dist/src/graphql/generate.js +3 -1
- package/dist/src/graphql/generate.js.map +1 -1
- package/dist/src/graphql/preflight.js +2 -0
- package/dist/src/graphql/preflight.js.map +1 -1
- package/dist/src/graphql/resolvers.js +7 -3
- package/dist/src/graphql/resolvers.js.map +1 -1
- package/dist/src/graphql/routes.js +4 -1
- package/dist/src/graphql/routes.js.map +1 -1
- package/dist/src/graphql/schema.js +5 -2
- package/dist/src/graphql/schema.js.map +1 -1
- package/dist/src/openapi/document.js +30 -19
- package/dist/src/openapi/document.js.map +1 -1
- package/dist/src/openapi/generate.js +3 -1
- package/dist/src/openapi/generate.js.map +1 -1
- package/dist/src/openapi/options.d.ts +0 -2
- package/dist/src/openapi/registry.d.ts +11 -0
- package/dist/src/openapi/registry.js +20 -0
- package/dist/src/openapi/registry.js.map +1 -0
- package/dist/src/rest/options.d.ts +11 -3
- package/dist/src/rest/options.js +15 -0
- package/dist/src/rest/options.js.map +1 -1
- package/dist/src/rest/projection.d.ts +15 -3
- package/dist/src/rest/projection.js +49 -15
- package/dist/src/rest/projection.js.map +1 -1
- package/dist/src/rest/routes.js +18 -7
- package/dist/src/rest/routes.js.map +1 -1
- package/dist/src/server/bootstrap.d.ts +7 -0
- package/dist/src/server/bootstrap.js +48 -0
- package/dist/src/server/bootstrap.js.map +1 -0
- package/dist/src/server/config.d.ts +28 -30
- package/dist/src/server/config.js +82 -169
- package/dist/src/server/config.js.map +1 -1
- package/dist/src/server/create.d.ts +3 -5
- package/dist/src/server/create.js +24 -89
- package/dist/src/server/create.js.map +1 -1
- package/dist/src/server/features.d.ts +0 -11
- package/dist/src/server/features.js +0 -20
- package/dist/src/server/features.js.map +1 -1
- package/dist/src/server/http.d.ts +12 -0
- package/dist/src/server/http.js +40 -0
- package/dist/src/server/http.js.map +1 -0
- package/dist/src/server/model.d.ts +6 -0
- package/dist/src/server/model.js +14 -0
- package/dist/src/server/model.js.map +1 -0
- package/dist/src/server/openapi-options.d.ts +6 -0
- package/dist/src/server/openapi-options.js +15 -0
- package/dist/src/server/openapi-options.js.map +1 -0
- package/dist/src/server/public.d.ts +1 -2
- package/package.json +3 -3
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { AUTH_PATHS } from '../auth/contract.js';
|
|
2
|
+
import { inputPaths } from '../core/paths.js';
|
|
3
|
+
import { configSourcePath } from './config.js';
|
|
4
|
+
import { validateEndpoints } from './features.js';
|
|
5
|
+
/** Подключает к HTTP-серверу хранилище записей и включённые прикладные модули.
|
|
6
|
+
* @example Конфигурация только с базой → REST-маршруты без auth, files и API-экспортов.
|
|
7
|
+
*/
|
|
8
|
+
export async function registerConfiguredModules(app, config, explicitModel, openapi) {
|
|
9
|
+
const enabled = { auth: config.auth !== undefined, files: config.files !== undefined };
|
|
10
|
+
const recordSettings = { auth: enabled.auth };
|
|
11
|
+
const keys = explicitModel ? new Map(explicitModel.entities.map((entity) => [entity.collection, entity.primary])) : undefined;
|
|
12
|
+
const [{ createDatabaseStore }, { Engine }, { inferModel }, { registerRestRoutes }] = await Promise.all([
|
|
13
|
+
import('../core/database.js'),
|
|
14
|
+
import('../core/engine.js'),
|
|
15
|
+
import('../core/model.js'),
|
|
16
|
+
import('../rest/routes.js'),
|
|
17
|
+
]);
|
|
18
|
+
const store = await createDatabaseStore(config.database, keys);
|
|
19
|
+
const model = explicitModel ?? inferModel(store.database.data, recordSettings);
|
|
20
|
+
const engine = new Engine(store, model, config.server.pageSize, config.server.maxPageSize);
|
|
21
|
+
engine.validateData(store.database.data);
|
|
22
|
+
const graphqlPath = config.graphql?.endpoint;
|
|
23
|
+
const openapiPath = config.openapi?.endpoint;
|
|
24
|
+
validateEndpoints(model.entities.map((entity) => entity.collection), [...(graphqlPath ? [graphqlPath] : []), ...(openapiPath ? [openapiPath] : []), ...(enabled.auth ? Object.values(AUTH_PATHS) : [])]);
|
|
25
|
+
const auth = enabled.auth && config.auth ? await (await import('../auth/service.js')).createAuthService(config.auth) : undefined;
|
|
26
|
+
if (auth) {
|
|
27
|
+
app.addHook('onClose', async () => auth.close());
|
|
28
|
+
const { registerAuthRoutes } = await import('../auth/routes.js');
|
|
29
|
+
registerAuthRoutes(app, auth);
|
|
30
|
+
}
|
|
31
|
+
const authenticate = auth ? (header) => auth.me(header) : undefined;
|
|
32
|
+
registerRestRoutes(app, engine, authenticate);
|
|
33
|
+
if (graphqlPath) {
|
|
34
|
+
const [{ registerGraphqlRoutes }, { buildGraphql }] = await Promise.all([import('../graphql/routes.js'), import('../graphql/schema.js')]);
|
|
35
|
+
registerGraphqlRoutes(app, buildGraphql(model), engine, graphqlPath, authenticate);
|
|
36
|
+
}
|
|
37
|
+
if (openapiPath) {
|
|
38
|
+
const document = await openapi();
|
|
39
|
+
document.servers = [{ url: '/' }];
|
|
40
|
+
app.get(openapiPath, async () => document);
|
|
41
|
+
}
|
|
42
|
+
if (enabled.files && config.files) {
|
|
43
|
+
const { createFileStore, registerFileRoutes } = await import('../files/index.js');
|
|
44
|
+
const protectedPaths = inputPaths({ database: config.database, auth: config.auth }, '.', configSourcePath(config));
|
|
45
|
+
registerFileRoutes(app, { getStore: () => createFileStore(config.files, protectedPaths), maxFileSize: config.server.maxFileSize });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/server/bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
+
import type { FastifyServerOptions } from 'fastify';
|
|
1
2
|
import type { AuthConfig } from '../auth/contract.js';
|
|
2
3
|
import type { DatabaseConfig } from '../core/database.js';
|
|
4
|
+
import type { ModelSchema } from '../core/model.js';
|
|
5
|
+
import type { Storage } from '../core/storage.js';
|
|
3
6
|
import type { FilesConfig } from '../files/contract.js';
|
|
4
7
|
import { type OpenapiInfo } from '../openapi/options.js';
|
|
5
8
|
export type { AuthConfig } from '../auth/contract.js';
|
|
6
|
-
import type { FastifyServerOptions } from 'fastify';
|
|
7
|
-
import type { ModelSchema } from '../core/model.js';
|
|
8
|
-
export type DatabaseSchema = ModelSchema;
|
|
9
9
|
export type { DatabaseConfig } from '../core/database.js';
|
|
10
|
+
export type { Storage } from '../core/storage.js';
|
|
10
11
|
export type { FilesConfig, MemoryFile } from '../files/contract.js';
|
|
12
|
+
export type DatabaseSchema = ModelSchema;
|
|
11
13
|
export interface OpenapiConfig {
|
|
12
|
-
enabled?: boolean;
|
|
13
14
|
endpoint?: string;
|
|
14
|
-
|
|
15
|
+
target?: string;
|
|
15
16
|
info?: OpenapiInfo;
|
|
16
17
|
}
|
|
17
18
|
export interface GraphqlConfig {
|
|
18
|
-
|
|
19
|
-
enabled?: boolean;
|
|
19
|
+
target?: string;
|
|
20
20
|
endpoint?: string;
|
|
21
21
|
}
|
|
22
22
|
export interface ServerConfig {
|
|
@@ -28,26 +28,34 @@ export interface ServerConfig {
|
|
|
28
28
|
pageSize?: number;
|
|
29
29
|
port?: number;
|
|
30
30
|
}
|
|
31
|
-
export
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
export type DeepJsonServerConfig = {
|
|
32
|
+
[S in Storage]: {
|
|
33
|
+
storage: S;
|
|
34
|
+
database: DatabaseConfig<S>;
|
|
35
|
+
files?: FilesConfig<S>;
|
|
36
|
+
auth?: AuthConfig<S>;
|
|
37
|
+
openapi?: OpenapiConfig;
|
|
38
|
+
graphql?: GraphqlConfig;
|
|
39
|
+
server?: ServerConfig;
|
|
40
|
+
};
|
|
41
|
+
}[Storage];
|
|
39
42
|
export interface NormalizedServerConfig {
|
|
43
|
+
storage: Storage;
|
|
40
44
|
database: DatabaseConfig;
|
|
41
45
|
files?: FilesConfig;
|
|
42
46
|
auth?: AuthConfig;
|
|
43
|
-
openapi
|
|
44
|
-
|
|
47
|
+
openapi?: OpenapiConfig & {
|
|
48
|
+
endpoint: string;
|
|
49
|
+
};
|
|
50
|
+
graphql?: GraphqlConfig & {
|
|
51
|
+
endpoint: string;
|
|
52
|
+
};
|
|
45
53
|
server: Required<ServerConfig>;
|
|
46
54
|
}
|
|
47
|
-
/**
|
|
48
|
-
* @example
|
|
55
|
+
/** Нормализует объект конфигурации без чтения содержимого файлов.
|
|
56
|
+
* @example Путь './db.json' с directory = '/tmp' → '/tmp/db.json'.
|
|
49
57
|
*/
|
|
50
|
-
export declare const normalizeServerConfig: (config: DeepJsonServerConfig,
|
|
58
|
+
export declare const normalizeServerConfig: (config: DeepJsonServerConfig, directory?: string) => NormalizedServerConfig;
|
|
51
59
|
/** Загружает default-экспорт ES-модуля, обходя кеш повторного импорта; выполняет код модуля.
|
|
52
60
|
* @example Файл /tmp/config.mjs с export default {} → { config: {}, directory: '/tmp', path: '/tmp/config.mjs' }.
|
|
53
61
|
*/
|
|
@@ -64,13 +72,3 @@ export declare const configSourcePath: (config: NormalizedServerConfig) => strin
|
|
|
64
72
|
* @example configure(config, '/tmp', '/tmp/config.mjs') → настройки; configSourcePath(result) → '/tmp/config.mjs'.
|
|
65
73
|
*/
|
|
66
74
|
export declare function configure(config: unknown, directory: string, sourcePath?: string): NormalizedServerConfig;
|
|
67
|
-
/** Выбирает настройки для указанных форматов экспорта и подставляет пустые данные вместо чтения базы.
|
|
68
|
-
* @example formats = ['graphql'] → настройки генерации GraphQL с database.data = {}.
|
|
69
|
-
*/
|
|
70
|
-
export declare function configureGeneration(source: Record<string, unknown>, formats: string[], directory: string, sourcePath: string, overrides: {
|
|
71
|
-
host?: string;
|
|
72
|
-
port?: number;
|
|
73
|
-
files?: boolean;
|
|
74
|
-
timestamps?: boolean;
|
|
75
|
-
softDelete?: boolean;
|
|
76
|
-
}): NormalizedServerConfig;
|
|
@@ -1,170 +1,109 @@
|
|
|
1
|
-
import { getBoolean, getObject, getPositiveInteger, getString, normalizeAddress } from '../core/config-values.js';
|
|
2
|
-
import { DEFAULT_MAX_FILE_SIZE } from '../core/constants.js';
|
|
3
|
-
import { recordOptions } from '../core/lifecycle/options.js';
|
|
4
|
-
import { errorMessage } from '../core/utils.js';
|
|
5
|
-
import { normalizeOpenapiInfo } from '../openapi/options.js';
|
|
6
1
|
import { dirname, resolve } from 'node:path';
|
|
7
2
|
import { pathToFileURL } from 'node:url';
|
|
3
|
+
import { getBoolean, getObject, getPositiveInteger, getString, normalizeAddress } from '../core/config-values.js';
|
|
4
|
+
import { DEFAULT_MAX_FILE_SIZE } from '../core/constants.js';
|
|
8
5
|
import { normalizePagination } from '../core/pagination.js';
|
|
9
|
-
import { assertKnownKeys, isObject } from '../core/utils.js';
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
const FILES_KEYS = new Set(['data', 'directory', 'metadata']);
|
|
13
|
-
const OPENAPI_KEYS = new Set(['path', 'info', 'enabled', 'endpoint']);
|
|
14
|
-
const GRAPHQL_KEYS = new Set(['path', 'enabled', 'endpoint']);
|
|
6
|
+
import { assertKnownKeys, errorMessage, isObject } from '../core/utils.js';
|
|
7
|
+
import { normalizeOpenapiInfo } from '../openapi/options.js';
|
|
8
|
+
const CONFIG_KEYS = new Set(['storage', 'database', 'files', 'auth', 'openapi', 'graphql', 'server']);
|
|
15
9
|
const SERVER_KEYS = new Set(['cors', 'host', 'logger', 'maxFileSize', 'maxPageSize', 'pageSize', 'port']);
|
|
16
10
|
let configImportIndex = 0;
|
|
17
|
-
/**
|
|
18
|
-
* @example
|
|
11
|
+
/** Проверяет секцию и её допустимые ключи; undefined означает отсутствие секции.
|
|
12
|
+
* @example section({}, 'auth', []) → {}; section(null, 'auth', []) → ошибка.
|
|
19
13
|
*/
|
|
20
|
-
|
|
14
|
+
function section(value, name, keys) {
|
|
15
|
+
if (value === undefined)
|
|
16
|
+
return undefined;
|
|
17
|
+
const object = getObject(value, `config.${name}`, true);
|
|
18
|
+
assertKnownKeys(object, new Set(keys), `config.${name}`);
|
|
19
|
+
return object;
|
|
20
|
+
}
|
|
21
|
+
/** Проверяет путь либо начальные данные в соответствии с общим режимом хранения.
|
|
22
|
+
* @example source('db.json', 'file', 'database.source', '/tmp') → '/tmp/db.json'.
|
|
23
|
+
*/
|
|
24
|
+
function source(value, storage, name, directory, array = false) {
|
|
25
|
+
if (storage === 'file')
|
|
26
|
+
return resolve(directory, getString(value, `config.${name}`, true));
|
|
27
|
+
if (array ? !Array.isArray(value) : !isObject(value))
|
|
28
|
+
throw new Error(`config.${name} must contain ${array ? 'an array' : 'an object'} for memory storage`);
|
|
21
29
|
try {
|
|
22
30
|
return structuredClone(value);
|
|
23
31
|
}
|
|
24
32
|
catch (error) {
|
|
25
|
-
throw new Error(
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
/** Делает заданный путь абсолютным относительно указанного каталога.
|
|
29
|
-
* @example resolveConfigPath('a.json', '/tmp') → '/tmp/a.json'; undefined → undefined.
|
|
30
|
-
*/
|
|
31
|
-
const resolveConfigPath = (value, directoryPath) => (value == null ? undefined : resolve(directoryPath, value));
|
|
32
|
-
/** Принимает объект описания или разрешает путь к нему относительно каталога.
|
|
33
|
-
* @example normalizeSchema('schema.json', '/tmp') → '/tmp/schema.json'.
|
|
34
|
-
*/
|
|
35
|
-
const normalizeSchema = (schema, directoryPath) => {
|
|
36
|
-
if (schema == null) {
|
|
37
|
-
return undefined;
|
|
38
|
-
}
|
|
39
|
-
if (typeof schema === 'string') {
|
|
40
|
-
return resolve(directoryPath, getString(schema, 'config.database.schema', true));
|
|
41
|
-
}
|
|
42
|
-
return getObject(schema, 'config.database.schema', true);
|
|
43
|
-
};
|
|
44
|
-
/** Проверяет выбор между файлом и данными в памяти, разрешает пути и копирует данные.
|
|
45
|
-
* @example { path: 'db.json' } с каталогом /tmp → path: '/tmp/db.json'; одновременно data и path → ошибка.
|
|
46
|
-
*/
|
|
47
|
-
const normalizeDatabase = (value, directoryPath) => {
|
|
48
|
-
const database = getObject(value, 'config.database', true);
|
|
49
|
-
assertKnownKeys(database, DATABASE_KEYS, 'config.database');
|
|
50
|
-
const hasData = database.data != null;
|
|
51
|
-
const hasPath = database.path != null;
|
|
52
|
-
if (hasData === hasPath) {
|
|
53
|
-
throw new Error('Укажите ровно один из ключей config.database.path и config.database.data');
|
|
54
|
-
}
|
|
55
|
-
const schema = normalizeSchema(database.schema, directoryPath);
|
|
56
|
-
recordOptions({ timestamps: database.timestamps, softDelete: database.softDelete });
|
|
57
|
-
const flags = {
|
|
58
|
-
...(database.timestamps !== undefined ? { timestamps: database.timestamps } : {}),
|
|
59
|
-
...(database.softDelete !== undefined ? { softDelete: database.softDelete } : {}),
|
|
60
|
-
};
|
|
61
|
-
if (hasData) {
|
|
62
|
-
return { data: copyInput(getObject(database.data, 'config.database.data', true)), schema, ...flags };
|
|
63
|
-
}
|
|
64
|
-
return { path: resolve(directoryPath, getString(database.path, 'config.database.path', true)), schema, ...flags };
|
|
65
|
-
};
|
|
66
|
-
/** Проверяет выбор между файлами в памяти и дисковым хранилищем, разрешает пути.
|
|
67
|
-
* @example normalizeFiles(undefined, '/tmp') → undefined; { data: [] } → { data: [] }.
|
|
68
|
-
*/
|
|
69
|
-
const normalizeFiles = (value, directoryPath) => {
|
|
70
|
-
const files = getObject(value, 'config.files');
|
|
71
|
-
if (files == null) {
|
|
72
|
-
return undefined;
|
|
73
|
-
}
|
|
74
|
-
assertKnownKeys(files, FILES_KEYS, 'config.files');
|
|
75
|
-
const hasData = files.data != null;
|
|
76
|
-
const hasDiskStorage = files.directory != null || files.metadata != null;
|
|
77
|
-
if (hasData === hasDiskStorage) {
|
|
78
|
-
throw new Error('Укажите либо config.files.data, либо пару config.files.directory и config.files.metadata');
|
|
33
|
+
throw new Error(`config.${name} must contain structured data`, { cause: error });
|
|
79
34
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
return { data: copyInput(files.data) };
|
|
85
|
-
}
|
|
86
|
-
return {
|
|
87
|
-
directory: resolve(directoryPath, getString(files.directory, 'config.files.directory', true)),
|
|
88
|
-
metadata: resolve(directoryPath, getString(files.metadata, 'config.files.metadata', true)),
|
|
89
|
-
};
|
|
90
|
-
};
|
|
91
|
-
/** Проверяет источник учётных записей и срок сессии; массив копирует, путь делает абсолютным.
|
|
92
|
-
* @example { users: 'users.json' } с каталогом /tmp → users: '/tmp/users.json'.
|
|
35
|
+
}
|
|
36
|
+
/** Проверяет секции настроек и возвращает независимые данные с абсолютными путями.
|
|
37
|
+
* @example { storage: 'file', database: { source: 'db.json' } } → абсолютный database.source.
|
|
93
38
|
*/
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
expiresIn,
|
|
39
|
+
function normalizeConfig(value, directory = '.') {
|
|
40
|
+
const config = getObject(value, 'config', true);
|
|
41
|
+
assertKnownKeys(config, CONFIG_KEYS, 'config');
|
|
42
|
+
if (config.storage !== 'file' && config.storage !== 'memory')
|
|
43
|
+
throw new Error("config.storage must be 'file' or 'memory'");
|
|
44
|
+
const storage = config.storage;
|
|
45
|
+
const database = section(config.database, 'database', ['source', 'schema']);
|
|
46
|
+
if (!database)
|
|
47
|
+
throw new Error('config.database is required');
|
|
48
|
+
const normalizedDatabase = {
|
|
49
|
+
source: source(database.source, storage, 'database.source', directory),
|
|
50
|
+
...(database.schema !== undefined ? { schema: source(database.schema, storage, 'database.schema', directory) } : {}),
|
|
107
51
|
};
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
52
|
+
const files = section(config.files, 'files', storage === 'file' ? ['source', 'metadata'] : ['source']);
|
|
53
|
+
const normalizedFiles = files === undefined
|
|
54
|
+
? undefined
|
|
55
|
+
: storage === 'file'
|
|
56
|
+
? {
|
|
57
|
+
source: source(files.source, storage, 'files.source', directory),
|
|
58
|
+
metadata: files.metadata === undefined
|
|
59
|
+
? resolve(directory, getString(files.source, 'config.files.source', true), '.files.json')
|
|
60
|
+
: resolve(directory, getString(files.metadata, 'config.files.metadata', true)),
|
|
61
|
+
}
|
|
62
|
+
: { source: source(files.source, storage, 'files.source', directory, true) };
|
|
63
|
+
const auth = section(config.auth, 'auth', ['source', 'expiresIn']);
|
|
64
|
+
let normalizedAuth;
|
|
65
|
+
if (auth) {
|
|
66
|
+
const expiresIn = getPositiveInteger(auth.expiresIn, 'config.auth.expiresIn');
|
|
67
|
+
if (expiresIn !== undefined && expiresIn > 2147483647)
|
|
68
|
+
throw new Error('config.auth.expiresIn must be at most 2147483647 seconds');
|
|
69
|
+
normalizedAuth = { source: source(auth.source, storage, 'auth.source', directory, true), expiresIn };
|
|
115
70
|
}
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const openapiEnabled = getBoolean(openapi.enabled, 'config.openapi.enabled') ?? false;
|
|
125
|
-
const openapiEndpoint = getString(openapi.endpoint, 'config.openapi.endpoint');
|
|
126
|
-
if (openapiEndpoint && !/^\/[A-Za-z][A-Za-z0-9_./-]*$/.test(openapiEndpoint))
|
|
71
|
+
const openapi = section(config.openapi, 'openapi', ['target', 'info', 'endpoint']);
|
|
72
|
+
const graphql = section(config.graphql, 'graphql', ['target', 'endpoint']);
|
|
73
|
+
if ((openapi || graphql) && normalizedDatabase.schema === undefined)
|
|
74
|
+
throw new Error('GraphQL and OpenAPI require an explicit model schema');
|
|
75
|
+
const exportPath = (value, name) => (value === undefined ? undefined : resolve(directory, getString(value, name, true)));
|
|
76
|
+
const openapiEndpoint = getString(openapi?.endpoint, 'config.openapi.endpoint') ?? '/openapi.json';
|
|
77
|
+
const graphqlEndpoint = getString(graphql?.endpoint, 'config.graphql.endpoint') ?? '/graphql';
|
|
78
|
+
if (!/^\/[A-Za-z][A-Za-z0-9_./-]*$/.test(openapiEndpoint))
|
|
127
79
|
throw new Error('Invalid OpenAPI endpoint');
|
|
128
|
-
|
|
129
|
-
const endpoint = getString(graphql.endpoint, 'config.graphql.endpoint');
|
|
130
|
-
if (endpoint && (!/^\/[A-Za-z][A-Za-z0-9_/-]*$/.test(endpoint) || endpoint === '/'))
|
|
80
|
+
if (!/^\/[A-Za-z][A-Za-z0-9_/-]*$/.test(graphqlEndpoint))
|
|
131
81
|
throw new Error('Invalid GraphQL endpoint');
|
|
132
|
-
const
|
|
82
|
+
const server = getObject(config.server, 'config.server') ?? {};
|
|
133
83
|
assertKnownKeys(server, SERVER_KEYS, 'config.server');
|
|
134
|
-
const openapiPath = getString(openapi.path, 'config.openapi.path');
|
|
135
|
-
const cors = getBoolean(server.cors ?? undefined, 'config.server.cors') ?? true;
|
|
136
|
-
const { host, port } = normalizeAddress(server);
|
|
137
84
|
const logger = server.logger;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (logger != null && typeof logger !== 'boolean' && !isObject(logger)) {
|
|
141
|
-
throw new Error('Ключ config.server.logger должен содержать boolean или JSON-объект');
|
|
142
|
-
}
|
|
85
|
+
if (logger != null && typeof logger !== 'boolean' && !isObject(logger))
|
|
86
|
+
throw new Error('config.server.logger must be boolean or an object');
|
|
143
87
|
return {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
path: resolveConfigPath(openapiPath, directoryPath),
|
|
151
|
-
...(info && { info }),
|
|
152
|
-
},
|
|
153
|
-
graphql: { path: resolveConfigPath(getString(graphql.path, 'config.graphql.path'), directoryPath), enabled: graphqlEnabled, endpoint: endpoint ?? '/graphql' },
|
|
88
|
+
storage,
|
|
89
|
+
database: normalizedDatabase,
|
|
90
|
+
files: normalizedFiles,
|
|
91
|
+
auth: normalizedAuth,
|
|
92
|
+
openapi: openapi ? { endpoint: openapiEndpoint, target: exportPath(openapi.target, 'config.openapi.target'), info: normalizeOpenapiInfo(openapi.info) } : undefined,
|
|
93
|
+
graphql: graphql ? { endpoint: graphqlEndpoint, target: exportPath(graphql.target, 'config.graphql.target') } : undefined,
|
|
154
94
|
server: {
|
|
155
|
-
|
|
156
|
-
|
|
95
|
+
...normalizeAddress(server),
|
|
96
|
+
...normalizePagination(server),
|
|
97
|
+
cors: getBoolean(server.cors, 'config.server.cors') ?? true,
|
|
157
98
|
logger: (logger ?? true),
|
|
158
|
-
maxFileSize: maxFileSize ?? DEFAULT_MAX_FILE_SIZE,
|
|
159
|
-
...pagination,
|
|
160
|
-
port,
|
|
99
|
+
maxFileSize: getPositiveInteger(server.maxFileSize, 'config.server.maxFileSize') ?? DEFAULT_MAX_FILE_SIZE,
|
|
161
100
|
},
|
|
162
101
|
};
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* @example
|
|
102
|
+
}
|
|
103
|
+
/** Нормализует объект конфигурации без чтения содержимого файлов.
|
|
104
|
+
* @example Путь './db.json' с directory = '/tmp' → '/tmp/db.json'.
|
|
166
105
|
*/
|
|
167
|
-
export const normalizeServerConfig = (config,
|
|
106
|
+
export const normalizeServerConfig = (config, directory) => normalizeConfig(config, directory);
|
|
168
107
|
/** Загружает default-экспорт ES-модуля, обходя кеш повторного импорта; выполняет код модуля.
|
|
169
108
|
* @example Файл /tmp/config.mjs с export default {} → { config: {}, directory: '/tmp', path: '/tmp/config.mjs' }.
|
|
170
109
|
*/
|
|
@@ -200,30 +139,4 @@ export function configure(config, directory, sourcePath) {
|
|
|
200
139
|
sourcePaths.set(normalized, sourcePath);
|
|
201
140
|
return normalized;
|
|
202
141
|
}
|
|
203
|
-
/** Выбирает настройки для указанных форматов экспорта и подставляет пустые данные вместо чтения базы.
|
|
204
|
-
* @example formats = ['graphql'] → настройки генерации GraphQL с database.data = {}.
|
|
205
|
-
*/
|
|
206
|
-
export function configureGeneration(source, formats, directory, sourcePath, overrides) {
|
|
207
|
-
assertKnownKeys(source, CONFIG_KEYS, 'config');
|
|
208
|
-
const database = getObject(source.database, 'config.database', true);
|
|
209
|
-
if (database.schema === undefined)
|
|
210
|
-
throw new Error('Generation requires an explicit model schema');
|
|
211
|
-
const openapi = formats.includes('openapi');
|
|
212
|
-
const server = openapi ? (getObject(source.server, 'config.server') ?? {}) : {};
|
|
213
|
-
return configure({
|
|
214
|
-
database: { data: {}, schema: database.schema, timestamps: overrides.timestamps ?? database.timestamps, softDelete: overrides.softDelete ?? database.softDelete },
|
|
215
|
-
auth: source.auth != null ? { users: [] } : undefined,
|
|
216
|
-
openapi: openapi ? source.openapi : undefined,
|
|
217
|
-
graphql: formats.includes('graphql') ? source.graphql : undefined,
|
|
218
|
-
files: openapi && (overrides.files || source.files != null) ? { data: [] } : undefined,
|
|
219
|
-
server: openapi
|
|
220
|
-
? {
|
|
221
|
-
host: overrides.host ?? server.host,
|
|
222
|
-
port: overrides.port ?? server.port,
|
|
223
|
-
pageSize: server.pageSize,
|
|
224
|
-
maxPageSize: server.maxPageSize,
|
|
225
|
-
}
|
|
226
|
-
: {},
|
|
227
|
-
}, directory, sourcePath);
|
|
228
|
-
}
|
|
229
142
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/server/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/server/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import type { FastifyInstance } from 'fastify';
|
|
2
2
|
import type { OpenapiDocument } from '../openapi/types.js';
|
|
3
3
|
import { type DeepJsonServerConfig, type NormalizedServerConfig } from './config.js';
|
|
4
|
-
import { type ServerFeatures } from './features.js';
|
|
5
4
|
export interface ServerFacade {
|
|
6
5
|
fastify(): FastifyInstance;
|
|
7
6
|
openapi(): Promise<OpenapiDocument>;
|
|
8
7
|
graphql(): Promise<string>;
|
|
9
8
|
}
|
|
10
|
-
export type { ServerFeatures } from './features.js';
|
|
11
9
|
/** Проверяет настройки и создаёт интерфейс запуска и генерации схем; сетевой порт ещё не открывает.
|
|
12
|
-
* @example await createServer({ database: {
|
|
10
|
+
* @example await createServer({ storage: 'memory', database: { source: { notes: [] } } }) → объект с fastify(), openapi(), graphql().
|
|
13
11
|
*/
|
|
14
|
-
export declare function createServer(
|
|
12
|
+
export declare function createServer(...args: [DeepJsonServerConfig]): Promise<ServerFacade>;
|
|
15
13
|
/** Собирает сервер из нормализованных настроек; хранилища открываются при инициализации HTTP-экземпляра.
|
|
16
14
|
* @example Нормализованные настройки → Promise<ServerFacade>; listen() затем открывает сетевой порт.
|
|
17
15
|
*/
|
|
18
|
-
export declare function createConfiguredServer(normalized: NormalizedServerConfig
|
|
16
|
+
export declare function createConfiguredServer(normalized: NormalizedServerConfig): Promise<ServerFacade>;
|