@kollors/deep-json-server 1.0.0-beta.5 → 1.0.0-rc.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/CHANGELOG.md +14 -0
- package/MIGRATION.md +41 -0
- package/README.md +36 -30
- package/README.ru.md +49 -43
- package/dist/index.d.ts +1 -1
- package/dist/src/cli/index.js +15 -10
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/core/config-values.js +4 -4
- package/dist/src/core/config-values.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.js +16 -16
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/core/project-package.d.ts +9 -0
- package/dist/src/core/project-package.js +27 -0
- package/dist/src/core/project-package.js.map +1 -0
- package/dist/src/core/utils.js +2 -2
- package/dist/src/core/utils.js.map +1 -1
- package/dist/src/files/contract.js +8 -8
- package/dist/src/files/contract.js.map +1 -1
- package/dist/src/files/disk-metadata.js +3 -3
- package/dist/src/files/disk-metadata.js.map +1 -1
- package/dist/src/files/disk-paths.js +6 -6
- package/dist/src/files/disk-paths.js.map +1 -1
- package/dist/src/files/disk-store.js +10 -10
- package/dist/src/files/disk-store.js.map +1 -1
- package/dist/src/files/memory-store.js +8 -8
- package/dist/src/files/memory-store.js.map +1 -1
- package/dist/src/files/routes.js +9 -9
- package/dist/src/files/routes.js.map +1 -1
- package/dist/src/files/streams.js +1 -1
- package/dist/src/files/streams.js.map +1 -1
- package/dist/src/openapi/entry.d.ts +1 -1
- package/dist/src/openapi/entry.js.map +1 -1
- package/dist/src/openapi/generate.d.ts +3 -3
- package/dist/src/openapi/generate.js +7 -5
- package/dist/src/openapi/generate.js.map +1 -1
- package/dist/src/openapi/options.d.ts +7 -1
- package/dist/src/openapi/options.js +6 -0
- package/dist/src/openapi/options.js.map +1 -1
- package/dist/src/server/bootstrap.js +1 -1
- package/dist/src/server/bootstrap.js.map +1 -1
- package/dist/src/server/config.d.ts +19 -5
- package/dist/src/server/config.js +11 -6
- package/dist/src/server/config.js.map +1 -1
- package/dist/src/server/create.d.ts +2 -1
- package/dist/src/server/create.js +8 -4
- package/dist/src/server/create.js.map +1 -1
- package/dist/src/server/http.js +1 -1
- package/dist/src/server/http.js.map +1 -1
- package/dist/src/server/input-paths.d.ts +1 -0
- package/dist/src/server/input-paths.js +9 -1
- package/dist/src/server/input-paths.js.map +1 -1
- package/dist/src/server/openapi-options.d.ts +2 -2
- package/dist/src/server/openapi-options.js +2 -2
- package/dist/src/server/openapi-options.js.map +1 -1
- package/dist/src/server/public.d.ts +1 -1
- package/examples/database.json +99 -0
- package/examples/schema.json +153 -0
- package/examples/server.config.js +8 -0
- package/package.json +5 -2
|
@@ -17,12 +17,12 @@ const getFileSize = async (path) => {
|
|
|
17
17
|
try {
|
|
18
18
|
const stats = await stat(path);
|
|
19
19
|
if (!stats.isFile())
|
|
20
|
-
throw domainError('INVALID_INPUT', '
|
|
20
|
+
throw domainError('INVALID_INPUT', 'Path must point to a regular file');
|
|
21
21
|
return stats.size;
|
|
22
22
|
}
|
|
23
23
|
catch (error) {
|
|
24
24
|
if (isSystemError(error) && error.code === 'ENOENT') {
|
|
25
|
-
throw domainError('NOT_FOUND', '
|
|
25
|
+
throw domainError('NOT_FOUND', 'File not found');
|
|
26
26
|
}
|
|
27
27
|
throw error;
|
|
28
28
|
}
|
|
@@ -74,7 +74,7 @@ export const createDiskFileStore = async ({ directory: sourceDirectoryPath, meta
|
|
|
74
74
|
const findFile = (path) => {
|
|
75
75
|
const file = files.get(path);
|
|
76
76
|
if (file == null) {
|
|
77
|
-
throw domainError('NOT_FOUND', '
|
|
77
|
+
throw domainError('NOT_FOUND', 'File not found');
|
|
78
78
|
}
|
|
79
79
|
return file;
|
|
80
80
|
};
|
|
@@ -90,7 +90,7 @@ export const createDiskFileStore = async ({ directory: sourceDirectoryPath, meta
|
|
|
90
90
|
try {
|
|
91
91
|
const stats = await handle.stat();
|
|
92
92
|
if (!stats.isFile())
|
|
93
|
-
throw domainError('INVALID_INPUT', '
|
|
93
|
+
throw domainError('INVALID_INPUT', 'Path must point to a regular file');
|
|
94
94
|
const size = stats.size;
|
|
95
95
|
return { file: { ...file, size }, stream: handle.createReadStream() };
|
|
96
96
|
}
|
|
@@ -103,7 +103,7 @@ export const createDiskFileStore = async ({ directory: sourceDirectoryPath, meta
|
|
|
103
103
|
const storedFile = { directory, mimeType, name };
|
|
104
104
|
const key = getFileKey(storedFile);
|
|
105
105
|
if (files.has(key) && !override) {
|
|
106
|
-
throw domainError('CONFLICT', '
|
|
106
|
+
throw domainError('CONFLICT', 'File already exists');
|
|
107
107
|
}
|
|
108
108
|
const stagedPath = resolve(stagingPath, `${randomBytes(12).toString('hex')}.upload`);
|
|
109
109
|
let size = 0;
|
|
@@ -117,7 +117,7 @@ export const createDiskFileStore = async ({ directory: sourceDirectoryPath, meta
|
|
|
117
117
|
const existsOnDisk = await paths.pathExists(path);
|
|
118
118
|
const exists = files.has(key) || existsOnDisk;
|
|
119
119
|
if (exists && !override) {
|
|
120
|
-
throw domainError('CONFLICT', '
|
|
120
|
+
throw domainError('CONFLICT', 'File already exists');
|
|
121
121
|
}
|
|
122
122
|
const backupPath = `${path}.${randomBytes(6).toString('hex')}.backup`;
|
|
123
123
|
let backedUp = false;
|
|
@@ -146,7 +146,7 @@ export const createDiskFileStore = async ({ directory: sourceDirectoryPath, meta
|
|
|
146
146
|
await rename(backupPath, path).catch((rollbackError) => rollbackErrors.push(rollbackError));
|
|
147
147
|
}
|
|
148
148
|
if (rollbackErrors.length > 0) {
|
|
149
|
-
throw new AggregateError([error, ...rollbackErrors], '
|
|
149
|
+
throw new AggregateError([error, ...rollbackErrors], 'Could not save the file or fully roll back the operation');
|
|
150
150
|
}
|
|
151
151
|
throw error;
|
|
152
152
|
}
|
|
@@ -172,13 +172,13 @@ export const createDiskFileStore = async ({ directory: sourceDirectoryPath, meta
|
|
|
172
172
|
}
|
|
173
173
|
const targetFilePath = await paths.prepareTargetPath(targetPath);
|
|
174
174
|
if (files.has(targetPath) || (await paths.pathExists(targetFilePath))) {
|
|
175
|
-
throw domainError('CONFLICT', '
|
|
175
|
+
throw domainError('CONFLICT', 'A file already exists at this path');
|
|
176
176
|
}
|
|
177
177
|
await rename(sourceFilePath, targetFilePath);
|
|
178
178
|
const nextFiles = new Map(files);
|
|
179
179
|
nextFiles.delete(sourcePath);
|
|
180
180
|
nextFiles.set(targetPath, updatedFile);
|
|
181
|
-
await commitMetadata(nextFiles, () => rename(targetFilePath, sourceFilePath), '
|
|
181
|
+
await commitMetadata(nextFiles, () => rename(targetFilePath, sourceFilePath), 'Could not update the file or roll back the move');
|
|
182
182
|
return { ...updatedFile, size: await getFileSize(targetFilePath) };
|
|
183
183
|
});
|
|
184
184
|
const remove = (path) => schedule(async () => {
|
|
@@ -189,7 +189,7 @@ export const createDiskFileStore = async ({ directory: sourceDirectoryPath, meta
|
|
|
189
189
|
await rename(filePath, temporaryPath);
|
|
190
190
|
const nextFiles = new Map(files);
|
|
191
191
|
nextFiles.delete(path);
|
|
192
|
-
await commitMetadata(nextFiles, () => rename(temporaryPath, filePath), '
|
|
192
|
+
await commitMetadata(nextFiles, () => rename(temporaryPath, filePath), 'Could not delete the file or roll back the operation');
|
|
193
193
|
await cleanupLater(temporaryPath);
|
|
194
194
|
});
|
|
195
195
|
return { get, metadata, remove, update, upload };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"disk-store.js","sourceRoot":"","sources":["../../../src/files/disk-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAqE,UAAU,EAA2B,MAAM,eAAe,CAAC;AACvI,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,GAAG,KAAK,EAAE,IAAY,EAAmB,EAAE;IAC1D,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAE/B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAAE,MAAM,WAAW,CAAC,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"disk-store.js","sourceRoot":"","sources":["../../../src/files/disk-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,15 +25,15 @@ export const createMemoryFileStore = (sourceFiles) => {
|
|
|
25
25
|
const storedFiles = new Map();
|
|
26
26
|
sourceFiles.forEach((sourceFile, index) => {
|
|
27
27
|
if (!(sourceFile.content instanceof Uint8Array)) {
|
|
28
|
-
throw new Error(
|
|
28
|
+
throw new Error(`Invalid record ${index} in config.files.source`);
|
|
29
29
|
}
|
|
30
30
|
const file = {
|
|
31
|
-
...normalizeStoredFileMetadata(sourceFile,
|
|
31
|
+
...normalizeStoredFileMetadata(sourceFile, `Record ${index} in config.files.source`),
|
|
32
32
|
size: sourceFile.content.length,
|
|
33
33
|
};
|
|
34
34
|
const path = getFileKey(file);
|
|
35
35
|
if (storedFiles.has(path)) {
|
|
36
|
-
throw new Error(`config.files.source
|
|
36
|
+
throw new Error(`config.files.source contains duplicate path "${path}"`);
|
|
37
37
|
}
|
|
38
38
|
storedFiles.set(path, { content: Buffer.from(sourceFile.content), file });
|
|
39
39
|
});
|
|
@@ -41,7 +41,7 @@ export const createMemoryFileStore = (sourceFiles) => {
|
|
|
41
41
|
const findStoredFile = (path) => {
|
|
42
42
|
const storedFile = storedFiles.get(path);
|
|
43
43
|
if (storedFile == null) {
|
|
44
|
-
throw domainError('NOT_FOUND', '
|
|
44
|
+
throw domainError('NOT_FOUND', 'File not found');
|
|
45
45
|
}
|
|
46
46
|
return storedFile;
|
|
47
47
|
};
|
|
@@ -53,13 +53,13 @@ export const createMemoryFileStore = (sourceFiles) => {
|
|
|
53
53
|
const upload = async ({ directory, maxFileSize, mimeType, name, override, stream }) => {
|
|
54
54
|
const path = getFileKey({ directory, name });
|
|
55
55
|
if (storedFiles.has(path) && !override) {
|
|
56
|
-
throw domainError('CONFLICT', '
|
|
56
|
+
throw domainError('CONFLICT', 'File already exists');
|
|
57
57
|
}
|
|
58
58
|
const content = await readUpload(stream, maxFileSize);
|
|
59
59
|
return schedule(() => {
|
|
60
60
|
const exists = storedFiles.has(path);
|
|
61
61
|
if (exists && !override) {
|
|
62
|
-
throw domainError('CONFLICT', '
|
|
62
|
+
throw domainError('CONFLICT', 'File already exists');
|
|
63
63
|
}
|
|
64
64
|
const file = { directory, mimeType, name, size: content.length };
|
|
65
65
|
storedFiles.set(path, { content, file });
|
|
@@ -71,7 +71,7 @@ export const createMemoryFileStore = (sourceFiles) => {
|
|
|
71
71
|
const file = { ...storedFile.file, ...updates };
|
|
72
72
|
const targetPath = getFileKey(file);
|
|
73
73
|
if (sourcePath !== targetPath && storedFiles.has(targetPath)) {
|
|
74
|
-
throw domainError('CONFLICT', '
|
|
74
|
+
throw domainError('CONFLICT', 'A file already exists at this path');
|
|
75
75
|
}
|
|
76
76
|
storedFiles.delete(sourcePath);
|
|
77
77
|
storedFiles.set(targetPath, { ...storedFile, file });
|
|
@@ -79,7 +79,7 @@ export const createMemoryFileStore = (sourceFiles) => {
|
|
|
79
79
|
});
|
|
80
80
|
const remove = (path) => schedule(() => {
|
|
81
81
|
if (!storedFiles.delete(path)) {
|
|
82
|
-
throw domainError('NOT_FOUND', '
|
|
82
|
+
throw domainError('NOT_FOUND', 'File not found');
|
|
83
83
|
}
|
|
84
84
|
});
|
|
85
85
|
return { get, metadata, remove, update, upload };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../../src/files/memory-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAqE,UAAU,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC;AAC3I,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD;;GAEG;AACH,MAAM,UAAU,GAAG,KAAK,EAAE,MAAgB,EAAE,WAAmB,EAAmB,EAAE;IAClF,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,MAAM,QAAQ,CACZ,MAAM,EACN,iBAAiB,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;QACvC,IAAI,GAAG,KAAK,CAAC;IACf,CAAC,CAAC,EACF,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACpE,CAAC,CACF,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,WAAyB,EAAa,EAAE;IAC5E,MAAM,WAAW,GAAG,IAAI,GAAG,EAAiD,CAAC;IAE7E,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE;QACxC,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,YAAY,UAAU,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../../src/files/memory-store.ts"],"names":[],"mappings":"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"}
|
package/dist/src/files/routes.js
CHANGED
|
@@ -6,23 +6,23 @@ import { createFileMetadata, FILE_HEADERS, FILE_ROUTES, FILE_UPDATE_SCHEMA, getD
|
|
|
6
6
|
*/
|
|
7
7
|
const decodeHeader = (value, name) => {
|
|
8
8
|
if (typeof value !== 'string') {
|
|
9
|
-
throw createHttpError(400,
|
|
9
|
+
throw createHttpError(400, `Header ${name} is required`);
|
|
10
10
|
}
|
|
11
11
|
try {
|
|
12
12
|
return decodeURIComponent(value);
|
|
13
13
|
}
|
|
14
14
|
catch {
|
|
15
|
-
throw createHttpError(400,
|
|
15
|
+
throw createHttpError(400, `Header ${name} has an invalid value`);
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
18
|
/** Декодирует и проверяет имя файла из заголовка.
|
|
19
19
|
* @example getContentName('a%20b.txt') → 'a b.txt'.
|
|
20
20
|
*/
|
|
21
|
-
const getContentName = (value) => validateName(decodeHeader(value, FILE_HEADERS.name.name),
|
|
21
|
+
const getContentName = (value) => validateName(decodeHeader(value, FILE_HEADERS.name.name), `Header ${FILE_HEADERS.name.name}`);
|
|
22
22
|
/** Декодирует относительный каталог; отсутствующее значение заменяет пустой строкой.
|
|
23
23
|
* @example getContentDirectory(undefined) → ''; getContentDirectory('my%20photos') → 'my photos'.
|
|
24
24
|
*/
|
|
25
|
-
const getContentDirectory = (value) => (value == null ? '' : validateDirectory(decodeHeader(value, FILE_HEADERS.directory.name),
|
|
25
|
+
const getContentDirectory = (value) => (value == null ? '' : validateDirectory(decodeHeader(value, FILE_HEADERS.directory.name), `Header ${FILE_HEADERS.directory.name}`));
|
|
26
26
|
/** Читает строковый логический флаг перезаписи; отсутствие означает false.
|
|
27
27
|
* @example getContentOverride('true') → true; getContentOverride(undefined) → false; 'yes' → ошибка.
|
|
28
28
|
*/
|
|
@@ -33,7 +33,7 @@ const getContentOverride = (value) => {
|
|
|
33
33
|
if (value === 'true') {
|
|
34
34
|
return true;
|
|
35
35
|
}
|
|
36
|
-
throw createHttpError(400,
|
|
36
|
+
throw createHttpError(400, `Header ${FILE_HEADERS.override.name} must be true or false`);
|
|
37
37
|
};
|
|
38
38
|
/** Извлекает и проверяет путь из параметра маршрута.
|
|
39
39
|
* @example При request.params = { '*': 'photos/a.jpg' } → 'photos/a.jpg'.
|
|
@@ -43,8 +43,8 @@ const getRequestPath = (request) => getFileKey(getPathLocation(request.params['*
|
|
|
43
43
|
* @example normalizeUpdate({ name: 'a.txt' }) → { name: 'a.txt' }.
|
|
44
44
|
*/
|
|
45
45
|
const normalizeUpdate = (body) => ({
|
|
46
|
-
...(body.directory != null && { directory: validateDirectory(body.directory, '
|
|
47
|
-
...(body.name != null && { name: validateName(body.name, '
|
|
46
|
+
...(body.directory != null && { directory: validateDirectory(body.directory, 'body.directory') }),
|
|
47
|
+
...(body.name != null && { name: validateName(body.name, 'body.name') }),
|
|
48
48
|
});
|
|
49
49
|
/** Читает поток из хранилища и отправляет его с MIME-типом и заголовком скачивания или просмотра.
|
|
50
50
|
* @example При disposition = 'inline' ответ содержит Content-Disposition: inline и байты файла.
|
|
@@ -67,7 +67,7 @@ export const registerFileRoutes = (fastify, { getStore, maxFileSize }) => {
|
|
|
67
67
|
uploadServer.post(FILE_ROUTES.storage, async (request, reply) => {
|
|
68
68
|
const contentLength = Number(request.headers['content-length']);
|
|
69
69
|
if (Number.isFinite(contentLength) && contentLength > maxFileSize) {
|
|
70
|
-
throw createHttpError(413,
|
|
70
|
+
throw createHttpError(413, `File size must not exceed ${maxFileSize} bytes`);
|
|
71
71
|
}
|
|
72
72
|
const result = await store.upload({
|
|
73
73
|
directory: getContentDirectory(request.headers[FILE_HEADERS.directory.key]),
|
|
@@ -88,7 +88,7 @@ export const registerFileRoutes = (fastify, { getStore, maxFileSize }) => {
|
|
|
88
88
|
bodyLimit: PATCH_BODY_LIMIT,
|
|
89
89
|
preValidation: async (request) => {
|
|
90
90
|
if (normalizeMimeType(request.headers['content-type']) !== 'application/json') {
|
|
91
|
-
throw createHttpError(415, '
|
|
91
|
+
throw createHttpError(415, 'Use Content-Type: application/json to update a file');
|
|
92
92
|
}
|
|
93
93
|
},
|
|
94
94
|
schema: { body: FILE_UPDATE_SCHEMA },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/files/routes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAmC,UAAU,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACjJ,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAMjI;;GAEG;AACH,MAAM,YAAY,GAAG,CAAC,KAAc,EAAE,IAAY,EAAU,EAAE;IAC5D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,eAAe,CAAC,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/files/routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ export const createSizeLimiter = (maxFileSize, onSize) => {
|
|
|
9
9
|
transform(chunk, _encoding, callback) {
|
|
10
10
|
size += chunk.length;
|
|
11
11
|
if (size > maxFileSize) {
|
|
12
|
-
callback(domainError('PAYLOAD_TOO_LARGE',
|
|
12
|
+
callback(domainError('PAYLOAD_TOO_LARGE', `File size must not exceed ${maxFileSize} bytes`));
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
15
|
onSize(size);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streams.js","sourceRoot":"","sources":["../../../src/files/streams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA0B,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAE,MAA8B,EAAa,EAAE;IAClG,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,OAAO,IAAI,SAAS,CAAC;QACnB,SAAS,CAAC,KAAa,EAAE,SAAyB,EAAE,QAA2B;YAC7E,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC;YAErB,IAAI,IAAI,GAAG,WAAW,EAAE,CAAC;gBACvB,QAAQ,CAAC,WAAW,CAAC,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"streams.js","sourceRoot":"","sources":["../../../src/files/streams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA0B,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAE,MAA8B,EAAa,EAAE;IAClG,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,OAAO,IAAI,SAAS,CAAC;QACnB,SAAS,CAAC,KAAa,EAAE,SAAyB,EAAE,QAA2B;YAC7E,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC;YAErB,IAAI,IAAI,GAAG,WAAW,EAAE,CAAC;gBACvB,QAAQ,CAAC,WAAW,CAAC,mBAAmB,EAAE,6BAA6B,WAAW,QAAQ,CAAC,CAAC,CAAC;gBAC7F,OAAO;YACT,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,CAAC;YACb,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -5,7 +5,7 @@ import type { OpenapiDocument } from './types.js';
|
|
|
5
5
|
/** Загружает генератор при первом обращении и передаёт ему описание и параметры.
|
|
6
6
|
* @example await generateOpenapi({ models: { Note: { collection: 'notes', fields: { id: { type: 'string', primary: true } } } } }) → документ с маршрутом /notes.
|
|
7
7
|
*/
|
|
8
|
-
export declare function generateOpenapi(schema: ModelSchema | string, options
|
|
8
|
+
export declare function generateOpenapi(schema: ModelSchema | string, options: OpenapiOptions): Promise<OpenapiDocument>;
|
|
9
9
|
/** Загружает модуль записи по требованию и сохраняет схему в указанный файл.
|
|
10
10
|
* @example await writeOpenapi(document, './openapi.json') → undefined; файл содержит JSON документа.
|
|
11
11
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../src/openapi/entry.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAA4B,EAAE,
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../src/openapi/entry.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAA4B,EAAE,OAAuB;IACzF,OAAO,CAAC,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC1E,CAAC;AACD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAyB,EAAE,IAAY;IACxE,OAAO,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { type Model, type ModelSchema } from '../core/model.js';
|
|
2
|
-
import { type OpenapiOptions } from './options.js';
|
|
2
|
+
import { type OpenapiDocumentOptions, type OpenapiOptions } from './options.js';
|
|
3
3
|
import type { OpenapiDocument } from './types.js';
|
|
4
4
|
/** Проверяет параметры экспорта и строит документ из подготовленной модели.
|
|
5
5
|
* @example Модель с коллекцией notes → документ с paths['/notes'].
|
|
6
6
|
*/
|
|
7
|
-
export declare function openapiFromModel(model: Model | undefined, options
|
|
7
|
+
export declare function openapiFromModel(model: Model | undefined, options: OpenapiDocumentOptions): OpenapiDocument;
|
|
8
8
|
/** Загружает описание из объекта или файла и возвращает документ спецификации.
|
|
9
9
|
* @example Корректное описание → Promise<OpenapiDocument> с openapi: '3.0.3'.
|
|
10
10
|
*/
|
|
11
|
-
export declare function generateOpenapi(schema: ModelSchema | string, options
|
|
11
|
+
export declare function generateOpenapi(schema: ModelSchema | string, options: OpenapiOptions): Promise<OpenapiDocument>;
|
|
12
12
|
/** Копирует документ и задаёт адрес сервера, не меняя исходный объект.
|
|
13
13
|
* @example При host = 'localhost', port = 80 поле servers → [{ url: 'http://localhost:80' }].
|
|
14
14
|
*/
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { getBoolean, normalizeAddress } from '../core/config-values.js';
|
|
2
2
|
import { assertApi, loadModel } from '../core/model.js';
|
|
3
|
+
import { loadProjectPackage } from '../core/project-package.js';
|
|
3
4
|
import { assertKnownKeys } from '../core/utils.js';
|
|
4
5
|
import { buildOpenapiDocument } from './document.js';
|
|
5
|
-
import { normalizeOpenapiInfo } from './options.js';
|
|
6
|
+
import { normalizeOpenapiInfo, projectPackageToOpenapiInfo } from './options.js';
|
|
6
7
|
/** Проверяет параметры экспорта и строит документ из подготовленной модели.
|
|
7
8
|
* @example Модель с коллекцией notes → документ с paths['/notes'].
|
|
8
9
|
*/
|
|
9
|
-
export function openapiFromModel(model, options
|
|
10
|
+
export function openapiFromModel(model, options) {
|
|
10
11
|
assertApi(model, 'openapi');
|
|
11
12
|
const auth = getBoolean(options.auth, 'auth');
|
|
12
13
|
const files = getBoolean(options.files, 'files');
|
|
@@ -16,9 +17,10 @@ export function openapiFromModel(model, options = {}) {
|
|
|
16
17
|
/** Загружает описание из объекта или файла и возвращает документ спецификации.
|
|
17
18
|
* @example Корректное описание → Promise<OpenapiDocument> с openapi: '3.0.3'.
|
|
18
19
|
*/
|
|
19
|
-
export async function generateOpenapi(schema, options
|
|
20
|
-
assertKnownKeys(options, new Set(['auth', 'files', 'host', 'port', 'pageSize', 'maxPageSize', '
|
|
21
|
-
|
|
20
|
+
export async function generateOpenapi(schema, options) {
|
|
21
|
+
assertKnownKeys(options, new Set(['auth', 'files', 'host', 'port', 'pageSize', 'maxPageSize', 'packagePath']), 'options');
|
|
22
|
+
const { packagePath, ...documentOptions } = options;
|
|
23
|
+
return openapiFromModel(await loadModel(schema, { auth: options.auth, api: ['openapi'] }), { ...documentOptions, info: projectPackageToOpenapiInfo(await loadProjectPackage(packagePath)) });
|
|
22
24
|
}
|
|
23
25
|
/** Строит HTTP-адрес, оборачивая IPv6 в квадратные скобки; нулевой порт даёт относительный адрес.
|
|
24
26
|
* @example getServerUrl({ host: '::1', port: 80 }) → 'http://[::1]:80'; { port: 0 } → '/'.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/openapi/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAgC,MAAM,kBAAkB,CAAC;AACtF,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/openapi/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAgC,MAAM,kBAAkB,CAAC;AACtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAoD,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAEnI;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAwB,EAAE,OAA+B;IACxF,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,aAAa,CAAC,EAAE,QAAQ,EAAE,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAC/L,CAAC;AACD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAA4B,EAAE,OAAuB;IACzF,eAAe,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC1H,MAAM,EAAE,WAAW,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,CAAC;IACpD,OAAO,gBAAgB,CAAC,MAAM,SAAS,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,eAAe,EAAE,IAAI,EAAE,2BAA2B,CAAC,MAAM,kBAAkB,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;AAC/L,CAAC;AAED;;GAEG;AACH,MAAM,YAAY,GAAG,CAAC,OAAyC,EAAU,EAAE;IACzE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAEpF,OAAO,UAAU,UAAU,IAAI,IAAI,EAAE,CAAC;AACxC,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,EAA+D,EAAmB,EAAE;IACtJ,MAAM,QAAQ,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;IAEjD,QAAQ,CAAC,OAAO,GAAG,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAE3D,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ProjectPackage } from '../core/project-package.js';
|
|
1
2
|
export type OpenapiInfo = {
|
|
2
3
|
title: string;
|
|
3
4
|
version: string;
|
|
@@ -7,6 +8,8 @@ export type OpenapiInfo = {
|
|
|
7
8
|
* @example normalizeOpenapiInfo({ title: 'API', version: '1' }) → { title: 'API', version: '1' }; description: 42 → ошибка.
|
|
8
9
|
*/
|
|
9
10
|
export declare function normalizeOpenapiInfo(value: unknown): OpenapiInfo | undefined;
|
|
11
|
+
/** Преобразует метаданные проекта в обязательный раздел info OpenAPI. */
|
|
12
|
+
export declare const projectPackageToOpenapiInfo: (value: ProjectPackage) => OpenapiInfo;
|
|
10
13
|
export interface OpenapiOptions {
|
|
11
14
|
auth?: boolean;
|
|
12
15
|
files?: boolean;
|
|
@@ -14,5 +17,8 @@ export interface OpenapiOptions {
|
|
|
14
17
|
port?: number;
|
|
15
18
|
pageSize?: number;
|
|
16
19
|
maxPageSize?: number;
|
|
17
|
-
|
|
20
|
+
packagePath: string;
|
|
18
21
|
}
|
|
22
|
+
export type OpenapiDocumentOptions = Omit<OpenapiOptions, 'packagePath'> & {
|
|
23
|
+
info: OpenapiInfo;
|
|
24
|
+
};
|
|
@@ -10,4 +10,10 @@ export function normalizeOpenapiInfo(value) {
|
|
|
10
10
|
throw new Error('Invalid OpenAPI info');
|
|
11
11
|
return structuredClone(info);
|
|
12
12
|
}
|
|
13
|
+
/** Преобразует метаданные проекта в обязательный раздел info OpenAPI. */
|
|
14
|
+
export const projectPackageToOpenapiInfo = (value) => ({
|
|
15
|
+
title: value.name,
|
|
16
|
+
version: value.version,
|
|
17
|
+
...(value.description === undefined ? {} : { description: value.description }),
|
|
18
|
+
});
|
|
13
19
|
//# sourceMappingURL=options.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/openapi/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/openapi/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGrD;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAC9C,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC5L,OAAO,eAAe,CAAC,IAAI,CAAgB,CAAC;AAC9C,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,KAAqB,EAAe,EAAE,CAAC,CAAC;IAClF,KAAK,EAAE,KAAK,CAAC,IAAI;IACjB,OAAO,EAAE,KAAK,CAAC,OAAO;IACtB,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC;CAC/E,CAAC,CAAC"}
|
|
@@ -41,7 +41,7 @@ export async function registerConfiguredModules(app, config, explicitModel, open
|
|
|
41
41
|
}
|
|
42
42
|
if (enabled.files && config.files) {
|
|
43
43
|
const { createFileStore, registerFileRoutes } = await import('../files/index.js');
|
|
44
|
-
const protectedPaths = inputPaths({ database: config.database, auth: config.auth }, '.', configSourcePath(config));
|
|
44
|
+
const protectedPaths = inputPaths({ database: config.database, auth: config.auth, package: config.package }, '.', configSourcePath(config));
|
|
45
45
|
registerFileRoutes(app, { getStore: () => createFileStore(config.files, protectedPaths), maxFileSize: config.server.maxFileSize });
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/server/bootstrap.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/server/bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,9 +2,9 @@ import type { FastifyServerOptions } from 'fastify';
|
|
|
2
2
|
import type { AuthConfig } from '../auth/contract.js';
|
|
3
3
|
import type { DatabaseConfig } from '../core/database.js';
|
|
4
4
|
import type { ModelSchema } from '../core/model.js';
|
|
5
|
+
import { type ProjectPackage } from '../core/project-package.js';
|
|
5
6
|
import type { Storage } from '../core/storage.js';
|
|
6
7
|
import type { FilesConfig } from '../files/contract.js';
|
|
7
|
-
import { type OpenapiInfo } from '../openapi/options.js';
|
|
8
8
|
export type { AuthConfig } from '../auth/contract.js';
|
|
9
9
|
export type { DatabaseConfig } from '../core/database.js';
|
|
10
10
|
export type { Storage } from '../core/storage.js';
|
|
@@ -13,12 +13,14 @@ export type DatabaseSchema = ModelSchema;
|
|
|
13
13
|
export interface OpenapiConfig {
|
|
14
14
|
endpoint?: string;
|
|
15
15
|
target?: string;
|
|
16
|
-
info?: OpenapiInfo;
|
|
17
16
|
}
|
|
18
17
|
export interface GraphqlConfig {
|
|
19
18
|
target?: string;
|
|
20
19
|
endpoint?: string;
|
|
21
20
|
}
|
|
21
|
+
export type PackageConfig<S extends Storage> = {
|
|
22
|
+
source: S extends 'file' ? string : ProjectPackage;
|
|
23
|
+
};
|
|
22
24
|
export interface ServerConfig {
|
|
23
25
|
cors?: boolean;
|
|
24
26
|
host?: string;
|
|
@@ -28,16 +30,27 @@ export interface ServerConfig {
|
|
|
28
30
|
pageSize?: number;
|
|
29
31
|
port?: number;
|
|
30
32
|
}
|
|
33
|
+
type ApiConfig<S extends Storage> = {
|
|
34
|
+
openapi?: undefined;
|
|
35
|
+
graphql?: undefined;
|
|
36
|
+
package?: PackageConfig<S>;
|
|
37
|
+
} | {
|
|
38
|
+
openapi: OpenapiConfig;
|
|
39
|
+
graphql?: GraphqlConfig;
|
|
40
|
+
package: PackageConfig<S>;
|
|
41
|
+
} | {
|
|
42
|
+
openapi?: OpenapiConfig;
|
|
43
|
+
graphql: GraphqlConfig;
|
|
44
|
+
package: PackageConfig<S>;
|
|
45
|
+
};
|
|
31
46
|
export type DeepJsonServerConfig = {
|
|
32
47
|
[S in Storage]: {
|
|
33
48
|
storage: S;
|
|
34
49
|
database: DatabaseConfig<S>;
|
|
35
50
|
files?: FilesConfig<S>;
|
|
36
51
|
auth?: AuthConfig<S>;
|
|
37
|
-
openapi?: OpenapiConfig;
|
|
38
|
-
graphql?: GraphqlConfig;
|
|
39
52
|
server?: ServerConfig;
|
|
40
|
-
}
|
|
53
|
+
} & ApiConfig<S>;
|
|
41
54
|
}[Storage];
|
|
42
55
|
type NormalizedSources = {
|
|
43
56
|
[S in Storage]: {
|
|
@@ -45,6 +58,7 @@ type NormalizedSources = {
|
|
|
45
58
|
database: DatabaseConfig<S>;
|
|
46
59
|
files?: FilesConfig<S>;
|
|
47
60
|
auth?: AuthConfig<S>;
|
|
61
|
+
package?: PackageConfig<S>;
|
|
48
62
|
};
|
|
49
63
|
}[Storage];
|
|
50
64
|
export type NormalizedServerConfig = NormalizedSources & {
|
|
@@ -3,9 +3,9 @@ import { pathToFileURL } from 'node:url';
|
|
|
3
3
|
import { getBoolean, getObject, getPositiveInteger, getString, normalizeAddress } from '../core/config-values.js';
|
|
4
4
|
import { DEFAULT_MAX_FILE_SIZE } from '../core/constants.js';
|
|
5
5
|
import { normalizePagination } from '../core/pagination.js';
|
|
6
|
+
import { normalizeProjectPackage } from '../core/project-package.js';
|
|
6
7
|
import { assertKnownKeys, errorMessage, isObject } from '../core/utils.js';
|
|
7
|
-
|
|
8
|
-
const CONFIG_KEYS = new Set(['storage', 'database', 'files', 'auth', 'openapi', 'graphql', 'server']);
|
|
8
|
+
const CONFIG_KEYS = new Set(['storage', 'database', 'files', 'auth', 'openapi', 'graphql', 'package', 'server']);
|
|
9
9
|
const SERVER_KEYS = new Set(['cors', 'host', 'logger', 'maxFileSize', 'maxPageSize', 'pageSize', 'port']);
|
|
10
10
|
let configImportIndex = 0;
|
|
11
11
|
/** Проверяет секцию и её допустимые ключи; undefined означает отсутствие секции.
|
|
@@ -42,6 +42,7 @@ function normalizeSources(config, directory) {
|
|
|
42
42
|
throw new Error('config.database is required');
|
|
43
43
|
const files = section(config.files, 'files', config.storage === 'file' ? ['source', 'metadata'] : ['source']);
|
|
44
44
|
const auth = section(config.auth, 'auth', ['source', 'expiresIn']);
|
|
45
|
+
const projectPackage = section(config.package, 'package', ['source']);
|
|
45
46
|
const expiresIn = getPositiveInteger(auth?.expiresIn, 'config.auth.expiresIn');
|
|
46
47
|
if (expiresIn !== undefined && expiresIn > 2147483647)
|
|
47
48
|
throw new Error('config.auth.expiresIn must be at most 2147483647 seconds');
|
|
@@ -53,6 +54,7 @@ function normalizeSources(config, directory) {
|
|
|
53
54
|
database: { source: path(database.source, 'database.source'), ...(database.schema === undefined ? {} : { schema: path(database.schema, 'database.schema') }) },
|
|
54
55
|
files: files && filesSource ? { source: filesSource, metadata: files.metadata === undefined ? resolve(filesSource, '.files.json') : path(files.metadata, 'files.metadata') } : undefined,
|
|
55
56
|
auth: auth ? { source: path(auth.source, 'auth.source'), expiresIn } : undefined,
|
|
57
|
+
package: projectPackage ? { source: path(projectPackage.source, 'package.source') } : undefined,
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
60
|
// Содержимое контейнеров проверяют загрузчики модели и хранилищ перед использованием.
|
|
@@ -64,6 +66,7 @@ function normalizeSources(config, directory) {
|
|
|
64
66
|
},
|
|
65
67
|
files: files ? { source: memorySource(files.source, 'files.source', true) } : undefined,
|
|
66
68
|
auth: auth ? { source: memorySource(auth.source, 'auth.source', true), expiresIn } : undefined,
|
|
69
|
+
package: projectPackage ? { source: normalizeProjectPackage(memorySource(projectPackage.source, 'package.source'), 'config.package.source') } : undefined,
|
|
67
70
|
};
|
|
68
71
|
}
|
|
69
72
|
/** Проверяет секции настроек и возвращает независимые данные с абсолютными путями.
|
|
@@ -73,10 +76,12 @@ function normalizeConfig(value, directory = '.') {
|
|
|
73
76
|
const config = getObject(value, 'config', true);
|
|
74
77
|
assertKnownKeys(config, CONFIG_KEYS, 'config');
|
|
75
78
|
const sources = normalizeSources(config, directory);
|
|
76
|
-
const openapi = section(config.openapi, 'openapi', ['target', '
|
|
79
|
+
const openapi = section(config.openapi, 'openapi', ['target', 'endpoint']);
|
|
77
80
|
const graphql = section(config.graphql, 'graphql', ['target', 'endpoint']);
|
|
78
81
|
if ((openapi || graphql) && sources.database.schema === undefined)
|
|
79
82
|
throw new Error('GraphQL and OpenAPI require an explicit model schema');
|
|
83
|
+
if ((openapi || graphql) && !sources.package)
|
|
84
|
+
throw new Error('GraphQL and OpenAPI require config.package');
|
|
80
85
|
const exportPath = (value, name) => (value === undefined ? undefined : resolve(directory, getString(value, name, true)));
|
|
81
86
|
const openapiEndpoint = getString(openapi?.endpoint, 'config.openapi.endpoint') ?? '/openapi.json';
|
|
82
87
|
const graphqlEndpoint = getString(graphql?.endpoint, 'config.graphql.endpoint') ?? '/graphql';
|
|
@@ -91,7 +96,7 @@ function normalizeConfig(value, directory = '.') {
|
|
|
91
96
|
throw new Error('config.server.logger must be boolean or an object');
|
|
92
97
|
return {
|
|
93
98
|
...sources,
|
|
94
|
-
openapi: openapi ? { endpoint: openapiEndpoint, target: exportPath(openapi.target, 'config.openapi.target')
|
|
99
|
+
openapi: openapi ? { endpoint: openapiEndpoint, target: exportPath(openapi.target, 'config.openapi.target') } : undefined,
|
|
95
100
|
graphql: graphql ? { endpoint: graphqlEndpoint, target: exportPath(graphql.target, 'config.graphql.target') } : undefined,
|
|
96
101
|
server: {
|
|
97
102
|
...normalizeAddress(server),
|
|
@@ -120,10 +125,10 @@ export async function readConfigModule(configPath) {
|
|
|
120
125
|
}
|
|
121
126
|
catch (error) {
|
|
122
127
|
const message = errorMessage(error);
|
|
123
|
-
throw new Error(
|
|
128
|
+
throw new Error(`Cannot load configuration ${resolvedConfigPath}: ${message}`, { cause: error });
|
|
124
129
|
}
|
|
125
130
|
if (!isObject(config)) {
|
|
126
|
-
throw new Error('
|
|
131
|
+
throw new Error('Server configuration must export a JSON object as default');
|
|
127
132
|
}
|
|
128
133
|
return { config, directory: dirname(resolvedConfigPath), path: resolvedConfigPath };
|
|
129
134
|
}
|