@kollors/deep-json-server 1.0.0-alpha.2 → 1.0.0-alpha.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/README.md +103 -19
- package/README.ru.md +103 -19
- package/dist/index.d.ts +2 -1
- package/dist/index.js.map +1 -1
- package/dist/src/cli.d.ts +2 -2
- package/dist/src/cli.js +22 -15
- package/dist/src/cli.js.map +1 -1
- package/dist/src/config.d.ts +12 -1
- package/dist/src/config.js +40 -5
- package/dist/src/config.js.map +1 -1
- package/dist/src/constants.d.ts +1 -1
- package/dist/src/constants.js +1 -1
- package/dist/src/database.d.ts +0 -1
- package/dist/src/database.js +12 -10
- package/dist/src/database.js.map +1 -1
- package/dist/src/engine.d.ts +16 -26
- package/dist/src/engine.js +36 -149
- package/dist/src/engine.js.map +1 -1
- package/dist/src/errors.d.ts +1 -1
- package/dist/src/files/contract.d.ts +0 -30
- package/dist/src/files/contract.js +6 -47
- package/dist/src/files/contract.js.map +1 -1
- package/dist/src/files/disk-store.d.ts +2 -1
- package/dist/src/files/disk-store.js +24 -14
- package/dist/src/files/disk-store.js.map +1 -1
- package/dist/src/files/http.d.ts +31 -0
- package/dist/src/files/http.js +44 -0
- package/dist/src/files/http.js.map +1 -0
- package/dist/src/files/index.d.ts +1 -1
- package/dist/src/files/index.js +1 -1
- package/dist/src/files/index.js.map +1 -1
- package/dist/src/files/memory-store.js +8 -7
- package/dist/src/files/memory-store.js.map +1 -1
- package/dist/src/files/openapi.js +2 -4
- package/dist/src/files/openapi.js.map +1 -1
- package/dist/src/files/routes.js +3 -2
- package/dist/src/files/routes.js.map +1 -1
- package/dist/src/graphql/entry.d.ts +3 -0
- package/dist/src/graphql/entry.js +3 -0
- package/dist/src/graphql/entry.js.map +1 -0
- package/dist/src/graphql/preflight.d.ts +3 -3
- package/dist/src/graphql/preflight.js +4 -2
- package/dist/src/graphql/preflight.js.map +1 -1
- package/dist/src/graphql/public.d.ts +3 -0
- package/dist/src/graphql/public.js +11 -0
- package/dist/src/graphql/public.js.map +1 -0
- package/dist/src/graphql/resolvers.d.ts +8 -0
- package/dist/src/graphql/resolvers.js +38 -0
- package/dist/src/graphql/resolvers.js.map +1 -0
- package/dist/src/graphql/routes.js +3 -4
- package/dist/src/graphql/routes.js.map +1 -1
- package/dist/src/graphql/write.d.ts +1 -0
- package/dist/src/graphql/write.js +7 -0
- package/dist/src/graphql/write.js.map +1 -0
- package/dist/src/graphql.d.ts +1 -2
- package/dist/src/graphql.js +18 -27
- package/dist/src/graphql.js.map +1 -1
- package/dist/src/http/errors.d.ts +6 -0
- package/dist/src/http/errors.js +3 -0
- package/dist/src/http/errors.js.map +1 -0
- package/dist/src/model.d.ts +6 -3
- package/dist/src/model.js +51 -14
- package/dist/src/model.js.map +1 -1
- package/dist/src/mutations/write.d.ts +25 -0
- package/dist/src/mutations/write.js +270 -0
- package/dist/src/mutations/write.js.map +1 -0
- package/dist/src/openapi/document.js +58 -12
- package/dist/src/openapi/document.js.map +1 -1
- package/dist/src/openapi/entry.d.ts +3 -0
- package/dist/src/openapi/entry.js +2 -0
- package/dist/src/openapi/entry.js.map +1 -0
- package/dist/src/openapi/helpers.d.ts +17 -0
- package/dist/src/openapi/helpers.js +4 -0
- package/dist/src/openapi/helpers.js.map +1 -0
- package/dist/src/openapi/index.js +6 -4
- package/dist/src/openapi/index.js.map +1 -1
- package/dist/src/openapi/public.d.ts +17 -0
- package/dist/src/openapi/public.js +18 -0
- package/dist/src/openapi/public.js.map +1 -0
- package/dist/src/pagination.d.ts +7 -0
- package/dist/src/pagination.js +12 -0
- package/dist/src/pagination.js.map +1 -0
- package/dist/src/paths.d.ts +6 -0
- package/dist/src/paths.js +47 -0
- package/dist/src/paths.js.map +1 -0
- package/dist/src/query/filter.d.ts +1 -2
- package/dist/src/query/filter.js +2 -0
- package/dist/src/query/filter.js.map +1 -1
- package/dist/src/query/options.js +4 -2
- package/dist/src/query/options.js.map +1 -1
- package/dist/src/records.d.ts +25 -0
- package/dist/src/records.js +50 -0
- package/dist/src/records.js.map +1 -0
- package/dist/src/relation-metadata.d.ts +0 -1
- package/dist/src/relation-metadata.js +0 -1
- package/dist/src/relation-metadata.js.map +1 -1
- package/dist/src/rest/options.d.ts +3 -3
- package/dist/src/rest/options.js +22 -52
- package/dist/src/rest/options.js.map +1 -1
- package/dist/src/rest/projection.d.ts +3 -3
- package/dist/src/rest/projection.js +11 -10
- package/dist/src/rest/projection.js.map +1 -1
- package/dist/src/rest/routes.js +6 -6
- package/dist/src/rest/routes.js.map +1 -1
- package/dist/src/schema.d.ts +6 -15
- package/dist/src/schema.js +7 -17
- package/dist/src/schema.js.map +1 -1
- package/dist/src/server/public.d.ts +3 -0
- package/dist/src/server/public.js +2 -0
- package/dist/src/server/public.js.map +1 -0
- package/dist/src/server.d.ts +3 -2
- package/dist/src/server.js +43 -36
- package/dist/src/server.js.map +1 -1
- package/dist/src/utils.d.ts +0 -7
- package/dist/src/utils.js +0 -4
- package/dist/src/utils.js.map +1 -1
- package/package.json +13 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
A JSON-backed mock server with REST, GraphQL, nested queries, binary files and schema exports. Requires Node.js 22 or newer.
|
|
6
6
|
|
|
7
|
-
**1.0.0-alpha.
|
|
7
|
+
**1.0.0-alpha.4 is a prerelease.** When upgrading from 0.x, update your model schema and query parameters using the examples below.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@ A JSON-backed mock server with REST, GraphQL, nested queries, binary files and s
|
|
|
12
12
|
npm install @kollors/deep-json-server@alpha
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
To install a specific version, use `@1.0.0-alpha.
|
|
15
|
+
To install a specific version, use `@1.0.0-alpha.4`.
|
|
16
16
|
|
|
17
17
|
## Quick start
|
|
18
18
|
|
|
@@ -51,7 +51,7 @@ The user list is available at `http://127.0.0.1:4001/users`.
|
|
|
51
51
|
| `openapi.enabled` | Enable the specification endpoint; default `false` |
|
|
52
52
|
| `openapi.endpoint` | Specification path; default `/openapi.json` |
|
|
53
53
|
| `openapi.path` | YAML export destination |
|
|
54
|
-
| `openapi.info` | Optional `title
|
|
54
|
+
| `openapi.info` | Optional metadata object: required `title` and `version`, optional `description` |
|
|
55
55
|
| `graphql.enabled` | Enable GraphQL HTTP endpoint; default `false` |
|
|
56
56
|
| `graphql.endpoint` | Endpoint path; default `/graphql` |
|
|
57
57
|
| `graphql.path` | GraphQL SDL export destination |
|
|
@@ -62,7 +62,9 @@ The user list is available at `http://127.0.0.1:4001/users`.
|
|
|
62
62
|
| `files.data` | In-memory binary files |
|
|
63
63
|
| `files.directory`, `files.metadata` | Disk storage directory and metadata JSON file; both required |
|
|
64
64
|
|
|
65
|
-
Relative paths resolve from the configuration file's directory. When passing a configuration object to `createServer()`, paths resolve from the working directory. The server works with a copy of in-memory input.
|
|
65
|
+
Relative paths resolve from the configuration file's directory. When passing a configuration object to `createServer()`, paths resolve from the working directory. The server works with a copy of in-memory input and metadata.
|
|
66
|
+
|
|
67
|
+
Set `server.port` to `0` to let the operating system choose an available port. The OpenAPI endpoint uses a relative server URL.
|
|
66
68
|
|
|
67
69
|
| CLI flag | Action |
|
|
68
70
|
|---|---|
|
|
@@ -84,7 +86,17 @@ npx deep-json-server generate graphql server.config.js
|
|
|
84
86
|
npx deep-json-server generate openapi,graphql server.config.js
|
|
85
87
|
```
|
|
86
88
|
|
|
87
|
-
The command reads `database.schema` and writes schemas to `openapi.path` and `graphql.path`.
|
|
89
|
+
The command reads `database.schema` and writes schemas to `openapi.path` and `graphql.path`. A configuration for generation only can contain:
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
export default {
|
|
93
|
+
database: { schema: './schema.json' },
|
|
94
|
+
openapi: { path: './generated/openapi.yaml' },
|
|
95
|
+
graphql: { path: './generated/schema.graphql' },
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Each format needs its own output file. The command rejects destinations that would overwrite the configuration, database, schema or file metadata.
|
|
88
100
|
|
|
89
101
|
## Model schema
|
|
90
102
|
|
|
@@ -122,7 +134,9 @@ Examples: [database](examples/database.json), [model schema](examples/schema.jso
|
|
|
122
134
|
| OpenAPI 3.0.3 export | Available | Error when requested |
|
|
123
135
|
| GraphQL SDL / API | Available | Error when requested |
|
|
124
136
|
|
|
125
|
-
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.
|
|
137
|
+
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.
|
|
138
|
+
|
|
139
|
+
Schemaless REST generates an `id` and preserves arbitrary JSON fields. Filters and individual field selections use identifier-style names; other fields are returned through `scope={"*":true}`. Fields with mixed value types can be read, but using them in `where`, `order` or `nested` requires an explicit schema.
|
|
126
140
|
|
|
127
141
|
### Fields
|
|
128
142
|
|
|
@@ -134,7 +148,7 @@ The `type` property accepts `string`, `number`, `boolean`, `object`, or a model
|
|
|
134
148
|
| `description`, `example` | Documentation and example value |
|
|
135
149
|
| `required`, `nullable` | Defaults `false`; presence and explicit null are separate |
|
|
136
150
|
| `default` | Value when omitted on create/replace; PATCH does not insert defaults |
|
|
137
|
-
| `enum` | Allowed
|
|
151
|
+
| `enum` | Allowed strings, numbers or booleans; for arrays, allowed element values |
|
|
138
152
|
| `primary` | Root primary key; mandatory, unique, non-null and immutable |
|
|
139
153
|
| `generated` | `uuid` for strings, `increment` for numbers; server supplies the value |
|
|
140
154
|
| `readOnly`, `writeOnly` | Output-only or input-only; mutually exclusive |
|
|
@@ -149,6 +163,8 @@ Each model requires exactly one primary key of type `string` or `number`, declar
|
|
|
149
163
|
|
|
150
164
|
For example, a `LocalUser` with primary key `username` and `password: {"type":"string","required":true,"writeOnly":true}` has `localUser(username: ...)` and `/localUsers/{username}`. A `writeOnly` field accepts input and is excluded from responses, `scope`, filters and ordering.
|
|
151
165
|
|
|
166
|
+
Objects used in GraphQL must have at least one field visible in responses; REST also accepts empty objects.
|
|
167
|
+
|
|
152
168
|
### Relations
|
|
153
169
|
|
|
154
170
|
```json
|
|
@@ -219,7 +235,60 @@ Root `where` selects records from the main collection. `where` inside a relation
|
|
|
219
235
|
|
|
220
236
|
The path parameter name follows the primary key. POST, PUT and PATCH accept a JSON record object. PUT replaces the record while retaining its key and server-managed fields. PATCH merges fields at the top level; supplied nested objects are replaced while preserving their read-only fields. Creation and replacement require all mandatory fields. Updates validate supplied values and the final record. Missing records return `404`; conflicts return `409`. DELETE returns the deleted record.
|
|
221
237
|
|
|
222
|
-
|
|
238
|
+
### Nested writes
|
|
239
|
+
|
|
240
|
+
Storage keys such as `genreIds: ["1"]` only set a relation. Relation fields also accept records to create or update:
|
|
241
|
+
|
|
242
|
+
```http
|
|
243
|
+
PATCH /movies/1
|
|
244
|
+
Content-Type: application/json
|
|
245
|
+
|
|
246
|
+
{
|
|
247
|
+
"actors": [
|
|
248
|
+
{
|
|
249
|
+
"userId": "1",
|
|
250
|
+
"genres": [
|
|
251
|
+
"1",
|
|
252
|
+
{ "id": "2", "name": "Updated genre" },
|
|
253
|
+
{ "name": "New genre" }
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
| Relation value | Behavior |
|
|
261
|
+
|---|---|
|
|
262
|
+
| A key, such as `"1"` | Link an existing record without changing it |
|
|
263
|
+
| An object with a primary key | PATCH updates supplied fields; PUT replaces the related record |
|
|
264
|
+
| An object without a primary key | Create a related record with defaults and a generated key |
|
|
265
|
+
|
|
266
|
+
The key name and type follow the target model. An object containing only a key still counts as an update: in PUT it must include the model's required fields. Replacement preserves primary keys, generated values and `readOnly` fields. In POST, nested objects with existing keys receive partial updates. A missing target is an error; creating a nested record without a key requires an autogenerated primary key.
|
|
267
|
+
|
|
268
|
+
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.
|
|
269
|
+
|
|
270
|
+
Use either the relation field or its storage key in an object, for example `genres` or `genreIds`. 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.
|
|
271
|
+
|
|
272
|
+
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.
|
|
273
|
+
|
|
274
|
+
GraphQL accepts typed objects in relation fields. To change only the links in a replace mutation, use storage keys such as `genreIds`. For example:
|
|
275
|
+
|
|
276
|
+
```graphql
|
|
277
|
+
mutation {
|
|
278
|
+
movieUpdate(id: "1", data: {
|
|
279
|
+
actors: [{
|
|
280
|
+
userId: "1"
|
|
281
|
+
genres: [{ id: "2", name: "Updated genre" }, { name: "New genre" }]
|
|
282
|
+
}]
|
|
283
|
+
}) {
|
|
284
|
+
actors { data { genres { data { id name } } } }
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### REST query parameters
|
|
290
|
+
|
|
291
|
+
Query parameters `where`, `order`, `pager`, `nested` and `scope` contain JSON. Example shown before URL encoding:
|
|
223
292
|
|
|
224
293
|
```text
|
|
225
294
|
GET /users?where={"fullName":{"contains":"Мира"}}&order=[{"field":"fullName","direction":"ASC"}]&pager={"page":1,"pageSize":20}
|
|
@@ -229,13 +298,27 @@ Construct encoded URLs with `URLSearchParams`:
|
|
|
229
298
|
|
|
230
299
|
```js
|
|
231
300
|
const params = new URLSearchParams({
|
|
232
|
-
scope:
|
|
301
|
+
scope: JSON.stringify({ id: true, fullName: true, movies: { id: true, title: true } }),
|
|
233
302
|
nested: JSON.stringify({ movies: { order: [{ field: 'title', direction: 'ASC' }], pager: { page: 1, pageSize: 5 } } }),
|
|
234
303
|
});
|
|
235
304
|
const response = await fetch(`/users?${params}`);
|
|
236
305
|
```
|
|
237
306
|
|
|
238
|
-
`scope
|
|
307
|
+
`scope` selects fields in the response:
|
|
308
|
+
|
|
309
|
+
```json
|
|
310
|
+
{
|
|
311
|
+
"*": true,
|
|
312
|
+
"actors": {
|
|
313
|
+
"user": { "id": true, "fullName": true },
|
|
314
|
+
"genres": { "*": true }
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
`true` includes a field; an object selects fields inside an object or relation. `"*": true` includes own fields and stored keys, except `writeOnly` fields. Relations are listed explicitly. Setting a relation to `true` selects its own fields.
|
|
320
|
+
|
|
321
|
+
Omitting `scope` selects own fields. `{}` selects no fields. Values must be `true` or nested objects; `false`, `null` and arrays return `400`. Lists retain the `{ data, total }` response structure.
|
|
239
322
|
|
|
240
323
|
`nested` maps full response paths to list options:
|
|
241
324
|
|
|
@@ -441,30 +524,31 @@ Content-Type: application/json
|
|
|
441
524
|
|
|
442
525
|
`PATCH` returns the updated metadata with status `200`; if a file already exists at the new path, the server returns `409`. `DELETE` returns `204` without a response body. A missing file returns `404` on every path-based operation. File paths in URLs are relative to `files.directory`, and all returned URLs are relative to the server origin.
|
|
443
526
|
|
|
444
|
-
In disk mode, the binary is stored at `<files.directory>/<directory>/<name>`.
|
|
527
|
+
In disk mode, the binary is stored at `<files.directory>/<directory>/<name>`. Metadata stores `directory`, `mimeType` and `name`; the server reads the size from the file and builds its URLs. Directories and the metadata file are created when needed.
|
|
528
|
+
|
|
529
|
+
Use one server process per disk database and file store. Stop it before editing stored files or metadata manually. Storage paths cannot contain symbolic links. Uploads and renames cannot overwrite the database, counters, schema, loaded configuration or metadata file.
|
|
445
530
|
|
|
446
531
|
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.
|
|
447
532
|
|
|
448
533
|
## Programmatic API
|
|
449
534
|
|
|
450
535
|
```js
|
|
451
|
-
import { createServer } from '@kollors/deep-json-server';
|
|
536
|
+
import { createServer } from '@kollors/deep-json-server/server';
|
|
452
537
|
import config from './server.config.js';
|
|
453
538
|
|
|
454
539
|
const facade = await createServer(config);
|
|
455
|
-
const openapi = await facade.openapi();
|
|
456
|
-
const sdl = await facade.graphql();
|
|
457
540
|
const server = facade.fastify();
|
|
458
541
|
await server.listen();
|
|
459
542
|
// await server.close();
|
|
460
543
|
```
|
|
461
544
|
|
|
462
|
-
The `openapi()` and `graphql()` methods return schemas. `fastify()` returns the server instance for configuration and startup. The database and enabled services initialize on `ready()`, `listen()` or the first `inject()`; initialization errors stop startup. Override server features with `createServer(config, { files: false, graphql: true, openapi: true })`.
|
|
545
|
+
The `openapi()` and `graphql()` methods return schemas and require `database.schema`. `fastify()` returns the server instance for configuration and startup. The database and enabled services initialize on `ready()`, `listen()` or the first `inject()`; initialization errors stop startup. Override server features with `createServer(config, { files: false, graphql: true, openapi: true })`.
|
|
463
546
|
|
|
464
|
-
Generators can
|
|
547
|
+
The root import `@kollors/deep-json-server` also provides these functions. Server adapters load when enabled. Generators can be used independently:
|
|
465
548
|
|
|
466
549
|
```js
|
|
467
|
-
import { generateOpenapi,
|
|
550
|
+
import { generateOpenapi, writeOpenapi } from '@kollors/deep-json-server/openapi';
|
|
551
|
+
import { generateGraphql, writeGraphql } from '@kollors/deep-json-server/graphql';
|
|
468
552
|
|
|
469
553
|
const document = await generateOpenapi('./schema.json', { files: true });
|
|
470
554
|
const sdl = await generateGraphql('./schema.json');
|
|
@@ -472,7 +556,7 @@ await writeOpenapi(document, './generated/openapi.yaml');
|
|
|
472
556
|
await writeGraphql(sdl, './generated/schema.graphql');
|
|
473
557
|
```
|
|
474
558
|
|
|
475
|
-
`generateOpenapi()` also accepts `host`, `port`, `pageSize`, `maxPageSize` and `info`. Pass a schema object instead of a path if preferred. Servers and generators use their own copy of the model.
|
|
559
|
+
`generateOpenapi()` also accepts `host`, `port`, `pageSize`, `maxPageSize` and `info`. Pass a schema object instead of a path if preferred. Servers and generators use their own copy of the model. Pagination sizes must be positive integers; `pageSize` cannot exceed `maxPageSize`.
|
|
476
560
|
|
|
477
561
|
## Storage and development
|
|
478
562
|
|
|
@@ -487,6 +571,6 @@ npm run verify
|
|
|
487
571
|
|
|
488
572
|
The command checks types, code style, test coverage and installation from the package archive.
|
|
489
573
|
|
|
490
|
-
To publish a new alpha, update the version in `package.json` and push to `main`. GitHub Actions creates the version tag and publishes to npm `alpha` through trusted publishing. Already published versions are skipped. If the tag exists but publication failed, a retry uses that tag and verifies that the package files match it. Pushing a version tag also triggers publication; stable versions publish to `latest`.
|
|
574
|
+
To publish a new alpha, update the version in `package.json`, `package-lock.json` and `src/constants.ts`, then push to `main`. GitHub Actions creates the version tag and publishes to npm `alpha` through trusted publishing. Already published versions are skipped. If the tag exists but publication failed, a retry uses that tag and verifies that the package files match it. Pushing a version tag also triggers publication; stable versions publish to `latest`.
|
|
491
575
|
|
|
492
576
|
License: MIT.
|
package/README.ru.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
JSON-сервер для имитации API: REST, GraphQL, вложенные запросы, бинарные файлы и экспорт схем. Требуется Node.js 22 или новее.
|
|
6
6
|
|
|
7
|
-
**1.0.0-alpha.
|
|
7
|
+
**1.0.0-alpha.4 — предварительная версия.** При переходе с 0.x обновите схему моделей и параметры запросов по примерам ниже.
|
|
8
8
|
|
|
9
9
|
## Установка
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@ JSON-сервер для имитации API: REST, GraphQL, вложенные
|
|
|
12
12
|
npm install @kollors/deep-json-server@alpha
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
Для установки конкретной версии укажите `@1.0.0-alpha.
|
|
15
|
+
Для установки конкретной версии укажите `@1.0.0-alpha.4`.
|
|
16
16
|
|
|
17
17
|
## Быстрый старт
|
|
18
18
|
|
|
@@ -51,7 +51,7 @@ npx deep-json-server server.config.js
|
|
|
51
51
|
| `openapi.enabled` | Включить HTTP-маршрут спецификации; по умолчанию `false` |
|
|
52
52
|
| `openapi.endpoint` | Путь спецификации; по умолчанию `/openapi.json` |
|
|
53
53
|
| `openapi.path` | Путь экспорта YAML |
|
|
54
|
-
| `openapi.info` |
|
|
54
|
+
| `openapi.info` | Необязательный объект метаданных: обязательные `title` и `version`, необязательный `description` |
|
|
55
55
|
| `graphql.enabled` | Включить GraphQL HTTP API; по умолчанию `false` |
|
|
56
56
|
| `graphql.endpoint` | Путь GraphQL; по умолчанию `/graphql` |
|
|
57
57
|
| `graphql.path` | Путь экспорта GraphQL SDL |
|
|
@@ -62,7 +62,9 @@ npx deep-json-server server.config.js
|
|
|
62
62
|
| `files.data` | Бинарные файлы в памяти |
|
|
63
63
|
| `files.directory`, `files.metadata` | Каталог файлов и JSON метаданных; необходимы оба |
|
|
64
64
|
|
|
65
|
-
Относительные пути отсчитываются от каталога конфигурационного файла. При вызове `createServer()` с объектом конфигурации — от рабочего каталога. Сервер работает с копией переданных данных в
|
|
65
|
+
Относительные пути отсчитываются от каталога конфигурационного файла. При вызове `createServer()` с объектом конфигурации — от рабочего каталога. Сервер работает с копией переданных данных в памяти и метаданных.
|
|
66
|
+
|
|
67
|
+
Значение `server.port: 0` позволяет системе выбрать свободный порт. OpenAPI на HTTP-эндпоинте использует относительный адрес сервера.
|
|
66
68
|
|
|
67
69
|
| Флаг CLI | Действие |
|
|
68
70
|
|---|---|
|
|
@@ -84,7 +86,17 @@ npx deep-json-server generate graphql server.config.js
|
|
|
84
86
|
npx deep-json-server generate openapi,graphql server.config.js
|
|
85
87
|
```
|
|
86
88
|
|
|
87
|
-
Команда читает `database.schema` и сохраняет схемы
|
|
89
|
+
Команда читает `database.schema` и сохраняет схемы в `openapi.path` и `graphql.path`. Для генерации достаточно такой конфигурации:
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
export default {
|
|
93
|
+
database: { schema: './schema.json' },
|
|
94
|
+
openapi: { path: './generated/openapi.yaml' },
|
|
95
|
+
graphql: { path: './generated/schema.graphql' },
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Для каждого формата нужен отдельный файл. Команда отклонит путь, который перезапишет конфигурацию, базу, схему или метаданные файлов.
|
|
88
100
|
|
|
89
101
|
## Схема моделей
|
|
90
102
|
|
|
@@ -122,7 +134,9 @@ npx deep-json-server generate openapi,graphql server.config.js
|
|
|
122
134
|
| Экспорт OpenAPI 3.0.3 | Доступен | Ошибка при запросе экспорта |
|
|
123
135
|
| GraphQL SDL / API | Доступен | Ошибка при запросе |
|
|
124
136
|
|
|
125
|
-
При явной схеме неизвестные поля и коллекции запрещены. Исключение — хранимые ключи, выведенные из связей. Исходная база проверяется при загрузке. Генерация использует описание моделей.
|
|
137
|
+
При явной схеме неизвестные поля и коллекции запрещены. Исключение — хранимые ключи, выведенные из связей. Исходная база проверяется при загрузке. Генерация использует описание моделей.
|
|
138
|
+
|
|
139
|
+
REST без схемы создаёт ключ `id` и сохраняет произвольные JSON-поля. Для фильтров и выбора отдельных полей используются имена в формате идентификаторов; остальные поля возвращаются через `scope={"*":true}`. Поля с разными типами значений можно читать, но для их использования в `where`, `order` или `nested` нужна явная схема.
|
|
126
140
|
|
|
127
141
|
### Поля
|
|
128
142
|
|
|
@@ -134,7 +148,7 @@ npx deep-json-server generate openapi,graphql server.config.js
|
|
|
134
148
|
| `description`, `example` | Документация и пример |
|
|
135
149
|
| `required`, `nullable` | По умолчанию `false`; наличие поля и разрешение `null` независимы |
|
|
136
150
|
| `default` | Значение при пропуске в create/replace; PATCH не вставляет значения по умолчанию |
|
|
137
|
-
| `enum` | Допустимые значения; у массива — значения каждого элемента |
|
|
151
|
+
| `enum` | Допустимые строки, числа или логические значения; у массива — значения каждого элемента |
|
|
138
152
|
| `primary` | Корневой первичный ключ: обязательный, уникальный, неизменяемый, без `null` |
|
|
139
153
|
| `generated` | `uuid` для строк, `increment` для чисел; значение создаёт сервер |
|
|
140
154
|
| `readOnly`, `writeOnly` | Только ответ или только входные данные; взаимно исключаются |
|
|
@@ -149,6 +163,8 @@ npx deep-json-server generate openapi,graphql server.config.js
|
|
|
149
163
|
|
|
150
164
|
Например, `LocalUser` с первичным ключом `username` и полем `password: {"type":"string","required":true,"writeOnly":true}` получает запрос `localUser(username: ...)` и маршрут `/localUsers/{username}`. Поле `writeOnly` доступно для записи и исключено из ответов, `scope`, фильтров и сортировки.
|
|
151
165
|
|
|
166
|
+
Объекты в GraphQL должны содержать хотя бы одно поле, доступное в ответе; REST допускает и пустые объекты.
|
|
167
|
+
|
|
152
168
|
### Связи
|
|
153
169
|
|
|
154
170
|
```json
|
|
@@ -219,7 +235,60 @@ npx deep-json-server generate openapi,graphql server.config.js
|
|
|
219
235
|
|
|
220
236
|
Имя параметра пути соответствует первичному ключу. POST, PUT и PATCH принимают JSON-объект записи. PUT заменяет запись с сохранением ключа и серверных полей. PATCH объединяет поля на верхнем уровне; переданные вложенные объекты заменяются с сохранением их полей `readOnly`. Создание и замена требуют всех обязательных полей. При обновлении проверяются переданные значения и итоговая запись. Отсутствующая запись — `404`, конфликт — `409`. DELETE возвращает удалённую запись.
|
|
221
237
|
|
|
222
|
-
|
|
238
|
+
### Вложенная запись
|
|
239
|
+
|
|
240
|
+
Поля ключей, например `genreIds: ["1"]`, только задают связь. В поля связей можно передавать записи для создания или обновления:
|
|
241
|
+
|
|
242
|
+
```http
|
|
243
|
+
PATCH /movies/1
|
|
244
|
+
Content-Type: application/json
|
|
245
|
+
|
|
246
|
+
{
|
|
247
|
+
"actors": [
|
|
248
|
+
{
|
|
249
|
+
"userId": "1",
|
|
250
|
+
"genres": [
|
|
251
|
+
"1",
|
|
252
|
+
{ "id": "2", "name": "Обновлённый жанр" },
|
|
253
|
+
{ "name": "Новый жанр" }
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
| Значение в связи | Действие |
|
|
261
|
+
|---|---|
|
|
262
|
+
| Ключ, например `"1"` | Связать существующую запись без её изменения |
|
|
263
|
+
| Объект с первичным ключом | PATCH обновляет переданные поля, PUT заменяет связанную запись |
|
|
264
|
+
| Объект без первичного ключа | Создать запись со значениями по умолчанию и сгенерированным ключом |
|
|
265
|
+
|
|
266
|
+
Имя и тип ключа берутся из целевой модели. Объект только с ключом тоже считается обновлением: в PUT он должен содержать обязательные поля модели. При замене сохраняются первичный ключ, генерируемые значения и поля `readOnly`. В POST вложенные объекты с существующими ключами обновляются частично. Если запись по ключу не найдена, операция завершится ошибкой. Для создания вложенной записи без ключа нужна его автоматическая генерация.
|
|
267
|
+
|
|
268
|
+
Переданный список заменяет состав связи. PATCH сохраняет пропущенные связи, PUT очищает пропущенные связи, ключи которых доступны для записи. `[]` очищает список, `null` — одиночную связь с разрешённым `nullable`. Разрыв связи не удаляет связанную запись. Обязательные связи должны оставаться заполненными.
|
|
269
|
+
|
|
270
|
+
В одном объекте указывайте либо связь, либо её хранимый ключ: например, `genres` или `genreIds`. Для обратной связи сервер меняет целевой ключ. Если путь проходит через массив и нельзя однозначно выбрать элемент для связи, передайте массив с нужными ключами явно. Защищённые ключи изменять нельзя.
|
|
271
|
+
|
|
272
|
+
Все вложенные изменения входят в транзакцию основной записи. Ошибка проверки, отсутствующая запись или неверный выбор полей ответа отменяет всю операцию. Изменения общей записи видны всем, кто с ней связан.
|
|
273
|
+
|
|
274
|
+
GraphQL принимает в полях связей типизированные объекты. Чтобы при замене изменить только связи, используйте поля ключей, например `genreIds`. Пример:
|
|
275
|
+
|
|
276
|
+
```graphql
|
|
277
|
+
mutation {
|
|
278
|
+
movieUpdate(id: "1", data: {
|
|
279
|
+
actors: [{
|
|
280
|
+
userId: "1"
|
|
281
|
+
genres: [{ id: "2", name: "Обновлённый жанр" }, { name: "Новый жанр" }]
|
|
282
|
+
}]
|
|
283
|
+
}) {
|
|
284
|
+
actors { data { genres { data { id name } } } }
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Параметры REST-запросов
|
|
290
|
+
|
|
291
|
+
Параметры `where`, `order`, `pager`, `nested` и `scope` содержат JSON. Пример до URL-кодирования:
|
|
223
292
|
|
|
224
293
|
```text
|
|
225
294
|
GET /users?where={"fullName":{"contains":"Мира"}}&order=[{"field":"fullName","direction":"ASC"}]&pager={"page":1,"pageSize":20}
|
|
@@ -229,13 +298,27 @@ GET /users?where={"fullName":{"contains":"Мира"}}&order=[{"field":"fullName"
|
|
|
229
298
|
|
|
230
299
|
```js
|
|
231
300
|
const params = new URLSearchParams({
|
|
232
|
-
scope:
|
|
301
|
+
scope: JSON.stringify({ id: true, fullName: true, movies: { id: true, title: true } }),
|
|
233
302
|
nested: JSON.stringify({ movies: { order: [{ field: 'title', direction: 'ASC' }], pager: { page: 1, pageSize: 5 } } }),
|
|
234
303
|
});
|
|
235
304
|
const response = await fetch(`/users?${params}`);
|
|
236
305
|
```
|
|
237
306
|
|
|
238
|
-
`scope
|
|
307
|
+
`scope` выбирает поля ответа:
|
|
308
|
+
|
|
309
|
+
```json
|
|
310
|
+
{
|
|
311
|
+
"*": true,
|
|
312
|
+
"actors": {
|
|
313
|
+
"user": { "id": true, "fullName": true },
|
|
314
|
+
"genres": { "*": true }
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
`true` включает поле, вложенный объект выбирает поля внутри объекта или связи. `"*": true` включает собственные поля и хранимые ключи, кроме `writeOnly`. Связи перечисляются явно. Если указать для связи `true`, вернутся её собственные поля.
|
|
320
|
+
|
|
321
|
+
Без `scope` выбираются собственные поля. `{}` не выбирает ни одного поля. Значениями могут быть `true` или вложенные объекты; `false`, `null` и массивы возвращают `400`. Списки сохраняют структуру ответа `{ data, total }`.
|
|
239
322
|
|
|
240
323
|
`nested` сопоставляет полные пути ответа и настройки списков:
|
|
241
324
|
|
|
@@ -441,30 +524,31 @@ Content-Type: application/json
|
|
|
441
524
|
|
|
442
525
|
`PATCH` возвращает обновлённые метаданные со статусом `200`; если по новому пути уже существует файл, сервер возвращает `409`. `DELETE` отвечает статусом `204` без тела. Если файл не найден, любая операция по пути возвращает `404`. Пути в URL задаются относительно `files.directory`, а все возвращаемые URL — относительно адреса сервера.
|
|
443
526
|
|
|
444
|
-
При хранении на диске бинарный файл находится по пути `<files.directory>/<directory>/<name>`.
|
|
527
|
+
При хранении на диске бинарный файл находится по пути `<files.directory>/<directory>/<name>`. Метаданные содержат `directory`, `mimeType` и `name`; размер сервер читает из файла, а URL формирует сам. Директории и файл метаданных создаются по мере необходимости.
|
|
528
|
+
|
|
529
|
+
Используйте один процесс сервера для дисковой базы и файлового хранилища. Перед ручным изменением файлов или метаданных остановите его. Пути в хранилище не могут содержать символические ссылки. Загрузка и переименование не могут перезаписать базу, счётчики, схему, загруженную конфигурацию или файл метаданных.
|
|
445
530
|
|
|
446
531
|
Отправляйте файл как бинарное тело запроса. В браузере для этого можно использовать `xhr.send(file)`, а прогресс отслеживать через `XMLHttpRequest.upload.onprogress`. Максимальный размер по умолчанию равен 100 МиБ и настраивается через `server.maxFileSize`. Отсутствующие или небезопасные заголовки и пути возвращают `400`, превышение лимита — `413`, а отсутствующий, некорректный или не поддерживаемый Fastify `Content-Type` — `400` либо `415` в зависимости от этапа проверки.
|
|
447
532
|
|
|
448
533
|
## Программный API
|
|
449
534
|
|
|
450
535
|
```js
|
|
451
|
-
import { createServer } from '@kollors/deep-json-server';
|
|
536
|
+
import { createServer } from '@kollors/deep-json-server/server';
|
|
452
537
|
import config from './server.config.js';
|
|
453
538
|
|
|
454
539
|
const facade = await createServer(config);
|
|
455
|
-
const openapi = await facade.openapi();
|
|
456
|
-
const sdl = await facade.graphql();
|
|
457
540
|
const server = facade.fastify();
|
|
458
541
|
await server.listen();
|
|
459
542
|
// await server.close();
|
|
460
543
|
```
|
|
461
544
|
|
|
462
|
-
Методы `openapi()` и `graphql()` возвращают
|
|
545
|
+
Методы `openapi()` и `graphql()` возвращают схемы и требуют `database.schema`. `fastify()` возвращает экземпляр сервера для настройки и запуска. База и включённые сервисы инициализируются при `ready()`, `listen()` или первом `inject()`; ошибка инициализации останавливает запуск. Возможности сервера можно переопределить через `createServer(config, { files: false, graphql: true, openapi: true })`.
|
|
463
546
|
|
|
464
|
-
Генераторы можно использовать отдельно:
|
|
547
|
+
Эти функции доступны и через общий импорт `@kollors/deep-json-server`. Адаптеры сервера загружаются при включении. Генераторы можно использовать отдельно:
|
|
465
548
|
|
|
466
549
|
```js
|
|
467
|
-
import { generateOpenapi,
|
|
550
|
+
import { generateOpenapi, writeOpenapi } from '@kollors/deep-json-server/openapi';
|
|
551
|
+
import { generateGraphql, writeGraphql } from '@kollors/deep-json-server/graphql';
|
|
468
552
|
|
|
469
553
|
const document = await generateOpenapi('./schema.json', { files: true });
|
|
470
554
|
const sdl = await generateGraphql('./schema.json');
|
|
@@ -472,7 +556,7 @@ await writeOpenapi(document, './generated/openapi.yaml');
|
|
|
472
556
|
await writeGraphql(sdl, './generated/schema.graphql');
|
|
473
557
|
```
|
|
474
558
|
|
|
475
|
-
`generateOpenapi()` также принимает `host`, `port`, `pageSize`, `maxPageSize` и `info`. Вместо пути можно передать объект схемы. Сервер и генераторы работают с собственной копией модели.
|
|
559
|
+
`generateOpenapi()` также принимает `host`, `port`, `pageSize`, `maxPageSize` и `info`. Вместо пути можно передать объект схемы. Сервер и генераторы работают с собственной копией модели. Размеры страниц должны быть положительными целыми числами; `pageSize` не может превышать `maxPageSize`.
|
|
476
560
|
|
|
477
561
|
## Хранение и разработка
|
|
478
562
|
|
|
@@ -487,6 +571,6 @@ npm run verify
|
|
|
487
571
|
|
|
488
572
|
Команда проверяет типы, стиль кода, покрытие тестами и установку пакета из архива.
|
|
489
573
|
|
|
490
|
-
Для публикации новой альфы обновите версию в `package.json` и отправьте изменения в `main`. GitHub Actions создаст тег версии и опубликует пакет в канал npm `alpha` через trusted publishing. Уже опубликованная версия пропускается. Если тег создан, а публикация не завершилась, повторный запуск использует этот тег и проверяет соответствие ему файлов пакета. Отправка тега версии также запускает публикацию; стабильные версии публикуются в `latest`.
|
|
574
|
+
Для публикации новой альфы обновите версию в `package.json`, `package-lock.json` и `src/constants.ts`, затем отправьте изменения в `main`. GitHub Actions создаст тег версии и опубликует пакет в канал npm `alpha` через trusted publishing. Уже опубликованная версия пропускается. Если тег создан, а публикация не завершилась, повторный запуск использует этот тег и проверяет соответствие ему файлов пакета. Отправка тега версии также запускает публикацию; стабильные версии публикуются в `latest`.
|
|
491
575
|
|
|
492
576
|
Лицензия: MIT.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type { DatabaseConfig, DeepJsonServerConfig, FilesConfig, GraphqlConfig, MemoryFile, OpenapiConfig, ServerConfig } from './src/config.js';
|
|
2
2
|
export type { ServerFeatures } from './src/features.js';
|
|
3
|
-
export type {
|
|
3
|
+
export type { FileUpdate } from './src/files/contract.js';
|
|
4
|
+
export type { FileMetadata } from './src/files/http.js';
|
|
4
5
|
export type { EntityDefinition, Field, ModelSchema } from './src/model.js';
|
|
5
6
|
export type { OpenapiOptions } from './src/schema.js';
|
|
6
7
|
export { generateGraphql, generateOpenapi, writeGraphql, writeOpenapi } from './src/schema.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/F,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/src/cli.d.ts
CHANGED
package/dist/src/cli.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
|
-
import {
|
|
2
|
+
import { configure, configureGeneration, readConfigModule } from './config.js';
|
|
3
3
|
import { DEFAULT_HOST, DEFAULT_PORT, VERSION } from './constants.js';
|
|
4
4
|
import { resolveFeatures } from './features.js';
|
|
5
|
+
import { inputPaths, validateExportPaths } from './paths.js';
|
|
5
6
|
import { generateGraphql, generateOpenapi, writeGraphql, writeOpenapi } from './schema.js';
|
|
6
|
-
import {
|
|
7
|
+
import { createConfiguredServer } from './server.js';
|
|
8
|
+
import { isObject } from './utils.js';
|
|
7
9
|
const HELP_TEXT = `Deep JSON Server
|
|
8
10
|
|
|
9
11
|
Usage:
|
|
@@ -19,7 +21,7 @@ Usage:
|
|
|
19
21
|
--version, -v Show version
|
|
20
22
|
|
|
21
23
|
Files are enabled when configured. Generate writes schemas to the configured paths.`;
|
|
22
|
-
export async function runCli(args = process.argv.slice(2), services = { createServer }) {
|
|
24
|
+
export async function runCli(args = process.argv.slice(2), services = { createServer: createConfiguredServer }) {
|
|
23
25
|
if (args.includes('--help') || args.includes('-h')) {
|
|
24
26
|
process.stdout.write(`${HELP_TEXT}\n`);
|
|
25
27
|
return;
|
|
@@ -68,25 +70,30 @@ export async function runCli(args = process.argv.slice(2), services = { createSe
|
|
|
68
70
|
throw new Error('Invalid generation format');
|
|
69
71
|
if (generate && (features.graphql || features.openapi))
|
|
70
72
|
throw new Error('Endpoint flags are only available when starting the server');
|
|
71
|
-
const source = await
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
const
|
|
73
|
+
const source = await readConfigModule(configPath);
|
|
74
|
+
const serverOptions = generate && !formats.includes('openapi') ? {} : (source.config.server ?? {});
|
|
75
|
+
if (!isObject(serverOptions))
|
|
76
|
+
throw new Error('config.server must be an object');
|
|
77
|
+
const overrides = { host: host ?? serverOptions.host ?? process.env.HOST ?? DEFAULT_HOST, port: port ?? serverOptions.port ?? Number(process.env.PORT ?? DEFAULT_PORT) };
|
|
78
|
+
const config = generate
|
|
79
|
+
? configureGeneration(source.config, formats, source.directory, source.path, { ...overrides, files: features.files })
|
|
80
|
+
: configure({ ...source.config, server: { ...serverOptions, ...overrides } }, source.directory, source.path);
|
|
77
81
|
if (generate) {
|
|
78
82
|
if (!config.database.schema)
|
|
79
83
|
throw new Error('Generation requires an explicit model schema');
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (!
|
|
84
|
+
const destinations = formats.map((format) => {
|
|
85
|
+
const path = config[format].path;
|
|
86
|
+
if (!path)
|
|
83
87
|
throw new Error(`Укажите config.${format}.path`);
|
|
88
|
+
return path;
|
|
89
|
+
});
|
|
90
|
+
await validateExportPaths(destinations, inputPaths(source.config, source.directory, source.path));
|
|
84
91
|
const openapi = formats.includes('openapi')
|
|
85
92
|
? await generateOpenapi(config.database.schema, {
|
|
86
|
-
files:
|
|
93
|
+
files: config.files != null,
|
|
87
94
|
host: config.server.host,
|
|
88
95
|
port: config.server.port,
|
|
89
|
-
pageSize: config.server.pageSize
|
|
96
|
+
pageSize: config.server.pageSize,
|
|
90
97
|
maxPageSize: config.server.maxPageSize,
|
|
91
98
|
info: config.openapi.info,
|
|
92
99
|
})
|
|
@@ -102,7 +109,7 @@ export async function runCli(args = process.argv.slice(2), services = { createSe
|
|
|
102
109
|
}
|
|
103
110
|
return;
|
|
104
111
|
}
|
|
105
|
-
const server = (await services.createServer(config,
|
|
112
|
+
const server = (await services.createServer(config, resolveFeatures(config, features))).fastify();
|
|
106
113
|
await server.listen();
|
|
107
114
|
server.log.info('Deep JSON Server started');
|
|
108
115
|
}
|
package/dist/src/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/src/config.d.ts
CHANGED
|
@@ -67,4 +67,15 @@ export interface NormalizedServerConfig {
|
|
|
67
67
|
/** Validates configuration and resolves relative paths. */
|
|
68
68
|
export declare const normalizeServerConfig: (config: DeepJsonServerConfig, directoryPath?: string) => NormalizedServerConfig;
|
|
69
69
|
/** Loads an ES module config and resolves paths from its directory. */
|
|
70
|
-
export declare function
|
|
70
|
+
export declare function readConfigModule(configPath: string): Promise<{
|
|
71
|
+
config: Record<string, unknown>;
|
|
72
|
+
directory: string;
|
|
73
|
+
path: string;
|
|
74
|
+
}>;
|
|
75
|
+
export declare const configSourcePath: (config: NormalizedServerConfig) => string | undefined;
|
|
76
|
+
export declare function configure(config: unknown, directory: string, sourcePath?: string): NormalizedServerConfig;
|
|
77
|
+
export declare function configureGeneration(source: Record<string, unknown>, formats: string[], directory: string, sourcePath: string, overrides: {
|
|
78
|
+
host?: string;
|
|
79
|
+
port?: number;
|
|
80
|
+
files?: boolean;
|
|
81
|
+
}): NormalizedServerConfig;
|