@kollors/deep-json-server 0.3.1 → 0.3.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 +1 -1
- package/README.ru.md +1 -1
- package/package.json +1 -1
- package/src/openapi.js +5 -3
- package/src/server.js +2 -16
- package/src/utils.js +15 -1
package/README.md
CHANGED
|
@@ -106,7 +106,7 @@ PATCH /movies/:id
|
|
|
106
106
|
DELETE /movies/:id
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
`POST` generates a string ID, while `PUT` and `PATCH` preserve the stored ID type. All write operations — `POST`, `PUT`, `PATCH` and `DELETE` — persist their changes in the JSON file. The database file must exist before startup and contain a JSON object whose
|
|
109
|
+
`POST` generates a string ID, while `PUT` and `PATCH` preserve the stored ID type. All write operations — `POST`, `PUT`, `PATCH` and `DELETE` — persist their changes in the JSON file. The database file must exist before startup and contain a JSON object whose every top-level property is an array of resource records.
|
|
110
110
|
|
|
111
111
|
## Pagination and sorting
|
|
112
112
|
|
package/README.ru.md
CHANGED
|
@@ -106,7 +106,7 @@ PATCH /movies/:id
|
|
|
106
106
|
DELETE /movies/:id
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
`POST` генерирует строковый ID, а `PUT` и `PATCH` сохраняют исходный тип ID. Все операции записи — `POST`, `PUT`, `PATCH` и `DELETE` — сохраняют изменения в JSON-файле. Файл базы должен существовать до запуска и содержать JSON-объект,
|
|
109
|
+
`POST` генерирует строковый ID, а `PUT` и `PATCH` сохраняют исходный тип ID. Все операции записи — `POST`, `PUT`, `PATCH` и `DELETE` — сохраняют изменения в JSON-файле. Файл базы должен существовать до запуска и содержать JSON-объект, каждое свойство верхнего уровня которого является массивом записей отдельного ресурса.
|
|
110
110
|
|
|
111
111
|
## Пагинация и сортировка
|
|
112
112
|
|
package/package.json
CHANGED
package/src/openapi.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, resolve } from 'node:path';
|
|
3
3
|
import { stringify } from 'yaml';
|
|
4
|
-
import { getResourceNames, isObject, singularize, toPascalCase } from './utils.js';
|
|
4
|
+
import { getResourceNames, isObject, singularize, toPascalCase, validateDatabase } from './utils.js';
|
|
5
5
|
|
|
6
6
|
const readJson = async(path, label) => {
|
|
7
7
|
const value = JSON.parse(await readFile(resolve(path), 'utf8'));
|
|
@@ -450,8 +450,10 @@ const validateGeneratedNames = (resources, componentNames) => {
|
|
|
450
450
|
};
|
|
451
451
|
|
|
452
452
|
export function createOpenApiDocument(database, schemaConfig = {}, { host = '127.0.0.1', port = 4001 } = {}) {
|
|
453
|
-
|
|
454
|
-
|
|
453
|
+
validateDatabase(database);
|
|
454
|
+
|
|
455
|
+
if (!isObject(schemaConfig)) {
|
|
456
|
+
throw new Error('Схема базы данных должна содержать JSON-объект');
|
|
455
457
|
}
|
|
456
458
|
|
|
457
459
|
const resources = getResourceNames(database);
|
package/src/server.js
CHANGED
|
@@ -4,7 +4,7 @@ import { randomBytes } from 'node:crypto';
|
|
|
4
4
|
import { readFile } from 'node:fs/promises';
|
|
5
5
|
import { matchesWhere, paginateItems, parsePagination, parseWhere, sortItems, validateWhere } from './query.js';
|
|
6
6
|
import { embedItem, parseEmbedPaths } from './relations.js';
|
|
7
|
-
import { createHttpError, getResourceNames, isObject, isSafeKey, resolveDatabasePath } from './utils.js';
|
|
7
|
+
import { createHttpError, getResourceNames, isObject, isSafeKey, resolveDatabasePath, validateDatabase } from './utils.js';
|
|
8
8
|
|
|
9
9
|
const CORS_HEADERS = {
|
|
10
10
|
'Access-Control-Allow-Headers': 'Content-Type',
|
|
@@ -32,18 +32,6 @@ const getRequestBody = (body) => {
|
|
|
32
32
|
|
|
33
33
|
const findItem = (collection, id) => collection.find((item) => isObject(item) && String(item.id) === id);
|
|
34
34
|
|
|
35
|
-
const validateDatabase = (data) => {
|
|
36
|
-
if (!isObject(data)) {
|
|
37
|
-
throw new Error('База данных должна содержать JSON-объект');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const invalidResource = Object.entries(data).find(([key, value]) => !key.startsWith('$') && !Array.isArray(value));
|
|
41
|
-
|
|
42
|
-
if (invalidResource != null) {
|
|
43
|
-
throw new Error(`Ресурс «${invalidResource[0]}» должен содержать JSON-массив`);
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
|
|
47
35
|
const readDatabaseFile = async(databasePath) => {
|
|
48
36
|
let source;
|
|
49
37
|
|
|
@@ -59,9 +47,7 @@ const readDatabaseFile = async(databasePath) => {
|
|
|
59
47
|
|
|
60
48
|
const data = JSON.parse(source);
|
|
61
49
|
|
|
62
|
-
validateDatabase(data);
|
|
63
|
-
|
|
64
|
-
return data;
|
|
50
|
+
return validateDatabase(data);
|
|
65
51
|
};
|
|
66
52
|
|
|
67
53
|
export async function createServer({ databasePath, logger = true } = {}) {
|
package/src/utils.js
CHANGED
|
@@ -13,12 +13,26 @@ export const createHttpError = (statusCode, message) => {
|
|
|
13
13
|
return error;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
export const getResourceNames = (data) => Object.
|
|
16
|
+
export const getResourceNames = (data) => Object.keys(data);
|
|
17
17
|
export const isMainModule = (filePath, moduleUrl) => filePath != null && realpathSync(resolve(filePath)) === fileURLToPath(moduleUrl);
|
|
18
18
|
export const isObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
19
19
|
export const isSafeKey = (key) => !UNSAFE_KEYS.has(key);
|
|
20
20
|
export const toArray = (value) => (Array.isArray(value) ? value : [value]);
|
|
21
21
|
|
|
22
|
+
export const validateDatabase = (data) => {
|
|
23
|
+
if (!isObject(data)) {
|
|
24
|
+
throw new Error('База данных должна содержать JSON-объект');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const invalidResource = Object.entries(data).find(([, value]) => !Array.isArray(value));
|
|
28
|
+
|
|
29
|
+
if (invalidResource != null) {
|
|
30
|
+
throw new Error(`Ресурс «${invalidResource[0]}» должен содержать JSON-массив`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return data;
|
|
34
|
+
};
|
|
35
|
+
|
|
22
36
|
export const isEqual = (left, right) => {
|
|
23
37
|
if (Object.is(left, right)) {
|
|
24
38
|
return true;
|