@kollors/deep-json-server 1.0.0-rc.2 → 1.0.0-rc.4
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 +12 -0
- package/MIGRATION.md +3 -3
- package/README.md +17 -12
- package/README.ru.md +17 -12
- package/dist/src/core/constants.d.ts +1 -1
- package/dist/src/core/constants.js +1 -1
- package/dist/src/core/model/policy.js +2 -0
- package/dist/src/core/model/policy.js.map +1 -1
- package/dist/src/core/query/compare.d.ts +2 -0
- package/dist/src/core/query/compare.js +8 -0
- package/dist/src/core/query/compare.js.map +1 -0
- package/dist/src/core/query/execute.js +2 -10
- package/dist/src/core/query/execute.js.map +1 -1
- package/dist/src/core/query/filter.js +6 -5
- 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/files/disk-paths.js +1 -1
- package/dist/src/files/disk-paths.js.map +1 -1
- package/dist/src/graphql/schema.js +3 -3
- package/dist/src/graphql/schema.js.map +1 -1
- package/dist/src/openapi/document.js +3 -3
- package/dist/src/openapi/document.js.map +1 -1
- package/dist/src/rest/options.js +1 -1
- package/dist/src/rest/options.js.map +1 -1
- package/dist/src/rest/projection.js +2 -1
- package/dist/src/rest/projection.js.map +1 -1
- package/dist/src/server/bootstrap.js +51 -41
- package/dist/src/server/bootstrap.js.map +1 -1
- package/dist/src/server/input-paths.js +4 -1
- package/dist/src/server/input-paths.js.map +1 -1
- package/dist/src/server/storage-lock.d.ts +3 -0
- package/dist/src/server/storage-lock.js +116 -0
- package/dist/src/server/storage-lock.js.map +1 -0
- package/examples/schema.json +15 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.0-rc.4
|
|
4
|
+
|
|
5
|
+
- Prevent concurrent servers from writing to the same file-backed database and recover its lock after a process crash, using built-in Node.js APIs.
|
|
6
|
+
- Make range filters and sorting use the same comparison rules across REST and GraphQL.
|
|
7
|
+
- Execute key examples from both READMEs during tests to keep the documented behavior current.
|
|
8
|
+
- Add a database benchmark script for memory and file storage; runtime query behavior is unchanged by the benchmark.
|
|
9
|
+
|
|
10
|
+
## 1.0.0-rc.3
|
|
11
|
+
|
|
12
|
+
- Keep relation keys inferred from `source` in stored records while hiding them from REST, GraphQL, and OpenAPI unless declared explicitly in model `fields`.
|
|
13
|
+
- Clarified relation key selection with and without a model schema in both READMEs.
|
|
14
|
+
|
|
3
15
|
## 1.0.0-rc.2
|
|
4
16
|
|
|
5
17
|
- Added root schema `api` to select REST, GraphQL, or both for database routes, and per-model `api` selection with matching formats. Authentication and file routes remain REST endpoints; OpenAPI includes only enabled REST routes.
|
package/MIGRATION.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Migrating from 0.9.0 to 1.0.0-rc.
|
|
1
|
+
# Migrating from 0.9.0 to 1.0.0-rc.4
|
|
2
2
|
|
|
3
3
|
Version 1.0 changes configuration and request syntax. Update the server configuration and client requests together. Back up any file database, auth records, and file metadata before changing the running server.
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ Version 1.0 changes configuration and request syntax. Update the server configur
|
|
|
6
6
|
|
|
7
7
|
Declare a storage mode and use `source` for each enabled component:
|
|
8
8
|
|
|
9
|
-
| 0.9.0 | 1.0.0-rc.
|
|
9
|
+
| 0.9.0 | 1.0.0-rc.4 |
|
|
10
10
|
|---|---|
|
|
11
11
|
| `database.path` | `storage: 'file'`, `database.source` |
|
|
12
12
|
| `database.data` | `storage: 'memory'`, `database.source` |
|
|
@@ -32,7 +32,7 @@ const scope = [
|
|
|
32
32
|
const url = `/movies?${new URLSearchParams({ scope: JSON.stringify(scope) })}`;
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Without an explicit `scope`, the response contains scalar fields only. `"*": true` also selects only scalar fields that do not store relation keys. Select arrays, objects, relations, and relation keys explicitly. Related lists can have their own filters, order, and pagination. Review clients that expect embedded relations or relation keys in default responses.
|
|
35
|
+
Without an explicit `scope`, the response contains scalar fields only. `"*": true` also selects only scalar fields that do not store relation keys. Select arrays, objects, relations, and declared relation keys explicitly. Relation keys omitted from `fields` remain in the database but are unavailable in REST, GraphQL, and OpenAPI. Related lists can have their own filters, order, and pagination. Review clients that expect embedded relations or relation keys in default responses.
|
|
36
36
|
|
|
37
37
|
## Records and auth
|
|
38
38
|
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
A JSON mock server with REST, GraphQL, related records, file uploads and schema exports. Supports user login, owner and administrator permissions, record timestamps and soft deletion. Requires Node.js 22 or newer.
|
|
8
8
|
|
|
9
|
-
**Breaking changes in 1.0.0.** See the [migration guide](MIGRATION.md) when upgrading from 0.9.0. The REST `scope` wildcard selects only scalar fields that do not store relation keys. Arrays, objects, relations and
|
|
9
|
+
**Breaking changes in 1.0.0.** See the [migration guide](MIGRATION.md) when upgrading from 0.9.0. The REST `scope` wildcard selects only scalar fields that do not store relation keys. Arrays, objects, relations and explicitly declared relation keys must be selected explicitly. With auth enabled, record permissions are available through the virtual `actions` field.
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
@@ -14,7 +14,7 @@ A JSON mock server with REST, GraphQL, related records, file uploads and schema
|
|
|
14
14
|
npm install @kollors/deep-json-server@rc
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
To install this release candidate, use `@1.0.0-rc.
|
|
17
|
+
To install this release candidate, use `@1.0.0-rc.4`.
|
|
18
18
|
|
|
19
19
|
## Quick start
|
|
20
20
|
|
|
@@ -100,6 +100,7 @@ export default {
|
|
|
100
100
|
|
|
101
101
|
Set the root `api` in `schema.json`:
|
|
102
102
|
|
|
103
|
+
<!-- tested-example: graphql-only-schema -->
|
|
103
104
|
```json
|
|
104
105
|
{
|
|
105
106
|
"api": ["graphql"],
|
|
@@ -131,6 +132,7 @@ Address precedence: CLI → configuration → `HOST`/`PORT` → defaults. Withou
|
|
|
131
132
|
|
|
132
133
|
Examples: [database](examples/database.json), [model schema](examples/schema.json), [configuration](examples/server.config.js).
|
|
133
134
|
|
|
135
|
+
<!-- tested-example: implicit-relation-schema -->
|
|
134
136
|
```json
|
|
135
137
|
{
|
|
136
138
|
"api": ["rest", "graphql"],
|
|
@@ -188,7 +190,7 @@ An excluded model remains part of the database schema and its stored records are
|
|
|
188
190
|
| OpenAPI 3.0.3 export | Available | Error when requested |
|
|
189
191
|
| GraphQL SDL / API | Available | Error when requested |
|
|
190
192
|
|
|
191
|
-
Explicit schemas are strict: undeclared fields and collections are rejected, except storage keys inferred from relations. Existing data is validated on startup. Generation uses the model definitions.
|
|
193
|
+
Explicit schemas are strict: undeclared fields and collections are rejected, except storage keys inferred from relations. Inferred keys remain in stored records but are not API fields. Existing data is validated on startup. Generation uses the model definitions.
|
|
192
194
|
|
|
193
195
|
Schemaless REST generates an `id` and preserves arbitrary JSON fields. Newly inferred relations are available to subsequent reads and writes without restarting the server. Filters and individual field selections use identifier-style names. `scope=[{"*":true}]` returns top-level JSON scalars; arrays and objects must be selected by name. Fields with mixed value types can be read explicitly, but filtering, ordering and paging heterogeneous lists require an explicit schema.
|
|
194
196
|
|
|
@@ -237,11 +239,11 @@ Objects used in GraphQL must have at least one field visible in responses; REST
|
|
|
237
239
|
|
|
238
240
|
`Genre` returns an object; `Genre[]` returns a list. `source` defaults to the current model's primary key, `target` to the target model's primary key. These defaults also apply to nested relations. Paths start at the root of their respective records: in this example, `actors.genreIds` contains the current actor's genre keys.
|
|
239
241
|
|
|
240
|
-
Relation keys
|
|
242
|
+
Relation keys remain in the database even when they are absent from `fields`. A `source` field pointing to a target primary key can be omitted: the server infers an array of keys for a list relation or a scalar key for a single relation. An inferred key is internal: REST and GraphQL cannot read, select, filter, sort or write it directly, and OpenAPI does not describe it. The relation itself remains available. Declare the key in `fields`, for example `"countryId": { "type": "string" }`, to expose it in the APIs. An ambiguous mapping also requires an explicit declaration.
|
|
241
243
|
|
|
242
244
|
Reverse example: `User.movies = {"type":"Movie[]","target":"actors.userId"}`. A movie is returned once even if several actors match. A single relation that matches multiple records causes an error.
|
|
243
245
|
|
|
244
|
-
Every supplied
|
|
246
|
+
Every directly supplied, explicitly declared relation key must point to an existing record. `required: true` on a relation requires at least one target before response filtering/pagination. Reverse relations using the primary key as `source` may be empty unless required. Missing single relations return `null`.
|
|
245
247
|
|
|
246
248
|
`onDelete` describes what happens **when a target record is deleted**:
|
|
247
249
|
|
|
@@ -372,7 +374,7 @@ Primitive arrays are returned as plain arrays. Every object list accepts optiona
|
|
|
372
374
|
|
|
373
375
|
Use `page` and `pageSize` in `pager`. The default is the first page with the size from `server.pageSize`. Both values must be positive integers; `pageSize` is limited by `server.maxPageSize`. Out-of-range pages return empty `data` with the total matching record count in `total`.
|
|
374
376
|
|
|
375
|
-
`where` uses field operators `eq`, `ne`, `in`, string `contains`/`startsWith`/`endsWith`, and comparisons `gt`, `gte`, `lt`, `lte`. Conditions in the same object must all match. `and` and `or` take arrays of conditions; `not` takes one condition and can also be used inside a field filter. Arrays support `some`, `every`, `none`; primitive arrays also support `contains`, `in`. String `contains`, `startsWith` and `endsWith` ignore case; `eq`, `ne` and `in` compare exact values. A field condition is an object containing an operator, such as `{ "id": { "eq": "1" } }`.
|
|
377
|
+
`where` uses field operators `eq`, `ne`, `in`, string `contains`/`startsWith`/`endsWith`, and comparisons `gt`, `gte`, `lt`, `lte`. Conditions in the same object must all match. `and` and `or` take arrays of conditions; `not` takes one condition and can also be used inside a field filter. Arrays support `some`, `every`, `none`; primitive arrays also support `contains`, `in`. String `contains`, `startsWith` and `endsWith` ignore case; `eq`, `ne` and `in` compare exact values. For strings, `gt`, `gte`, `lt` and `lte` use the same case-insensitive, numeric-aware order as sorting. A field condition is an object containing an operator, such as `{ "id": { "eq": "1" } }`.
|
|
376
378
|
|
|
377
379
|
```json
|
|
378
380
|
{
|
|
@@ -415,6 +417,7 @@ REST record routes accept one query parameter, `scope`, containing a JSON array
|
|
|
415
417
|
|
|
416
418
|
Select users and their movies with independent ordering and pagination:
|
|
417
419
|
|
|
420
|
+
<!-- tested-example: rest-user-list -->
|
|
418
421
|
```js
|
|
419
422
|
const scope = [
|
|
420
423
|
{
|
|
@@ -435,10 +438,11 @@ const params = new URLSearchParams({ scope: JSON.stringify(scope) });
|
|
|
435
438
|
const response = await fetch(`/users?${params}`);
|
|
436
439
|
```
|
|
437
440
|
|
|
438
|
-
Select scalars and primitive arrays with `true`, and objects or relations with their own scope arrays. Without arguments, the array contains only the fields object. `"*": true` includes only scalar fields of the current model that do not store relation keys. Arrays, objects, relations, their keys and `writeOnly` fields are not included by the wildcard.
|
|
441
|
+
Select scalars and primitive arrays with `true`, and objects or relations with their own scope arrays. Without arguments, the array contains only the fields object. `"*": true` includes only scalar fields of the current model that do not store relation keys. Arrays, objects, relations, their keys and `writeOnly` fields are not included by the wildcard. With a schema, a relation key can be selected as `{ "*": true, "countryId": true }` only if it is declared in `fields`. Without a schema, a key present in stored records can be selected explicitly even if omitted from `*`; the wildcard omits it when the server infers a relation from its name and an existing collection.
|
|
439
442
|
|
|
440
443
|
For example, select a movie's own fields, its actors' users and sorted genres:
|
|
441
444
|
|
|
445
|
+
<!-- tested-example: rest-movie-scope -->
|
|
442
446
|
```json
|
|
443
447
|
[
|
|
444
448
|
{
|
|
@@ -462,7 +466,7 @@ Arguments are available only on lists. A list can instead use `{ "union": [scope
|
|
|
462
466
|
|
|
463
467
|
### Nested writes
|
|
464
468
|
|
|
465
|
-
|
|
469
|
+
Explicitly declared storage keys such as `genreIds: ["1"]` only set a relation. Relation fields also accept records to create or update:
|
|
466
470
|
|
|
467
471
|
```http
|
|
468
472
|
PATCH /movies/1
|
|
@@ -492,7 +496,7 @@ The key name and type follow the target model. An object containing only a key s
|
|
|
492
496
|
|
|
493
497
|
A supplied list replaces the relation's membership. PATCH preserves omitted relations; PUT clears omitted writable links. `[]` clears a list and `null` clears a nullable single relation. Removing a link does not delete the related record. Required relations must remain populated.
|
|
494
498
|
|
|
495
|
-
|
|
499
|
+
When the storage key is declared in `fields`, use either the relation field or its key in an object, for example `genres` or `genreIds`. Supplying both fields returns `400 INVALID_INPUT`, even when their key sets match:
|
|
496
500
|
|
|
497
501
|
```json
|
|
498
502
|
{
|
|
@@ -501,11 +505,11 @@ Use either the relation field or its storage key in an object, for example `genr
|
|
|
501
505
|
}
|
|
502
506
|
```
|
|
503
507
|
|
|
504
|
-
The server rejects both fields together and rolls back the operation. Relation fields accept objects only;
|
|
508
|
+
The server rejects both fields together and rolls back the operation. Relation fields accept objects only; a declared key such as `genreIds` changes links without creating or updating related records. Reverse relations update the target key. If a target path crosses an array and the server cannot identify one element to attach, provide the array with the intended keys explicitly. Protected keys cannot be changed.
|
|
505
509
|
|
|
506
510
|
All nested changes belong to the main record's transaction. A validation error, missing record or invalid response selection rolls back the entire operation. Updating a shared record affects every record linked to it.
|
|
507
511
|
|
|
508
|
-
GraphQL accepts typed objects in relation fields. To change only the links in a replace mutation, use storage
|
|
512
|
+
GraphQL accepts typed objects in relation fields. To change only the links in a replace mutation, use a declared storage key such as `genreIds`. For example:
|
|
509
513
|
|
|
510
514
|
```graphql
|
|
511
515
|
mutation {
|
|
@@ -530,6 +534,7 @@ npx deep-json-server server.config.js
|
|
|
530
534
|
|
|
531
535
|
Send requests to `/graphql` using POST with `Content-Type: application/json` and a body of `{ "query": "…", "variables": {} }`. Change the path through `graphql.endpoint`.
|
|
532
536
|
|
|
537
|
+
<!-- tested-example: graphql-user-list -->
|
|
533
538
|
```graphql
|
|
534
539
|
query {
|
|
535
540
|
userList(
|
|
@@ -827,7 +832,7 @@ Content-Type: application/json
|
|
|
827
832
|
|
|
828
833
|
In disk mode, the binary is stored at `<files.source>/<directory>/<name>`. Metadata defaults to `<files.source>/.files.json`; set `files.metadata` for another location. Directories and the metadata file are created when needed.
|
|
829
834
|
|
|
830
|
-
Use one server process per disk database and file store. Stop
|
|
835
|
+
Use one server process per disk database and file store. A second server using the same database file fails at startup; closing the first server releases its lock, and a lock left by a crashed process is recovered on the next start. Stop the server before editing stored files or metadata manually. Storage paths cannot contain symbolic links. Uploads and renames cannot overwrite the database, its lock, counters, schema, auth users, loaded configuration or metadata file.
|
|
831
836
|
|
|
832
837
|
Send the file as a binary request body. In a browser, use `xhr.send(file)` and track progress through `XMLHttpRequest.upload.onprogress`. The default maximum size is 100 MiB and can be changed through `server.maxFileSize`. Missing or unsafe headers and paths return `400`, an exceeded limit returns `413`, and a missing, malformed, or Fastify-unsupported `Content-Type` returns `400` or `415`, depending on which validation stage rejects it.
|
|
833
838
|
|
package/README.ru.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
JSON-сервер для создания тестового API с REST, GraphQL, связями между записями, загрузкой файлов и экспортом схем. Поддерживает вход пользователей, права владельца и администратора, даты записей и мягкое удаление. Требуется Node.js 22 или новее.
|
|
8
8
|
|
|
9
|
-
**Изменения в 1.0.0, нарушающие совместимость.** При переходе с 0.9.0 воспользуйтесь [инструкцией по миграции](MIGRATION.md). `*` в REST `scope` выбирает только скалярные поля, которые не хранят ключи связей. Массивы, объекты, связи и
|
|
9
|
+
**Изменения в 1.0.0, нарушающие совместимость.** При переходе с 0.9.0 воспользуйтесь [инструкцией по миграции](MIGRATION.md). `*` в REST `scope` выбирает только скалярные поля, которые не хранят ключи связей. Массивы, объекты, связи и явно объявленные ключи связей нужно указывать в выборе полей. При включённой аутентификации права на запись доступны через виртуальное поле `actions`.
|
|
10
10
|
|
|
11
11
|
## Установка
|
|
12
12
|
|
|
@@ -14,7 +14,7 @@ JSON-сервер для создания тестового API с REST, GraphQ
|
|
|
14
14
|
npm install @kollors/deep-json-server@rc
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Для установки этого релиз-кандидата укажите `@1.0.0-rc.
|
|
17
|
+
Для установки этого релиз-кандидата укажите `@1.0.0-rc.4`.
|
|
18
18
|
|
|
19
19
|
## Быстрый старт
|
|
20
20
|
|
|
@@ -100,6 +100,7 @@ export default {
|
|
|
100
100
|
|
|
101
101
|
В корне `schema.json` задайте `api`:
|
|
102
102
|
|
|
103
|
+
<!-- tested-example: graphql-only-schema -->
|
|
103
104
|
```json
|
|
104
105
|
{
|
|
105
106
|
"api": ["graphql"],
|
|
@@ -131,6 +132,7 @@ export default {
|
|
|
131
132
|
|
|
132
133
|
Примеры: [база данных](examples/database.json), [схема моделей](examples/schema.json), [конфигурация](examples/server.config.js).
|
|
133
134
|
|
|
135
|
+
<!-- tested-example: implicit-relation-schema -->
|
|
134
136
|
```json
|
|
135
137
|
{
|
|
136
138
|
"api": ["rest", "graphql"],
|
|
@@ -188,7 +190,7 @@ export default {
|
|
|
188
190
|
| Экспорт OpenAPI 3.0.3 | Доступен | Ошибка при запросе экспорта |
|
|
189
191
|
| GraphQL SDL / API | Доступен | Ошибка при запросе |
|
|
190
192
|
|
|
191
|
-
При явной схеме неизвестные поля и коллекции запрещены. Исключение — хранимые ключи, выведенные из связей. Исходная база проверяется при загрузке. Генерация использует описание моделей.
|
|
193
|
+
При явной схеме неизвестные поля и коллекции запрещены. Исключение — хранимые ключи, выведенные из связей. Они остаются в записях базы, но не становятся полями API. Исходная база проверяется при загрузке. Генерация использует описание моделей.
|
|
192
194
|
|
|
193
195
|
REST без схемы создаёт ключ `id` и сохраняет произвольные JSON-поля. Новые выведенные связи доступны для последующего чтения и записи без перезапуска сервера. Для фильтров и выбора отдельных полей используются имена в формате идентификаторов. `scope=[{"*":true}]` возвращает скаляры верхнего уровня; массивы и объекты выбираются по имени. Поля с разными типами значений можно запросить явно, но фильтрация, сортировка и пагинация неоднородных списков требуют явной схемы.
|
|
194
196
|
|
|
@@ -237,11 +239,11 @@ REST без схемы создаёт ключ `id` и сохраняет про
|
|
|
237
239
|
|
|
238
240
|
`Genre` возвращает объект, `Genre[]` — список. По умолчанию `source` указывает на первичный ключ текущей модели, `target` — целевой. Это правило действует и для вложенных связей. Пути задаются от корня соответствующей записи: в примере `actors.genreIds` содержит ключи жанров текущего актёра.
|
|
239
241
|
|
|
240
|
-
Ключи связей
|
|
242
|
+
Ключи связей остаются в базе, даже если их нет в `fields`. Если поле `source` ссылается на первичный ключ целевой модели, его можно не объявлять отдельно: сервер выведет массив ключей для множественной связи или одно значение для одиночной. Такой ключ остаётся внутренним: REST и GraphQL не позволяют читать, выбирать, фильтровать, сортировать или записывать его напрямую, а OpenAPI его не описывает. Сама связь при этом доступна. Чтобы открыть ключ в API, объявите его в `fields`, например `"countryId": { "type": "string" }`. Неоднозначное сопоставление тоже требует явного объявления.
|
|
241
243
|
|
|
242
244
|
Обратная связь: `User.movies = {"type":"Movie[]","target":"actors.userId"}`. Фильм возвращается один раз, даже если совпало несколько актёров. Несколько совпадений для одиночной связи — ошибка.
|
|
243
245
|
|
|
244
|
-
Каждый переданный ключ
|
|
246
|
+
Каждый переданный напрямую и явно объявленный ключ связи должен указывать на существующую запись. `required: true` у связи требует хотя бы одну связанную запись до фильтрации и пагинации ответа. Обратная связь с первичным ключом в `source` может быть пустой, если не объявлена обязательной. Отсутствующая одиночная связь возвращает `null`.
|
|
245
247
|
|
|
246
248
|
`onDelete` срабатывает **при удалении целевой записи**:
|
|
247
249
|
|
|
@@ -372,7 +374,7 @@ npx deep-json-server examples/server.config.js
|
|
|
372
374
|
|
|
373
375
|
В `pager` задаются `page` и `pageSize`. По умолчанию возвращается первая страница с размером из `server.pageSize`. Оба значения должны быть положительными целыми числами; `pageSize` ограничен `server.maxPageSize`. За пределами списка возвращается пустой `data` с общим числом найденных записей в `total`.
|
|
374
376
|
|
|
375
|
-
Фильтры: `eq`, `ne`, `in`; для строк `contains`, `startsWith`, `endsWith`; сравнения `gt`, `gte`, `lt`, `lte`. Несколько условий в одном объекте должны выполняться одновременно. `and` и `or` принимают массив условий, `not` — одно условие; `not` также можно использовать внутри фильтра поля. У массивов есть `some`, `every`, `none`; у примитивных массивов также `contains`, `in`. `contains`, `startsWith` и `endsWith` для строк не учитывают регистр; `eq`, `ne` и `in` сравнивают точные значения. Условие поля задаётся объектом с оператором, например `{ "id": { "eq": "1" } }`.
|
|
377
|
+
Фильтры: `eq`, `ne`, `in`; для строк `contains`, `startsWith`, `endsWith`; сравнения `gt`, `gte`, `lt`, `lte`. Несколько условий в одном объекте должны выполняться одновременно. `and` и `or` принимают массив условий, `not` — одно условие; `not` также можно использовать внутри фильтра поля. У массивов есть `some`, `every`, `none`; у примитивных массивов также `contains`, `in`. `contains`, `startsWith` и `endsWith` для строк не учитывают регистр; `eq`, `ne` и `in` сравнивают точные значения. Для строк `gt`, `gte`, `lt` и `lte` используют тот же порядок, что сортировка: без учёта регистра и с числовым сравнением фрагментов строки. Условие поля задаётся объектом с оператором, например `{ "id": { "eq": "1" } }`.
|
|
376
378
|
|
|
377
379
|
```json
|
|
378
380
|
{
|
|
@@ -415,6 +417,7 @@ POST возвращает созданную запись со статусом
|
|
|
415
417
|
|
|
416
418
|
Пример выбора пользователей и их фильмов с отдельной сортировкой и пагинацией:
|
|
417
419
|
|
|
420
|
+
<!-- tested-example: rest-user-list -->
|
|
418
421
|
```js
|
|
419
422
|
const scope = [
|
|
420
423
|
{
|
|
@@ -435,10 +438,11 @@ const params = new URLSearchParams({ scope: JSON.stringify(scope) });
|
|
|
435
438
|
const response = await fetch(`/users?${params}`);
|
|
436
439
|
```
|
|
437
440
|
|
|
438
|
-
Скаляры и массивы примитивов выбираются через `true`, объекты и связи — через свой массив `scope`. Если аргументы не нужны, в массиве остаётся только объект полей. `"*": true` включает только скалярные поля текущей модели, которые не хранят ключи связей. Массивы, объекты, связи, их ключи и поля `writeOnly` в него не входят.
|
|
441
|
+
Скаляры и массивы примитивов выбираются через `true`, объекты и связи — через свой массив `scope`. Если аргументы не нужны, в массиве остаётся только объект полей. `"*": true` включает только скалярные поля текущей модели, которые не хранят ключи связей. Массивы, объекты, связи, их ключи и поля `writeOnly` в него не входят. Со схемой ключ связи можно выбрать через `{ "*": true, "countryId": true }`, только если он объявлен в `fields`. Без схемы ключ, присутствующий в записях базы, можно выбрать явно, даже если его нет в `*`; из `*` он исключается, когда сервер выводит связь по имени ключа и существующей коллекции.
|
|
439
442
|
|
|
440
443
|
Например, собственные поля фильма, пользователи актёров и отсортированные жанры:
|
|
441
444
|
|
|
445
|
+
<!-- tested-example: rest-movie-scope -->
|
|
442
446
|
```json
|
|
443
447
|
[
|
|
444
448
|
{
|
|
@@ -462,7 +466,7 @@ const response = await fetch(`/users?${params}`);
|
|
|
462
466
|
|
|
463
467
|
### Вложенная запись
|
|
464
468
|
|
|
465
|
-
|
|
469
|
+
Явно объявленные поля ключей, например `genreIds: ["1"]`, только задают связь. В поля связей можно передавать записи для создания или обновления:
|
|
466
470
|
|
|
467
471
|
```http
|
|
468
472
|
PATCH /movies/1
|
|
@@ -492,7 +496,7 @@ Content-Type: application/json
|
|
|
492
496
|
|
|
493
497
|
Переданный список заменяет состав связи. PATCH сохраняет пропущенные связи, PUT очищает пропущенные связи, ключи которых доступны для записи. `[]` очищает список, `null` — одиночную связь с разрешённым `nullable`. Разрыв связи не удаляет связанную запись. Обязательные связи должны оставаться заполненными.
|
|
494
498
|
|
|
495
|
-
|
|
499
|
+
Если хранимый ключ объявлен в `fields`, в одном объекте указывайте либо связь, либо её ключ: например, `genres` или `genreIds`. Одновременная передача обоих полей возвращает `400 INVALID_INPUT`, даже если наборы ключей совпадают:
|
|
496
500
|
|
|
497
501
|
```json
|
|
498
502
|
{
|
|
@@ -501,11 +505,11 @@ Content-Type: application/json
|
|
|
501
505
|
}
|
|
502
506
|
```
|
|
503
507
|
|
|
504
|
-
Сервер не выбирает приоритет и не объединяет значения; вся операция отменяется. Поле связи принимает только объекты; для изменения одних ссылок без создания и обновления связанных записей используйте `genreIds`. Для обратной связи сервер меняет целевой ключ. Если путь проходит через массив и нельзя однозначно выбрать элемент для связи, передайте массив с нужными ключами явно. Защищённые ключи изменять нельзя.
|
|
508
|
+
Сервер не выбирает приоритет и не объединяет значения; вся операция отменяется. Поле связи принимает только объекты; для изменения одних ссылок без создания и обновления связанных записей используйте объявленный ключ, например `genreIds`. Для обратной связи сервер меняет целевой ключ. Если путь проходит через массив и нельзя однозначно выбрать элемент для связи, передайте массив с нужными ключами явно. Защищённые ключи изменять нельзя.
|
|
505
509
|
|
|
506
510
|
Все вложенные изменения входят в транзакцию основной записи. Ошибка проверки, отсутствующая запись или неверный выбор полей ответа отменяет всю операцию. Изменения общей записи видны всем, кто с ней связан.
|
|
507
511
|
|
|
508
|
-
GraphQL принимает в полях связей типизированные объекты. Чтобы при замене изменить только связи, используйте поля ключей, например `genreIds`. Пример:
|
|
512
|
+
GraphQL принимает в полях связей типизированные объекты. Чтобы при замене изменить только связи, используйте объявленные поля ключей, например `genreIds`. Пример:
|
|
509
513
|
|
|
510
514
|
```graphql
|
|
511
515
|
mutation {
|
|
@@ -530,6 +534,7 @@ npx deep-json-server server.config.js
|
|
|
530
534
|
|
|
531
535
|
Отправляйте запросы на `/graphql` методом POST с `Content-Type: application/json` и телом `{ "query": "…", "variables": {} }`. Путь можно изменить через `graphql.endpoint`.
|
|
532
536
|
|
|
537
|
+
<!-- tested-example: graphql-user-list -->
|
|
533
538
|
```graphql
|
|
534
539
|
query {
|
|
535
540
|
userList(
|
|
@@ -827,7 +832,7 @@ Content-Type: application/json
|
|
|
827
832
|
|
|
828
833
|
При хранении на диске бинарный файл находится по пути `<files.source>/<directory>/<name>`. Метаданные по умолчанию хранятся в `<files.source>/.files.json`; другой путь можно задать через `files.metadata`. Директории и файл метаданных создаются по мере необходимости.
|
|
829
834
|
|
|
830
|
-
Используйте один процесс сервера для дисковой базы и файлового хранилища. Перед ручным изменением файлов или метаданных остановите
|
|
835
|
+
Используйте один процесс сервера для дисковой базы и файлового хранилища. Второй сервер с тем же файлом базы не запустится; закрытие первого освобождает блокировку, а после аварийного завершения она снимается при следующем запуске. Перед ручным изменением файлов или метаданных остановите сервер. Пути в хранилище не могут содержать символические ссылки. Загрузка и переименование не могут перезаписать базу, её блокировку, счётчики, схему, учётные записи auth, загруженную конфигурацию или файл метаданных.
|
|
831
836
|
|
|
832
837
|
Отправляйте файл как бинарное тело запроса. В браузере для этого можно использовать `xhr.send(file)`, а прогресс отслеживать через `XMLHttpRequest.upload.onprogress`. Максимальный размер по умолчанию равен 100 МиБ и настраивается через `server.maxFileSize`. Отсутствующие или небезопасные заголовки и пути возвращают `400`, превышение лимита — `413`, а отсутствующий, некорректный или не поддерживаемый Fastify `Content-Type` — `400` либо `415` в зависимости от этапа проверки.
|
|
833
838
|
|
|
@@ -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-rc.
|
|
6
|
+
export declare const VERSION = "1.0.0-rc.4";
|
|
@@ -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-rc.
|
|
6
|
+
export const VERSION = '1.0.0-rc.4';
|
|
7
7
|
//# sourceMappingURL=constants.js.map
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* @example writable({ readOnly: true, … }, 'update') → false.
|
|
3
3
|
*/
|
|
4
4
|
export function writable(node, mode, relations = false) {
|
|
5
|
+
if (node.implicit && mode !== 'stored')
|
|
6
|
+
return false;
|
|
5
7
|
if (node.relation)
|
|
6
8
|
return relations;
|
|
7
9
|
if (node.generated || node.readOnly || (node.primary && mode !== 'create'))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../../src/core/model/policy.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAU,EAAE,IAAe,EAAE,SAAS,GAAG,KAAK;IACrE,IAAI,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IACpC,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,KAAK,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IACzF,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;AACvH,CAAC;AACD;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,KAAwB,EAAE,GAAmC;IACrF,IAAI,CAAC,KAAK,EAAE,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,oCAAoC,CAAC,CAAC;IAClF,MAAM,MAAM,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;IAChD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;IAC9G,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACvE,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;YAC7C,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,oBAAoB,GAAG,EAAE,CAAC,CAAC;AAC7J,CAAC;AACD;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU,EAAE,IAAe,EAAE,IAAI,GAAG,KAAK,EAAE,SAAS,GAAG,KAAK;IACxF,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC;AACnJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../../src/core/model/policy.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAU,EAAE,IAAe,EAAE,SAAS,GAAG,KAAK;IACrE,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACrD,IAAI,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IACpC,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,KAAK,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IACzF,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;AACvH,CAAC;AACD;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,KAAwB,EAAE,GAAmC;IACrF,IAAI,CAAC,KAAK,EAAE,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,oCAAoC,CAAC,CAAC;IAClF,MAAM,MAAM,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;IAChD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;IAC9G,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACvE,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;YAC7C,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,oBAAoB,GAAG,EAAE,CAAC,CAAC;AAC7J,CAAC;AACD;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU,EAAE,IAAe,EAAE,IAAI,GAAG,KAAK,EAAE,SAAS,GAAG,KAAK;IACxF,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC;AACnJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const collator = new Intl.Collator('en', { numeric: true, sensitivity: 'base' });
|
|
2
|
+
/** Задаёт один порядок строк и чисел для фильтров и сортировки. */
|
|
3
|
+
export function compareValues(left, right) {
|
|
4
|
+
if (typeof left === 'number' && typeof right === 'number')
|
|
5
|
+
return left - right;
|
|
6
|
+
return collator.compare(String(left), String(right));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=compare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../../../../src/core/query/compare.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;AAEjF,mEAAmE;AACnE,MAAM,UAAU,aAAa,CAAC,IAAqB,EAAE,KAAsB;IACzE,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,GAAG,KAAK,CAAC;IAC/E,OAAO,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readPath } from '../model/tree.js';
|
|
2
2
|
import { isRef, resolveField } from '../records.js';
|
|
3
3
|
import { hasOnlyKeys, isObject } from '../utils.js';
|
|
4
|
+
import { compareValues } from './compare.js';
|
|
4
5
|
import { compileWhere } from './filter.js';
|
|
5
6
|
import { badQuery, nodeAt } from './options.js';
|
|
6
7
|
/** Создаёт представление записи для фильтра, скрывая поля только для записи.
|
|
@@ -19,7 +20,6 @@ function filterView(ref) {
|
|
|
19
20
|
});
|
|
20
21
|
return value;
|
|
21
22
|
}
|
|
22
|
-
const collator = new Intl.Collator('en', { numeric: true, sensitivity: 'base' });
|
|
23
23
|
/** Проверяет аргументы списка и превращает их в готовый план выполнения.
|
|
24
24
|
* @example { pager: { page: 2, pageSize: 5 } } → план с page: 2 и pageSize: 5.
|
|
25
25
|
*/
|
|
@@ -63,15 +63,7 @@ export function executeList(records, prepared) {
|
|
|
63
63
|
for (const [index, rule] of rules.entries()) {
|
|
64
64
|
const left = leftEntry.keys[index];
|
|
65
65
|
const right = rightEntry.keys[index];
|
|
66
|
-
const comparison = left == null && right == null
|
|
67
|
-
? 0
|
|
68
|
-
: left == null
|
|
69
|
-
? 1
|
|
70
|
-
: right == null
|
|
71
|
-
? -1
|
|
72
|
-
: typeof left === 'number' && typeof right === 'number'
|
|
73
|
-
? left - right
|
|
74
|
-
: collator.compare(String(left), String(right));
|
|
66
|
+
const comparison = left == null && right == null ? 0 : left == null ? 1 : right == null ? -1 : compareValues(left, right);
|
|
75
67
|
if (comparison)
|
|
76
68
|
return rule.direction === 'DESC' ? -comparison : comparison;
|
|
77
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../../src/core/query/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,KAAK,EAAY,YAAY,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,YAAY,EAAkB,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAoB,MAAM,EAAE,MAAM,cAAc,CAAC;AAclE;;GAEG;AACH,SAAS,UAAU,CAAC,GAAQ;IAC1B,MAAM,KAAK,GAA4B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO;YAClC,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE;gBACjC,UAAU,EAAE,IAAI;gBAChB,GAAG,EAAE,GAAG,EAAE;oBACR,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;oBAC5C,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBACxI,CAAC;aACF,CAAC,CAAC;IACP,OAAO,KAAK,CAAC;AACf,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../../src/core/query/execute.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mentionsDeletedAt } from '../lifecycle/options.js';
|
|
2
2
|
import { isEqual, isObject } from '../utils.js';
|
|
3
|
+
import { compareValues } from './compare.js';
|
|
3
4
|
import { operatorsFor } from './contract.js';
|
|
4
5
|
import { badQuery, childrenOf } from './options.js';
|
|
5
6
|
const comparable = (value) => typeof value === 'string' || typeof value === 'number';
|
|
@@ -56,13 +57,13 @@ function condition(node, input, depth) {
|
|
|
56
57
|
case 'endsWith':
|
|
57
58
|
return (field) => typeof field === 'string' && field.toLowerCase().endsWith(String(value).toLowerCase());
|
|
58
59
|
case 'gt':
|
|
59
|
-
return (field) => comparable(field) && comparable(value) && field >
|
|
60
|
+
return (field) => comparable(field) && comparable(value) && compareValues(field, value) > 0;
|
|
60
61
|
case 'gte':
|
|
61
|
-
return (field) => comparable(field) && comparable(value) && field >=
|
|
62
|
+
return (field) => comparable(field) && comparable(value) && compareValues(field, value) >= 0;
|
|
62
63
|
case 'lt':
|
|
63
|
-
return (field) => comparable(field) && comparable(value) && field <
|
|
64
|
+
return (field) => comparable(field) && comparable(value) && compareValues(field, value) < 0;
|
|
64
65
|
default:
|
|
65
|
-
return (field) => comparable(field) && comparable(value) && field <=
|
|
66
|
+
return (field) => comparable(field) && comparable(value) && compareValues(field, value) <= 0;
|
|
66
67
|
}
|
|
67
68
|
});
|
|
68
69
|
return (value) => predicates.every((predicate) => predicate(value));
|
|
@@ -85,7 +86,7 @@ export function compileWhere(node, input, depth = 0, defaults = true) {
|
|
|
85
86
|
return (field) => !nested(field);
|
|
86
87
|
}
|
|
87
88
|
const child = childrenOf(node)[key];
|
|
88
|
-
if (!Object.hasOwn(childrenOf(node), key) || !child || child.writeOnly || child.virtual)
|
|
89
|
+
if (!Object.hasOwn(childrenOf(node), key) || !child || child.writeOnly || child.virtual || child.implicit)
|
|
89
90
|
badQuery(`Unknown or inaccessible filter field ${key}`);
|
|
90
91
|
if (child.mixed)
|
|
91
92
|
badQuery(`Field ${key} has inconsistent types; provide an explicit schema`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../../../src/core/query/filter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../../../src/core/query/filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ export function nodeAt(node, path, scalarOnly = false) {
|
|
|
20
20
|
const parts = pathParts(path);
|
|
21
21
|
parts.forEach((part, index) => {
|
|
22
22
|
const child = childrenOf(current)[part];
|
|
23
|
-
if (!Object.hasOwn(childrenOf(current), part) || !child || child.writeOnly || child.virtual)
|
|
23
|
+
if (!Object.hasOwn(childrenOf(current), part) || !child || child.writeOnly || child.virtual || child.implicit)
|
|
24
24
|
badQuery(`Unknown or inaccessible field ${path}`);
|
|
25
25
|
if (child.mixed)
|
|
26
26
|
badQuery(`Field ${path} has inconsistent types; provide an explicit schema`);
|
|
@@ -35,7 +35,7 @@ export function nodeAt(node, path, scalarOnly = false) {
|
|
|
35
35
|
*/
|
|
36
36
|
export function sortableFields(node, prefix = '') {
|
|
37
37
|
return Object.entries(childrenOf(node)).flatMap(([key, child]) => {
|
|
38
|
-
if (child.writeOnly || child.virtual || child.mixed || child.many || child.relation)
|
|
38
|
+
if (child.writeOnly || child.virtual || child.implicit || child.mixed || child.many || child.relation)
|
|
39
39
|
return [];
|
|
40
40
|
const path = prefix + key;
|
|
41
41
|
return child.base === 'object' ? sortableFields(child, `${path}.`) : [path];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../../src/core/query/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAe7C;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,MAAM,WAAW,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AACD;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,OAAO,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;AACvD,CAAC;AACD;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,IAAU,EAAE,IAAY,EAAE,UAAU,GAAG,KAAK;IACjE,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC5B,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO;YAAE,QAAQ,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../../src/core/query/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAe7C;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,MAAM,WAAW,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AACD;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,OAAO,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;AACvD,CAAC;AACD;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,IAAU,EAAE,IAAY,EAAE,UAAU,GAAG,KAAK;IACjE,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC5B,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ;YAAE,QAAQ,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;QACjK,IAAI,KAAK,CAAC,KAAK;YAAE,QAAQ,CAAC,SAAS,IAAI,qDAAqD,CAAC,CAAC;QAC9F,IAAI,UAAU,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;YAAE,QAAQ,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC;QAChJ,OAAO,GAAG,KAAK,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AACD;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAU,EAAE,MAAM,GAAG,EAAE;IACpD,OAAO,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC/D,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ;YAAE,OAAO,EAAE,CAAC;QACjH,MAAM,IAAI,GAAG,MAAM,GAAG,GAAG,CAAC;QAC1B,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -33,7 +33,7 @@ export async function createDiskPaths({ directory, metadata, staging, protectedP
|
|
|
33
33
|
const resolveFilePath = (path) => {
|
|
34
34
|
const filePath = resolve(directory, path);
|
|
35
35
|
const canonical = resolve(realDirectory, relative(directory, filePath));
|
|
36
|
-
if (protectedPaths.
|
|
36
|
+
if ([...protectedPaths].some((protectedPath) => isPathInside(protectedPath, canonical)))
|
|
37
37
|
throw domainError('INVALID_INPUT', 'Path is reserved for a server input file');
|
|
38
38
|
if (filePath === directory || !isPathInside(directory, filePath) || filePath === metadata || isPathInside(staging, filePath))
|
|
39
39
|
throw domainError('INVALID_INPUT', 'File path escapes the storage directory');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"disk-paths.js","sourceRoot":"","sources":["../../../src/files/disk-paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,UAAU,GAAG,KAAK,EAAE,IAAY,EAAoB,EAAE;IAC1D,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAClE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,QAAgB,EAAE,UAAkB,EAAW,EAAE;IACrE,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACpD,OAAO,YAAY,KAAK,EAAE,IAAI,CAAC,YAAY,KAAK,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;AAC7H,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,KAA4B,EAAQ,EAAE;IAC/D,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;QAAE,MAAM,WAAW,CAAC,eAAe,EAAE,mCAAmC,CAAC,CAAC;AAC/F,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAyF;IAC3K,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;IAChD,MAAM,eAAe,GAAG,CAAC,IAAY,EAAQ,EAAE;QAC7C,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,IAAI,CAAC;YAAE,MAAM,WAAW,CAAC,eAAe,EAAE,yCAAyC,CAAC,CAAC;IACxH,CAAC,CAAC;IACF,MAAM,eAAe,GAAG,CAAC,IAAY,EAAU,EAAE;QAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;QACxE,IAAI,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"disk-paths.js","sourceRoot":"","sources":["../../../src/files/disk-paths.ts"],"names":[],"mappings":"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"}
|