@kollors/deep-json-server 1.0.0-beta.6 → 1.0.0-rc.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/CHANGELOG.md +20 -0
- package/MIGRATION.md +41 -0
- package/README.md +73 -38
- package/README.ru.md +87 -52
- package/dist/src/cli/index.js +7 -7
- 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/model/infer.js +2 -2
- package/dist/src/core/model/infer.js.map +1 -1
- package/dist/src/core/model/load.js +9 -4
- package/dist/src/core/model/load.js.map +1 -1
- package/dist/src/core/model/policy.d.ts +1 -1
- package/dist/src/core/model/policy.js +4 -3
- package/dist/src/core/model/policy.js.map +1 -1
- package/dist/src/core/model/types.d.ts +5 -3
- 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/document.d.ts +3 -2
- package/dist/src/openapi/document.js +5 -4
- package/dist/src/openapi/document.js.map +1 -1
- package/dist/src/openapi/generate.js +8 -3
- package/dist/src/openapi/generate.js.map +1 -1
- package/dist/src/openapi/options.d.ts +1 -0
- package/dist/src/rest/routes.js +2 -2
- package/dist/src/rest/routes.js.map +1 -1
- package/dist/src/server/bootstrap.js +7 -2
- package/dist/src/server/bootstrap.js.map +1 -1
- package/dist/src/server/config.d.ts +1 -5
- package/dist/src/server/config.js +5 -5
- package/dist/src/server/config.js.map +1 -1
- package/dist/src/server/create.js +1 -1
- 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/model.js +10 -2
- package/dist/src/server/model.js.map +1 -1
- package/dist/src/server/openapi-options.d.ts +2 -1
- package/dist/src/server/openapi-options.js +2 -1
- package/dist/src/server/openapi-options.js.map +1 -1
- package/dist/src/server/public.d.ts +1 -1
- package/dist/src/server/public.js.map +1 -1
- package/examples/database.json +99 -0
- package/examples/schema.json +149 -0
- package/examples/server.config.js +8 -0
- package/package.json +5 -2
package/README.ru.md
CHANGED
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[История выпусков](CHANGELOG.md) · [Переход с 0.9.0](MIGRATION.md)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
JSON-сервер для создания тестового API с REST, GraphQL, связями между записями, загрузкой файлов и экспортом схем. Поддерживает вход пользователей, права владельца и администратора, даты записей и мягкое удаление. Требуется Node.js 22 или новее.
|
|
8
|
+
|
|
9
|
+
**Изменения в 1.0.0, нарушающие совместимость.** При переходе с 0.9.0 воспользуйтесь [инструкцией по миграции](MIGRATION.md). `*` в REST `scope` выбирает только скалярные поля, которые не хранят ключи связей. Массивы, объекты, связи и их ключи нужно указывать явно. При включённой аутентификации права на запись доступны через виртуальное поле `actions`.
|
|
8
10
|
|
|
9
11
|
## Установка
|
|
10
12
|
|
|
11
13
|
```sh
|
|
12
|
-
npm install @kollors/deep-json-server@
|
|
14
|
+
npm install @kollors/deep-json-server@rc
|
|
13
15
|
```
|
|
14
16
|
|
|
15
|
-
Для установки
|
|
17
|
+
Для установки этого релиз-кандидата укажите `@1.0.0-rc.2`.
|
|
16
18
|
|
|
17
19
|
## Быстрый старт
|
|
18
20
|
|
|
@@ -23,7 +25,7 @@ npm install @kollors/deep-json-server@beta
|
|
|
23
25
|
```json
|
|
24
26
|
{
|
|
25
27
|
"users": [
|
|
26
|
-
{ "id": "1", "fullName": "
|
|
28
|
+
{ "id": "1", "fullName": "Mira Volkova" }
|
|
27
29
|
]
|
|
28
30
|
}
|
|
29
31
|
```
|
|
@@ -44,7 +46,7 @@ npx deep-json-server server.config.js
|
|
|
44
46
|
|
|
45
47
|
## Конфигурация
|
|
46
48
|
|
|
47
|
-
При `storage: 'file'`
|
|
49
|
+
При `storage: 'file'` задайте пути для всех источников и схемы, при `'memory'` — передайте данные напрямую. Используйте один режим во всей конфигурации. Секции `auth` и `files` включают соответствующие REST-маршруты. Секция `graphql` настраивает маршрут GraphQL, а `openapi` публикует описание REST. `graphql: {}` и `openapi: {}` используют стандартные пути; для экспорта схемы добавьте `target`. GraphQL должен быть также включён корневым `api` схемы моделей.
|
|
48
50
|
|
|
49
51
|
```js
|
|
50
52
|
export default {
|
|
@@ -72,16 +74,46 @@ export default {
|
|
|
72
74
|
| `graphql.target` | Файл для экспорта GraphQL SDL |
|
|
73
75
|
| `openapi.endpoint` | HTTP-маршрут; по умолчанию `/openapi.json` |
|
|
74
76
|
| `openapi.target` | Файл для экспорта OpenAPI |
|
|
75
|
-
| `package.source` | `package.json` проекта; обязателен при наличии `openapi`
|
|
77
|
+
| `package.source` | `package.json` проекта; обязателен при наличии `openapi` |
|
|
76
78
|
| `server.host`, `server.port` | По умолчанию `127.0.0.1`, `4001`; CLI также читает `HOST`/`PORT` |
|
|
77
79
|
| `server.pageSize`, `server.maxPageSize` | По умолчанию 10 и 100; размер по умолчанию ограничен максимумом |
|
|
78
80
|
| `server.cors`, `server.logger` | По умолчанию `true`; logger принимает также настройки Fastify |
|
|
79
81
|
| `server.maxFileSize` | По умолчанию 100 МиБ |
|
|
80
82
|
|
|
81
|
-
`package.source`
|
|
83
|
+
Формат `package.source` зависит от режима хранения. При `storage: 'file'` укажите путь к `package.json`. При `storage: 'memory'` передайте метаданные напрямую: `{ name: 'example-api', version: '1.0.0', description: 'Example API' }`; `name` и `version` обязательны, `description` необязателен.
|
|
82
84
|
|
|
83
85
|
Относительные пути разрешаются от каталога файла конфигурации; при вызове `createServer(config)` — от рабочего каталога. Данные в памяти, включая схему и метаданные пакета, копируются. Порт `0` позволяет системе выбрать свободный порт.
|
|
84
86
|
|
|
87
|
+
Чтобы открыть базу только через GraphQL, а аутентификацию и файлы оставить в REST с описанием OpenAPI, укажите:
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
export default {
|
|
91
|
+
storage: 'file',
|
|
92
|
+
database: { source: './database.json', schema: './schema.json' },
|
|
93
|
+
auth: { source: './users.json' },
|
|
94
|
+
files: { source: './uploads' },
|
|
95
|
+
graphql: {},
|
|
96
|
+
openapi: {},
|
|
97
|
+
package: { source: './package.json' },
|
|
98
|
+
};
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
В корне `schema.json` задайте `api`:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"api": ["graphql"],
|
|
106
|
+
"models": {
|
|
107
|
+
"Item": {
|
|
108
|
+
"collection": "items",
|
|
109
|
+
"fields": { "id": { "type": "string", "primary": true } }
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Для REST с описанием OpenAPI используйте `"api": ["rest"]` и `openapi: {}`; для обоих API базы — `["rest", "graphql"]` с обеими секциями. Секция `graphql` обязательна тогда и только тогда, когда корневой `api` содержит `graphql`. OpenAPI описывает маршруты базы, только если включён REST; маршруты аутентификации и файлов включаются при наличии соответствующих секций.
|
|
116
|
+
|
|
85
117
|
### CLI
|
|
86
118
|
|
|
87
119
|
| Флаг | Действие |
|
|
@@ -101,10 +133,7 @@ export default {
|
|
|
101
133
|
|
|
102
134
|
```json
|
|
103
135
|
{
|
|
104
|
-
"api": [
|
|
105
|
-
"openapi",
|
|
106
|
-
"graphql"
|
|
107
|
-
],
|
|
136
|
+
"api": ["rest", "graphql"],
|
|
108
137
|
"models": {
|
|
109
138
|
"Country": {
|
|
110
139
|
"collection": "countries",
|
|
@@ -146,7 +175,11 @@ export default {
|
|
|
146
175
|
}
|
|
147
176
|
```
|
|
148
177
|
|
|
149
|
-
Модели
|
|
178
|
+
Модели задаются в `models`. Корень схемы принимает `models`, `api`, `timestamps` и `softDelete`. Корневой `api` выбирает маршруты базы. Если его нет, по умолчанию включён REST и дополнительно GraphQL при наличии секции `graphql` в конфигурации сервера. У модели настройки дат и мягкого удаления могут переопределять общие значения. Необязательный массив `api` у модели может сузить доступ до `['rest']`, `['graphql']`, обоих вариантов или `[]`, чтобы скрыть модель полностью. Модель не может включить API, отсутствующий в корневом `api`. OpenAPI включает модели, доступные через REST. Для генерации GraphQL нужна хотя бы одна GraphQL-модель; для генерации OpenAPI с маршрутами базы — хотя бы одна REST-модель. Если база доступна только через GraphQL, OpenAPI всё равно может описывать настроенные маршруты auth и файлов. Связанные модели должны разрешать тот же API. Имена моделей должны быть допустимыми идентификаторами; конфликты типов и операций вызывают ошибку. Имена `and`, `or`, `not` зарезервированы фильтрами.
|
|
179
|
+
|
|
180
|
+
Например, при корневом `api: ['rest', 'graphql']` модель с `api: ['rest']` получает REST-маршруты и пути в OpenAPI без операций GraphQL, а модель с `api: ['graphql']` — операции GraphQL без REST-маршрутов и путей в OpenAPI.
|
|
181
|
+
|
|
182
|
+
Исключённая из API модель остаётся частью схемы базы, а её сохранённые записи продолжают проверяться. Поле `api` управляет доступом клиентов к модели.
|
|
150
183
|
|
|
151
184
|
| Возможность | Со схемой | Без схемы |
|
|
152
185
|
|---|---|---|
|
|
@@ -159,7 +192,7 @@ export default {
|
|
|
159
192
|
|
|
160
193
|
REST без схемы создаёт ключ `id` и сохраняет произвольные JSON-поля. Новые выведенные связи доступны для последующего чтения и записи без перезапуска сервера. Для фильтров и выбора отдельных полей используются имена в формате идентификаторов. `scope=[{"*":true}]` возвращает скаляры верхнего уровня; массивы и объекты выбираются по имени. Поля с разными типами значений можно запросить явно, но фильтрация, сортировка и пагинация неоднородных списков требуют явной схемы.
|
|
161
194
|
|
|
162
|
-
У модели обязательны `collection`
|
|
195
|
+
У модели обязательны `collection` (имя коллекции в базе и REST-путь, если включён REST) и `fields` (описание полей). Имя модели (`User`) задаёт имена типов и операций GraphQL. `api` управляет доступностью маршрутов, а `timestamps` и `softDelete` переопределяют глобальные настройки для этой модели.
|
|
163
196
|
|
|
164
197
|
### Поля
|
|
165
198
|
|
|
@@ -225,37 +258,37 @@ REST без схемы создаёт ключ `id` и сохраняет про
|
|
|
225
258
|
{
|
|
226
259
|
"id": "1",
|
|
227
260
|
"isArchived": false,
|
|
228
|
-
"name": "
|
|
261
|
+
"name": "Ardenia"
|
|
229
262
|
},
|
|
230
263
|
{
|
|
231
264
|
"id": "2",
|
|
232
265
|
"isArchived": false,
|
|
233
|
-
"name": "
|
|
266
|
+
"name": "Veloria"
|
|
234
267
|
}
|
|
235
268
|
],
|
|
236
269
|
"genres": [
|
|
237
270
|
{
|
|
238
271
|
"id": "1",
|
|
239
272
|
"isArchived": false,
|
|
240
|
-
"name": "
|
|
273
|
+
"name": "Crime",
|
|
241
274
|
"parentIds": []
|
|
242
275
|
},
|
|
243
276
|
{
|
|
244
277
|
"id": "2",
|
|
245
278
|
"isArchived": false,
|
|
246
|
-
"name": "
|
|
279
|
+
"name": "Gangster",
|
|
247
280
|
"parentIds": ["1"]
|
|
248
281
|
},
|
|
249
282
|
{
|
|
250
283
|
"id": "3",
|
|
251
284
|
"isArchived": false,
|
|
252
|
-
"name": "
|
|
285
|
+
"name": "Drama",
|
|
253
286
|
"parentIds": []
|
|
254
287
|
},
|
|
255
288
|
{
|
|
256
289
|
"id": "4",
|
|
257
290
|
"isArchived": false,
|
|
258
|
-
"name": "
|
|
291
|
+
"name": "Comedy",
|
|
259
292
|
"parentIds": []
|
|
260
293
|
}
|
|
261
294
|
],
|
|
@@ -274,20 +307,20 @@ REST без схемы создаёт ключ `id` и сохраняет про
|
|
|
274
307
|
}
|
|
275
308
|
],
|
|
276
309
|
"coverSrc": "https://example.com/covers/shadows-of-ardenia.jpg",
|
|
277
|
-
"description": "
|
|
310
|
+
"description": "An heiress in a port city uncovers a plot involving two rival families.",
|
|
278
311
|
"id": "1",
|
|
279
312
|
"isArchived": false,
|
|
280
313
|
"publisherIds": ["2"],
|
|
281
|
-
"title": "
|
|
314
|
+
"title": "Shadows of Ardenia"
|
|
282
315
|
},
|
|
283
316
|
{
|
|
284
317
|
"actors": [],
|
|
285
318
|
"coverSrc": "https://example.com/covers/northern-star.jpg",
|
|
286
|
-
"description": "
|
|
319
|
+
"description": "A night clerk at an old hotel gets drawn into the search for a missing painting.",
|
|
287
320
|
"id": "2",
|
|
288
321
|
"isArchived": false,
|
|
289
322
|
"publisherIds": ["1"],
|
|
290
|
-
"title": "
|
|
323
|
+
"title": "Midnight at the Northern Star"
|
|
291
324
|
}
|
|
292
325
|
],
|
|
293
326
|
"publishers": [
|
|
@@ -306,14 +339,14 @@ REST без схемы создаёт ключ `id` и сохраняет про
|
|
|
306
339
|
{
|
|
307
340
|
"bornAt": "1988-03-14",
|
|
308
341
|
"countryId": "1",
|
|
309
|
-
"fullName": "
|
|
342
|
+
"fullName": "Mira Volkova",
|
|
310
343
|
"id": "1",
|
|
311
344
|
"isArchived": false
|
|
312
345
|
},
|
|
313
346
|
{
|
|
314
347
|
"bornAt": "1991-11-02",
|
|
315
348
|
"countryId": "2",
|
|
316
|
-
"fullName": "
|
|
349
|
+
"fullName": "Leon Vetrov",
|
|
317
350
|
"id": "2",
|
|
318
351
|
"isArchived": false
|
|
319
352
|
}
|
|
@@ -361,7 +394,7 @@ npx deep-json-server examples/server.config.js
|
|
|
361
394
|
|
|
362
395
|
### REST
|
|
363
396
|
|
|
364
|
-
`GET /`
|
|
397
|
+
Если REST включён корневым `api`, `GET /` перечисляет только REST-модели: `{ "resources": ["users", "movies"] }`. При базе только с GraphQL маршрута `GET /` нет. Для каждой REST-коллекции доступны следующие маршруты:
|
|
365
398
|
|
|
366
399
|
| Метод | Путь | Операция |
|
|
367
400
|
|---|---|---|
|
|
@@ -374,11 +407,11 @@ npx deep-json-server examples/server.config.js
|
|
|
374
407
|
|
|
375
408
|
Имя параметра пути соответствует первичному ключу. POST, PUT и PATCH принимают JSON-объект записи. PUT заменяет запись с сохранением ключа и серверных полей. PATCH объединяет поля на верхнем уровне; переданные вложенные объекты заменяются с сохранением их полей `readOnly`. Создание и замена требуют всех обязательных полей. При обновлении проверяются переданные значения и итоговая запись. Отсутствующая запись — `404`, конфликт — `409`.
|
|
376
409
|
|
|
377
|
-
POST возвращает созданную запись со статусом `201`; PUT, PATCH и DELETE — результат со статусом `200`. Ошибки REST имеют вид `{ "error": "
|
|
410
|
+
POST возвращает созданную запись со статусом `201`; PUT, PATCH и DELETE — результат со статусом `200`. Ошибки REST имеют вид `{ "error": "Error description" }`.
|
|
378
411
|
|
|
379
412
|
### Параметры REST-запросов
|
|
380
413
|
|
|
381
|
-
Для запросов к записям REST принимает один параметр URL `scope` с JSON-массивом `[
|
|
414
|
+
Для запросов к записям REST принимает один параметр URL `scope` с JSON-массивом `[fields, arguments?]`. Первый объект выбирает поля, второй задаёт `where`, `order` и `pager` для списка. Этот формат одинаков для корневого запроса, вложенных объектов и связей.
|
|
382
415
|
|
|
383
416
|
Пример выбора пользователей и их фильмов с отдельной сортировкой и пагинацией:
|
|
384
417
|
|
|
@@ -393,7 +426,7 @@ const scope = [
|
|
|
393
426
|
],
|
|
394
427
|
},
|
|
395
428
|
{
|
|
396
|
-
where: { fullName: { contains: '
|
|
429
|
+
where: { fullName: { contains: 'Mira' } },
|
|
397
430
|
order: [{ field: 'fullName', direction: 'ASC' }],
|
|
398
431
|
pager: { page: 1, pageSize: 20 },
|
|
399
432
|
},
|
|
@@ -441,8 +474,8 @@ Content-Type: application/json
|
|
|
441
474
|
"userId": "1",
|
|
442
475
|
"genres": [
|
|
443
476
|
{ "id": "1" },
|
|
444
|
-
{ "id": "2", "name": "
|
|
445
|
-
{ "name": "
|
|
477
|
+
{ "id": "2", "name": "Updated genre" },
|
|
478
|
+
{ "name": "New genre" }
|
|
446
479
|
]
|
|
447
480
|
}
|
|
448
481
|
]
|
|
@@ -479,7 +512,7 @@ mutation {
|
|
|
479
512
|
movieUpdate(id: "1", data: {
|
|
480
513
|
actors: [{
|
|
481
514
|
userId: "1"
|
|
482
|
-
genres: [{ id: "2", name: "
|
|
515
|
+
genres: [{ id: "2", name: "Updated genre" }, { name: "New genre" }]
|
|
483
516
|
}]
|
|
484
517
|
}) {
|
|
485
518
|
actors { data { genres { data { id name } } } }
|
|
@@ -489,7 +522,7 @@ mutation {
|
|
|
489
522
|
|
|
490
523
|
### GraphQL
|
|
491
524
|
|
|
492
|
-
Укажите `database.schema` и добавьте в конфигурацию `graphql: {}
|
|
525
|
+
Укажите `database.schema`, включите `graphql` в корневой `api` схемы и добавьте в конфигурацию `graphql: {}`:
|
|
493
526
|
|
|
494
527
|
```sh
|
|
495
528
|
npx deep-json-server server.config.js
|
|
@@ -500,7 +533,7 @@ npx deep-json-server server.config.js
|
|
|
500
533
|
```graphql
|
|
501
534
|
query {
|
|
502
535
|
userList(
|
|
503
|
-
where: { fullName: { contains: "
|
|
536
|
+
where: { fullName: { contains: "Mira" } }
|
|
504
537
|
order: [{ field: fullName, direction: ASC }]
|
|
505
538
|
pager: { page: 1, pageSize: 20 }
|
|
506
539
|
) {
|
|
@@ -509,7 +542,7 @@ query {
|
|
|
509
542
|
id
|
|
510
543
|
fullName
|
|
511
544
|
movies(
|
|
512
|
-
where: { title: { contains: "
|
|
545
|
+
where: { title: { contains: "Shadows" } }
|
|
513
546
|
order: [{ field: title, direction: ASC }]
|
|
514
547
|
pager: { pageSize: 5 }
|
|
515
548
|
) {
|
|
@@ -529,7 +562,7 @@ query {
|
|
|
529
562
|
|
|
530
563
|
## OpenAPI и экспорт схем
|
|
531
564
|
|
|
532
|
-
Экспорт использует OpenAPI 3.0.3. Добавьте `openapi: {}`, `database.schema` и `package.source`, чтобы получать спецификацию по HTTP на `/openapi.json`. Путь меняется через `openapi.endpoint`. Поля OpenAPI `info.title`, `info.version` и необязательное `info.description` берутся из настроенного `package.json`. Спецификацию можно открыть в Swagger UI или импортировать в API-клиент.
|
|
565
|
+
Экспорт использует OpenAPI 3.0.3. Добавьте `openapi: {}`, `database.schema` и `package.source`, чтобы получать спецификацию по HTTP на `/openapi.json`. Путь меняется через `openapi.endpoint`. Маршруты базы включаются только для REST-моделей; при базе только с GraphQL документ всё равно может описывать настроенные маршруты auth и файлов. Поля OpenAPI `info.title`, `info.version` и необязательное `info.description` берутся из настроенного `package.json`. Спецификацию можно открыть в Swagger UI или импортировать в API-клиент.
|
|
533
566
|
|
|
534
567
|
Для сохранения схем задайте пути экспорта:
|
|
535
568
|
|
|
@@ -548,7 +581,7 @@ npx deep-json-server server.config.js --generate-only
|
|
|
548
581
|
npx deep-json-server server.config.js --generate
|
|
549
582
|
```
|
|
550
583
|
|
|
551
|
-
`--generate-only` экспортирует и завершает работу, `--generate` после экспорта запускает сервер. Форматы определяются наличием секций. Для каждого выбранного формата обязателен свой `target`. Если секций нет, отсутствует `target` или генерация завершилась ошибкой, команда возвращает ошибку и сервер не запускается.
|
|
584
|
+
`--generate-only` экспортирует и завершает работу, `--generate` после экспорта запускает сервер. Форматы определяются наличием секций. Для каждого выбранного формата обязателен свой `target`. HTTP-маршрут OpenAPI возвращает JSON; `writeOpenapi()` и CLI записывают YAML. Если секций нет, отсутствует `target` или генерация завершилась ошибкой, команда возвращает ошибку и сервер не запускается.
|
|
552
585
|
|
|
553
586
|
Экспорт не открывает базу, учётные записи и файлы. Перед записью проверяются все выбранные `target`; они не могут совпадать с конфигурацией, базой, схемой, пользователями, счётчиками или метаданными файлов.
|
|
554
587
|
|
|
@@ -657,7 +690,7 @@ query {
|
|
|
657
690
|
|
|
658
691
|
`actions` доступен у корневых и связанных записей моделей, включая результаты мутаций. Его нельзя записывать, фильтровать или сортировать. Обычные вложенные объекты и ответы методов auth это поле не получают.
|
|
659
692
|
|
|
660
|
-
|
|
693
|
+
Когда настроен `openapi`, его документ описывает маршруты auth, необязательную Bearer-аутентификацию при чтении записей, обязательную при изменениях и поле ответа `actions`. В Swagger UI токен из ответа на вход можно вставить в **Authorize**. Для экспорта схем включите auth в конфигурации и выполните `npx deep-json-server server.config.js --generate-only`; файл учётных записей при генерации не читается. Методы auth доступны через REST. В GraphQL тот же токен проверяется при чтении прав и изменении записей. Для GraphQL и OpenAPI нужна `database.schema`.
|
|
661
694
|
|
|
662
695
|
## Даты записей, удаление и владельцы
|
|
663
696
|
|
|
@@ -717,11 +750,11 @@ OpenAPI описывает маршруты auth, необязательную B
|
|
|
717
750
|
|
|
718
751
|
При включённом auth создавать записи может любой вошедший пользователь. Изменять, удалять и восстанавливать — владелец по `createdById` или пользователь с `isAdmin: true`. Записи без владельца изменяет только администратор. Его правки не меняют владельца. Правила действуют на вложенные записи, изменение ключей связей, каскады и восстановление. Ссылка на существующую запись без её изменения не требует владения ею. Каждая мутация атомарна: отказ сохраняет прежнее состояние всех затронутых записей.
|
|
719
752
|
|
|
720
|
-
REST возвращает 401 при отсутствии действительного токена и 403 при недостатке прав. GraphQL проверяет мутации по тем же правилам и возвращает коды `UNAUTHENTICATED` или `FORBIDDEN`; токен получают через REST-вход и передают в `Authorization: Bearer
|
|
753
|
+
REST возвращает 401 при отсутствии действительного токена и 403 при недостатке прав. GraphQL проверяет мутации по тем же правилам и возвращает коды `UNAUTHENTICATED` или `FORBIDDEN`; токен получают через REST-вход и передают в `Authorization: Bearer <token>`. GraphQL-запросы чтения, OPTIONS и все операции с файлами остаются открытыми.
|
|
721
754
|
|
|
722
755
|
## Файлы
|
|
723
756
|
|
|
724
|
-
Файлы доступны через REST и
|
|
757
|
+
Файлы доступны через REST и появляются в документе OpenAPI, если настроена секция `openapi`. Добавьте хранилище в конфигурацию:
|
|
725
758
|
|
|
726
759
|
```js
|
|
727
760
|
export default {
|
|
@@ -769,13 +802,13 @@ Content-Type: image/jpeg
|
|
|
769
802
|
Сочетание `directory` и `name` идентифицирует файл. Повторная загрузка по существующему пути возвращает `409`. Чтобы заменить файл, передайте `Content-Override: true`; успешная перезапись возвращает `200`. Сервер поддерживает следующие файловые маршруты:
|
|
770
803
|
|
|
771
804
|
```text
|
|
772
|
-
POST /_files/storage
|
|
773
|
-
GET /_files/storage/*
|
|
774
|
-
PATCH /_files/storage/*
|
|
775
|
-
DELETE /_files/storage/*
|
|
805
|
+
POST /_files/storage Upload or replace a file
|
|
806
|
+
GET /_files/storage/* Return file contents inline
|
|
807
|
+
PATCH /_files/storage/* Rename or move a file
|
|
808
|
+
DELETE /_files/storage/* Delete a file
|
|
776
809
|
|
|
777
|
-
GET /_files/metadata/*
|
|
778
|
-
GET /_files/download/*
|
|
810
|
+
GET /_files/metadata/* Return file metadata as JSON
|
|
811
|
+
GET /_files/download/* Download a file as an attachment
|
|
779
812
|
```
|
|
780
813
|
|
|
781
814
|
Для переименования, перемещения либо обеих операций отправьте JSON-объект. Нужно указать хотя бы одно поле:
|
|
@@ -812,7 +845,9 @@ await server.listen();
|
|
|
812
845
|
|
|
813
846
|
Методы `openapi()` и `graphql()` возвращают схемы и требуют `database.schema`. `fastify()` возвращает экземпляр сервера для настройки и запуска. База и включённые сервисы инициализируются при `ready()`, `listen()` или первом `inject()`; ошибка инициализации останавливает запуск.
|
|
814
847
|
|
|
815
|
-
`createServer(config)` принимает тот же объект конфигурации, что и CLI. При наличии `openapi`
|
|
848
|
+
`createServer(config)` принимает тот же объект конфигурации, что и CLI. При наличии `openapi` обязателен `package.source`. Для методов `openapi()` и `graphql()` нужна соответствующая секция. Методы возвращают схему и не записывают файлы.
|
|
849
|
+
|
|
850
|
+
Полученный экземпляр Fastify принимает обычные параметры `listen()`, включая путь Unix-сокета. Вызов `listen()` без параметров использует `server.host` и `server.port`.
|
|
816
851
|
|
|
817
852
|
Эти функции доступны и через общий импорт `@kollors/deep-json-server`. Адаптеры сервера загружаются при включении. Генераторы можно использовать отдельно:
|
|
818
853
|
|
|
@@ -826,13 +861,13 @@ await writeOpenapi(document, './generated/openapi.yaml');
|
|
|
826
861
|
await writeGraphql(sdl, './generated/schema.graphql');
|
|
827
862
|
```
|
|
828
863
|
|
|
829
|
-
Отдельные генераторы принимают путь или объект схемы и не требуют конфигурации сервера.
|
|
864
|
+
Отдельные генераторы принимают путь или объект схемы и не требуют конфигурации сервера. Если корневой `api` не задан, `generateOpenapi()` использует REST по умолчанию, а `generateGraphql()` — GraphQL. Явные значения `api` в корне и у моделей сохраняют силу; для выбранного формата нужна хотя бы одна доступная модель. `timestamps` и `softDelete` берутся из схемы. Опция `{ auth: true }` добавляет поля владельца и `actions`; OpenAPI также описывает маршруты auth и требования токена. `hashPassword()` доступна и через общий импорт пакета.
|
|
830
865
|
|
|
831
866
|
Для `generateOpenapi()` обязателен `packagePath`; дополнительно доступны `host`, `port`, `pageSize` и `maxPageSize`. Метаданные OpenAPI читаются из указанного пакета. Вместо пути можно передать объект схемы. Сервер и генераторы работают с собственной копией модели. Размеры страниц должны быть положительными целыми числами; `pageSize` не может превышать `maxPageSize`.
|
|
832
867
|
|
|
833
868
|
## Хранение данных
|
|
834
869
|
|
|
835
|
-
Изменения выполняются последовательно внутри экземпляра сервера и проверяются на копии данных до сохранения. Для одного файла базы используйте один процесс сервера. Счётчики `increment` хранятся рядом с базой в
|
|
870
|
+
Изменения выполняются последовательно внутри экземпляра сервера и проверяются на копии данных до сохранения. Для одного файла базы используйте один процесс сервера. Счётчики `increment` хранятся рядом с базой в `<database path>.counters.json`; сохраняйте этот файл вместе с базой. Номера резервируются до записи данных: сбой может оставить пропуск, но не приводит к повторной выдаче номера.
|
|
836
871
|
|
|
837
872
|
## Разработка
|
|
838
873
|
|
|
@@ -843,8 +878,8 @@ npm ci
|
|
|
843
878
|
npm run verify
|
|
844
879
|
```
|
|
845
880
|
|
|
846
|
-
|
|
881
|
+
`npm run verify` проверяет типы, стиль кода, покрытие тестами и установку пакета из архива.
|
|
847
882
|
|
|
848
|
-
Для публикации предварительной версии обновите номер в `package.json`, `package-lock.json` и `src/core/constants.ts`, затем отправьте коммит в `main`. GitHub Actions создаст тег `v
|
|
883
|
+
Для публикации предварительной версии обновите номер в `package.json`, `package-lock.json` и `src/core/constants.ts`, затем отправьте коммит в `main`. GitHub Actions создаст тег `v<version>` и опубликует пакет через trusted publishing в канал `alpha`, `beta` или `rc`. Стабильные версии публикуются в `latest` из явно отправленного тега версии.
|
|
849
884
|
|
|
850
885
|
Лицензия: MIT.
|
package/dist/src/cli/index.js
CHANGED
|
@@ -37,14 +37,14 @@ async function generate(config, source, directory, sourcePath, openapiInfo) {
|
|
|
37
37
|
continue;
|
|
38
38
|
const target = config[format].target;
|
|
39
39
|
if (!target)
|
|
40
|
-
throw new Error(
|
|
40
|
+
throw new Error(`Provide config.${format}.target`);
|
|
41
41
|
outputs.push(target);
|
|
42
42
|
}
|
|
43
43
|
await validateExportPaths(outputs, inputPaths(source, directory, sourcePath));
|
|
44
44
|
const model = await configuredModel(config);
|
|
45
45
|
if (config.openapi && !openapiInfo)
|
|
46
46
|
throw new Error('OpenAPI package metadata is not configured');
|
|
47
|
-
const openapi = config.openapi ? (await import('../openapi/generate.js')).openapiFromModel(model, openapiOptions(config, openapiInfo)) : undefined;
|
|
47
|
+
const openapi = config.openapi ? (await import('../openapi/generate.js')).openapiFromModel(model, openapiOptions(config, openapiInfo, model)) : undefined;
|
|
48
48
|
const graphql = config.graphql ? (await import('../graphql/generate.js')).graphqlFromModel(model) : undefined;
|
|
49
49
|
if (openapi && config.openapi?.target) {
|
|
50
50
|
await writeOpenapi(openapi, config.openapi.target);
|
|
@@ -80,12 +80,12 @@ export async function runCli(args = process.argv.slice(2), services = { createSe
|
|
|
80
80
|
continue;
|
|
81
81
|
}
|
|
82
82
|
if (!['--generate', '--generate-only', '--host', '--port'].includes(arg) || seen.has(arg))
|
|
83
|
-
throw new Error(
|
|
83
|
+
throw new Error(`Unknown or duplicate option: ${arg}`);
|
|
84
84
|
seen.add(arg);
|
|
85
85
|
if (arg === '--host' || arg === '--port') {
|
|
86
86
|
const value = args[++index];
|
|
87
87
|
if (!value || value.startsWith('-'))
|
|
88
|
-
throw new Error(
|
|
88
|
+
throw new Error(`Provide a value for ${arg}`);
|
|
89
89
|
if (arg === '--host')
|
|
90
90
|
host = value;
|
|
91
91
|
else {
|
|
@@ -98,12 +98,12 @@ export async function runCli(args = process.argv.slice(2), services = { createSe
|
|
|
98
98
|
if (seen.has('--generate') && seen.has('--generate-only'))
|
|
99
99
|
throw new Error('--generate and --generate-only are mutually exclusive');
|
|
100
100
|
if (!positional.length)
|
|
101
|
-
throw new Error('
|
|
101
|
+
throw new Error('Provide a configuration file path');
|
|
102
102
|
if (positional.length !== 1)
|
|
103
|
-
throw new Error('
|
|
103
|
+
throw new Error('Provide exactly one configuration file');
|
|
104
104
|
const configPath = positional[0];
|
|
105
105
|
if (configPath === undefined)
|
|
106
|
-
throw new Error('
|
|
106
|
+
throw new Error('Provide a configuration file path');
|
|
107
107
|
const source = await readConfigModule(configPath);
|
|
108
108
|
const server = source.config.server ?? {};
|
|
109
109
|
if (!isObject(server))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,SAAS,EAA+B,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC/F,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,MAAM,SAAS,GAAG;;;;;;;;;;;;;kEAagD,CAAC;AAEnE;;GAEG;AACH,KAAK,UAAU,QAAQ,CAAC,MAA8B,EAAE,MAA+B,EAAE,SAAiB,EAAE,UAAkB,EAAE,WAAyB;IACvJ,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IAC7G,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,MAAM,IAAI,CAAC,SAAS,EAAE,SAAS,CAAU,EAAE,CAAC;QACrD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;YAAE,SAAS;QAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;QACrC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,MAAM,SAAS,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IACD,MAAM,mBAAmB,CAAC,OAAO,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAC9E,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,WAAW;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAClG,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,MAAM,EAAE,WAA0B,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ export function getObject(value, path, required = false) {
|
|
|
5
5
|
return undefined;
|
|
6
6
|
}
|
|
7
7
|
if (!isObject(value)) {
|
|
8
|
-
throw new Error(
|
|
8
|
+
throw new Error(`${path} must be a JSON object`);
|
|
9
9
|
}
|
|
10
10
|
return value;
|
|
11
11
|
}
|
|
@@ -14,7 +14,7 @@ export function getString(value, path, required = false) {
|
|
|
14
14
|
return undefined;
|
|
15
15
|
}
|
|
16
16
|
if (typeof value !== 'string' || value.trim() === '') {
|
|
17
|
-
throw new Error(
|
|
17
|
+
throw new Error(`${path} must be a nonempty string`);
|
|
18
18
|
}
|
|
19
19
|
return value;
|
|
20
20
|
}
|
|
@@ -26,7 +26,7 @@ export const getPositiveInteger = (value, path) => {
|
|
|
26
26
|
return undefined;
|
|
27
27
|
}
|
|
28
28
|
if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 1) {
|
|
29
|
-
throw new Error(
|
|
29
|
+
throw new Error(`${path} must be a positive integer`);
|
|
30
30
|
}
|
|
31
31
|
return value;
|
|
32
32
|
};
|
|
@@ -47,7 +47,7 @@ export function normalizeAddress(options) {
|
|
|
47
47
|
const host = getString(options.host, 'config.server.host') ?? DEFAULT_HOST;
|
|
48
48
|
const port = options.port ?? DEFAULT_PORT;
|
|
49
49
|
if (!isPortNumber(port))
|
|
50
|
-
throw new Error('
|
|
50
|
+
throw new Error('config.server.port must be an integer from 0 to 65535');
|
|
51
51
|
return { host, port };
|
|
52
52
|
}
|
|
53
53
|
//# sourceMappingURL=config-values.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-values.js","sourceRoot":"","sources":["../../../src/core/config-values.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAOpD,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,IAAY,EAAE,QAAQ,GAAG,KAAK;IACtE,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,
|
|
1
|
+
{"version":3,"file":"config-values.js","sourceRoot":"","sources":["../../../src/core/config-values.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAOpD,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,IAAY,EAAE,QAAQ,GAAG,KAAK;IACtE,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,GAAG,IAAI,wBAAwB,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAOD,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,IAAY,EAAE,QAAQ,GAAG,KAAK;IACtE,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,GAAG,IAAI,4BAA4B,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAc,EAAE,IAAY,EAAsB,EAAE;IACrF,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC3E,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,6BAA6B,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,KAAc,EAAE,IAAY;IACrD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,kBAAkB,CAAC,CAAC;IAC3E,OAAO,KAAK,CAAC;AACf,CAAC;AACD;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA2C;IAC1E,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,oBAAoB,CAAC,IAAI,YAAY,CAAC;IAC3E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,YAAY,CAAC;IAC1C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAClG,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC"}
|
|
@@ -3,4 +3,4 @@ export declare const DEFAULT_MAX_FILE_SIZE: number;
|
|
|
3
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-
|
|
6
|
+
export declare const VERSION = "1.0.0-rc.2";
|
|
@@ -3,5 +3,5 @@ export const DEFAULT_MAX_FILE_SIZE = 100 * 1024 * 1024;
|
|
|
3
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-
|
|
6
|
+
export const VERSION = '1.0.0-rc.2';
|
|
7
7
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/core/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,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/core/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,YAAY,CAAC"}
|