@kollors/deep-json-server 0.4.0 → 0.5.0
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 +201 -38
- package/README.ru.md +201 -38
- package/package.json +1 -1
- package/src/cli.js +63 -51
- package/src/config.js +97 -0
- package/src/constants.js +1 -0
- package/src/files.js +278 -0
- package/src/openapi/document.js +52 -8
- package/src/openapi/index.js +3 -3
- package/src/server.js +30 -7
- package/types/src/constants.d.ts +1 -0
- package/types/src/files.d.ts +5 -0
- package/types/src/openapi/document.d.ts +3 -2
- package/types/src/openapi/index.d.ts +4 -3
- package/types/src/server.d.ts +8 -2
package/README.md
CHANGED
|
@@ -14,24 +14,67 @@ Node.js 20 or newer is required.
|
|
|
14
14
|
npm install --save-dev @kollors/deep-json-server
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
## Configuration and startup
|
|
18
|
+
|
|
19
|
+
Create the ESM module `server.config.js`. The example below enables every feature:
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
import process from 'node:process';
|
|
23
|
+
|
|
24
|
+
export default {
|
|
25
|
+
database: {
|
|
26
|
+
path: process.env.DATABASE_PATH ?? 'mock/database.json',
|
|
27
|
+
schema: 'mock/database-schema.json',
|
|
28
|
+
},
|
|
29
|
+
files: {
|
|
30
|
+
directory: 'mock/files',
|
|
31
|
+
metadata: 'mock/files/_database.json',
|
|
32
|
+
},
|
|
33
|
+
openapi: {
|
|
34
|
+
path: 'mock/openapi-schema.yaml',
|
|
35
|
+
},
|
|
36
|
+
server: {
|
|
37
|
+
host: '127.0.0.1',
|
|
38
|
+
port: 4001,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Configuration keys:
|
|
44
|
+
|
|
45
|
+
| Key | Required | Purpose |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| `database.path` | Always | Existing JSON database file |
|
|
48
|
+
| `database.schema` | No | JSON overrides for request validation and OpenAPI schemas |
|
|
49
|
+
| `files.directory` | With `--files` | Directory for binary contents |
|
|
50
|
+
| `files.metadata` | With `--files` | JSON file containing uploaded-file metadata |
|
|
51
|
+
| `openapi.path` | With `--openapi` | Generated OpenAPI YAML file |
|
|
52
|
+
| `server.host` | No | Listening host; falls back to `HOST`, then `127.0.0.1` |
|
|
53
|
+
| `server.port` | No | Listening port; falls back to `PORT`, then `4001` |
|
|
54
|
+
|
|
55
|
+
All relative paths are resolved from the directory containing `server.config.js`, not from the current working directory. Unknown keys, empty paths and invalid value types are rejected before startup. The config is executable JavaScript, so it can read environment variables, import other modules and calculate values before exporting the object. A `.js` config with `export default` requires an ESM project (`"type": "module"`); in a CommonJS project, use the same contents in `server.config.mjs`.
|
|
56
|
+
|
|
57
|
+
Add the commands you need to `package.json`:
|
|
18
58
|
|
|
19
59
|
```json
|
|
20
60
|
{
|
|
21
61
|
"scripts": {
|
|
22
|
-
"mock": "deep-json-server
|
|
23
|
-
"openapi": "deep-json-server
|
|
62
|
+
"mock": "deep-json-server --files server.config.js",
|
|
63
|
+
"openapi": "deep-json-server --openapi --files server.config.js"
|
|
24
64
|
}
|
|
25
65
|
}
|
|
26
66
|
```
|
|
27
67
|
|
|
28
|
-
|
|
68
|
+
CLI modes:
|
|
29
69
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
70
|
+
| Command | Behavior |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `deep-json-server server.config.js` | Starts the CRUD server without file routes |
|
|
73
|
+
| `deep-json-server --files server.config.js` | Starts the CRUD server with file routes |
|
|
74
|
+
| `deep-json-server --openapi server.config.js` | Generates OpenAPI and exits |
|
|
75
|
+
| `deep-json-server --openapi --files server.config.js` | Generates OpenAPI with file routes and exits |
|
|
33
76
|
|
|
34
|
-
|
|
77
|
+
`--openapi` never starts the HTTP server. `--files` is independent: without it, file routes are neither registered nor added to OpenAPI. Run `deep-json-server --help` to print the CLI summary.
|
|
35
78
|
|
|
36
79
|
## Example database
|
|
37
80
|
|
|
@@ -106,9 +149,15 @@ PATCH /movies/:id
|
|
|
106
149
|
DELETE /movies/:id
|
|
107
150
|
```
|
|
108
151
|
|
|
109
|
-
`POST` generates a string ID
|
|
152
|
+
`POST` generates a string ID. `PUT` completely replaces the selected record, while `PATCH` updates only supplied fields; both preserve the existing ID and its type. An `id` supplied in any request body cannot override the server-controlled ID. All write operations — `POST`, `PUT`, `PATCH` and `DELETE` — are serialized and persisted in the JSON file.
|
|
110
153
|
|
|
111
|
-
The database file must exist before startup. Resource names may contain Latin letters, numbers, `_` and `-`, and must start with a letter. Every resource is an array of JSON objects. Every record must have a non-empty string or finite numeric `id`; IDs must be unique within a resource when compared as strings, so `1` and `"1"` cannot coexist.
|
|
154
|
+
The database file must exist before startup. Resource names may contain Latin letters, numbers, `_` and `-`, and must start with a letter. Every resource is an array of JSON objects. Every record must have a non-empty string or finite numeric `id`; IDs must be unique within a resource when compared as strings, so `1` and `"1"` cannot coexist. The server rereads the file before every GET and write operation, so valid external edits become visible without a restart.
|
|
155
|
+
|
|
156
|
+
Successful writes return the created, replaced, updated or deleted record. Errors use an appropriate HTTP status and this JSON shape:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{ "error": "Human-readable message" }
|
|
160
|
+
```
|
|
112
161
|
|
|
113
162
|
## Pagination and sorting
|
|
114
163
|
|
|
@@ -132,7 +181,7 @@ A GET collection always returns a page object. `_page` defaults to `1`, and `_pe
|
|
|
132
181
|
|
|
133
182
|
Both pagination parameters must be positive integers. `_perPage` cannot exceed `1000` by default; use the programmatic `maxPageSize` option to change that limit. Invalid values return `400` instead of being silently corrected. A page beyond the last page returns an empty `data` array and points `prev` to the last available page instead of silently clamping the request.
|
|
134
183
|
|
|
135
|
-
|
|
184
|
+
`_sort` accepts comma-separated field paths. Rules are applied from left to right; prefix a field with `-` for descending order. Dot paths can address nested object fields, including fields added by `_embed`, for example `GET /users?_embed=country&_sort=country.name,-id`. Unknown or unsafe sort fields return `400`.
|
|
136
185
|
|
|
137
186
|
## Filters
|
|
138
187
|
|
|
@@ -151,18 +200,33 @@ Nested objects and arrays can be filtered at any depth. Conditions in one object
|
|
|
151
200
|
}
|
|
152
201
|
```
|
|
153
202
|
|
|
154
|
-
|
|
203
|
+
Use `and`, `or` and `not` for explicit logical groups:
|
|
155
204
|
|
|
156
205
|
```json
|
|
157
206
|
{
|
|
158
|
-
"
|
|
159
|
-
{
|
|
160
|
-
|
|
207
|
+
"and": [
|
|
208
|
+
{
|
|
209
|
+
"or": [
|
|
210
|
+
{ "title": { "contains": "father" } },
|
|
211
|
+
{ "actors": { "some": { "userId": { "eq": "2" } } } }
|
|
212
|
+
]
|
|
213
|
+
},
|
|
214
|
+
{ "not": { "isArchived": { "eq": true } } }
|
|
161
215
|
]
|
|
162
216
|
}
|
|
163
217
|
```
|
|
164
218
|
|
|
165
|
-
|
|
219
|
+
Field operators:
|
|
220
|
+
|
|
221
|
+
| Operator | Behavior |
|
|
222
|
+
| --- | --- |
|
|
223
|
+
| `eq`, `ne` | Equality or inequality |
|
|
224
|
+
| `contains` | Case-insensitive substring for strings, or matching member for arrays |
|
|
225
|
+
| `startsWith`, `endsWith` | Case-insensitive string prefix or suffix |
|
|
226
|
+
| `gt`, `gte`, `lt`, `lte` | Ordered comparison; ISO date strings can be compared lexically |
|
|
227
|
+
| `in` | Matches a scalar or array member against the supplied values |
|
|
228
|
+
| `some`, `every`, `none` | Applies a nested condition to array elements |
|
|
229
|
+
| `not` | Negates a nested field condition |
|
|
166
230
|
|
|
167
231
|
Simple query parameters are supported too:
|
|
168
232
|
|
|
@@ -172,15 +236,19 @@ GET /movies?title:contains=father
|
|
|
172
236
|
|
|
173
237
|
Simple filter values recognize JSON primitives: numbers, `true`, `false` and `null`. Values with leading zeroes, such as `001`, remain strings. Unknown operators, invalid logical conditions and filter paths that do not exist in a non-empty resource return `400`.
|
|
174
238
|
|
|
239
|
+
For a simple `in` filter, separate values with commas: `GET /movies?id:in=1,2`. If `_where` is present, it is the complete filter and other simple filter parameters are ignored. The examples show readable JSON; an HTTP client must URL-encode `_where` when constructing the URL manually.
|
|
240
|
+
|
|
241
|
+
Filtering is performed after `_embed`. This means a filter can address fields added by an embedded relation when the same request includes that `_embed`; stored `...Id` and `...Ids` fields can always be filtered directly.
|
|
242
|
+
|
|
175
243
|
## Relationships
|
|
176
244
|
|
|
177
|
-
Use `_embed` to
|
|
245
|
+
Use `_embed` to add related records to the response:
|
|
178
246
|
|
|
179
247
|
```http
|
|
180
248
|
GET /movies/1?_embed=actors.user.country&_embed=actors.genres&_embed=publishers
|
|
181
249
|
```
|
|
182
250
|
|
|
183
|
-
The response contains actors, each actor's user and genres, the user's country, and publishers. Embedding can follow any number of levels:
|
|
251
|
+
The response contains actors, each actor's user and genres, the user's country, and publishers. Original ID fields remain in the response, and the database file is not modified. Embedding can follow any number of levels:
|
|
184
252
|
|
|
185
253
|
```http
|
|
186
254
|
GET /movies/1?_embed=actors.user.country
|
|
@@ -189,27 +257,63 @@ GET /genres/2?_embed=parents.parents
|
|
|
189
257
|
|
|
190
258
|
Unknown or malformed `_embed` paths return `400`.
|
|
191
259
|
|
|
260
|
+
Pass `_embed` more than once, as above, or provide a comma-separated list in one parameter. Pagination applies only to the requested root collection; embedded related records are returned in full.
|
|
261
|
+
|
|
192
262
|
Reverse relationships work as well:
|
|
193
263
|
|
|
194
264
|
```http
|
|
195
265
|
GET /countries/1?_embed=users
|
|
196
266
|
```
|
|
197
267
|
|
|
198
|
-
Relations are inferred by convention:
|
|
268
|
+
Relations are inferred by convention. A field named `<relation>Id` creates a single relation, while `<relation>Ids` creates a collection relation. The relation name is matched to a top-level resource directly or through its singular form. For example:
|
|
199
269
|
|
|
200
270
|
- `countryId` points to `countries`;
|
|
201
271
|
- `userId` points to `users` when the requested relation is `user`;
|
|
202
272
|
- `genreIds` points to `genres`;
|
|
203
273
|
- `publisherIds` points to `publishers`;
|
|
204
|
-
- `parentIds` points back to the current resource when `_embed=parents` is requested.
|
|
274
|
+
- `parentIds` points back to the current resource when `_embed=parents` is requested; `_embed=children` resolves the reverse self-relation.
|
|
205
275
|
|
|
206
|
-
They are soft references: the server resolves them when requested but does not enforce referential integrity when data is written.
|
|
276
|
+
Reverse relations use the source resource name. For example, `_embed=users` on a country finds users whose nested data contains the corresponding `countryId`. They are soft references: the server resolves them when requested but does not enforce referential integrity when data is written.
|
|
207
277
|
|
|
208
|
-
An explicit `...Id` or `...Ids` field is the source of truth. If a record also contains an outdated embedded value, `_embed` replaces
|
|
278
|
+
An explicit `...Id` or `...Ids` field is the source of truth. If a record also contains an outdated embedded value, `_embed` replaces that response property with the current related record. A missing target becomes `null` for a single relation or is omitted from the resulting array for a collection relation. Relationship lookups use lazy per-request ID indexes, so each referenced resource is indexed only when needed.
|
|
209
279
|
|
|
210
|
-
##
|
|
280
|
+
## Files
|
|
211
281
|
|
|
212
|
-
|
|
282
|
+
Add `files.directory` and `files.metadata` to the server config, then pass `--files` to enable raw binary uploads:
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
deep-json-server --files server.config.js
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Upload one file as the request body. Both headers are required: `Content-Name` contains the relative logical name encoded with `encodeURIComponent`, and `Content-Type` contains the file MIME type:
|
|
289
|
+
|
|
290
|
+
```http
|
|
291
|
+
POST /_files
|
|
292
|
+
Content-Name: posters%2Fthe-godfather.jpg
|
|
293
|
+
Content-Type: image/jpeg
|
|
294
|
+
|
|
295
|
+
<binary body>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
The response contains metadata and a stable URL:
|
|
299
|
+
|
|
300
|
+
```json
|
|
301
|
+
{
|
|
302
|
+
"id": "generated-id",
|
|
303
|
+
"mimeType": "image/jpeg",
|
|
304
|
+
"name": "posters/the-godfather.jpg",
|
|
305
|
+
"size": 182340,
|
|
306
|
+
"url": "/_files/generated-id"
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Use `GET /_files/:id` to download the original bytes and `DELETE /_files/:id` to delete both the binary contents and their metadata. The returned `url` is relative to the mock-server origin. The server creates the configured directories automatically, stores binary contents under generated IDs without relying on the original file name, and keeps the logical names and other metadata in `files.metadata`. The metadata file may be absent initially and is created on the first upload. Do not edit it while the server is running.
|
|
311
|
+
|
|
312
|
+
The upload is raw binary rather than `multipart/form-data`, so `XMLHttpRequest.upload.onprogress` can report progress while the browser sends a `File` directly with `xhr.send(file)`. The default maximum size is 100 MiB and can be changed through the programmatic `maxFileSize` option. Unsafe or absolute `Content-Name` paths return `400`, an exceeded limit returns `413`, and a malformed or unsupported `Content-Type` returns `400` or `415`.
|
|
313
|
+
|
|
314
|
+
## Database schema and OpenAPI generation
|
|
315
|
+
|
|
316
|
+
The optional JSON file referenced by `database.schema`, for example `mock/database-schema.json`, customizes inferred schemas. It is read both during normal server startup and during OpenAPI generation:
|
|
213
317
|
|
|
214
318
|
```json
|
|
215
319
|
{
|
|
@@ -235,13 +339,23 @@ Create a small configuration file next to the database, for example `mock/databa
|
|
|
235
339
|
}
|
|
236
340
|
```
|
|
237
341
|
|
|
238
|
-
|
|
342
|
+
Schema configuration:
|
|
343
|
+
|
|
344
|
+
| Key | Purpose |
|
|
345
|
+
| --- | --- |
|
|
346
|
+
| `$info` | OpenAPI `info`; when present, non-empty `title` and `version` are required |
|
|
347
|
+
| `$schema.<resource>.name` | Explicit component name when automatic singularization is unsuitable or collides |
|
|
348
|
+
| `$schema.<resource>.required` | Required field paths; nested paths use dots, such as `actors.userId` |
|
|
349
|
+
| `$schema.<resource>.formats` | OpenAPI formats for inferred or explicit string fields, such as `date`, `date-time` or `uri` |
|
|
350
|
+
| `$schema.<resource>.properties` | Recursive OpenAPI-compatible field schemas merged with inference |
|
|
351
|
+
|
|
352
|
+
Set `openapi.path` in the server config, then generate an OpenAPI 3.0.3 file and exit:
|
|
239
353
|
|
|
240
354
|
```bash
|
|
241
|
-
deep-json-server
|
|
355
|
+
deep-json-server --openapi --files server.config.js
|
|
242
356
|
```
|
|
243
357
|
|
|
244
|
-
The generator infers resources and field types from all database records. Every inferred field is optional by default, while
|
|
358
|
+
The generator infers resources and field types from all database records. Every inferred field is optional by default, while the top-level `id` is always required in response schemas and is omitted from create and update request schemas. Add other required fields to `required`. A nested required path marks that nested property as required; it does not automatically make every parent path required, so list the parent separately when necessary.
|
|
245
359
|
|
|
246
360
|
Different value types are inferred independently and combined through `oneOf`. Configuration is validated before generation: `$info`, resource and schema names, and the structure of `properties` are validated, while paths from `required` and `formats` must exist in the resulting schema.
|
|
247
361
|
|
|
@@ -261,9 +375,9 @@ Use `properties` to describe fields that cannot be inferred, particularly for an
|
|
|
261
375
|
}
|
|
262
376
|
```
|
|
263
377
|
|
|
264
|
-
An empty resource still receives a required string `id` property because IDs created by the server are strings. Generation stops with an actionable error when resources produce duplicate schema names or operation IDs; use an explicit `name` to resolve schema-name collisions.
|
|
378
|
+
An empty resource still receives a required string `id` property because IDs created by the server are strings. Generation stops with an actionable error when resources produce duplicate schema names or operation IDs; use an explicit `name` to resolve schema-name collisions. The output directory is created automatically, and the configured YAML file is replaced on every generation.
|
|
265
379
|
|
|
266
|
-
`$info` becomes the OpenAPI `info` object, while resource settings live under `$schema`. The OpenAPI `servers` entry is generated automatically from
|
|
380
|
+
`$info` becomes the OpenAPI `info` object, while resource settings live under `$schema`. The OpenAPI `servers` entry is generated automatically from `server.host` and `server.port`, their `HOST` and `PORT` environment variable fallbacks, or the default `http://127.0.0.1:4001`.
|
|
267
381
|
|
|
268
382
|
Use `name` when a resource needs an explicit schema name instead of the automatically singularized name:
|
|
269
383
|
|
|
@@ -277,24 +391,73 @@ Use `name` when a resource needs an explicit schema name instead of the automati
|
|
|
277
391
|
}
|
|
278
392
|
```
|
|
279
393
|
|
|
280
|
-
The generated document describes CRUD endpoints, pagination, sorting, deep filters, `_embed`, and both direct and reverse response relations inferred from `...Id` and `...Ids` fields. A numeric database ID is described as `integer | string`, because a later `POST` creates a string ID in the same resource. The document can be used as input for tools such as RTK Query OpenAPI Codegen. OpenAPI is generated only when `--
|
|
394
|
+
The generated document describes CRUD endpoints, pagination, sorting, deep filters, `_embed`, and both direct and reverse response relations inferred from `...Id` and `...Ids` fields. When `--files` is present, it also describes raw binary upload, download and deletion endpoints. A numeric database ID is described as `integer | string`, because a later `POST` creates a string ID in the same resource. The document can be used as input for tools such as RTK Query OpenAPI Codegen. OpenAPI is generated only when `--openapi` is passed; normal server startup does not rewrite the file.
|
|
281
395
|
|
|
282
|
-
During normal startup, request bodies are validated against the inferred
|
|
396
|
+
During normal startup, request bodies are validated against the same inferred and configured schemas. `POST` and `PUT` enforce configured required fields; `PATCH` validates only fields that are actually supplied. `formats` and `properties` apply to all three methods. Unlisted additional object fields remain allowed. Invalid bodies return `400`.
|
|
397
|
+
|
|
398
|
+
## Scope and security
|
|
399
|
+
|
|
400
|
+
Deep JSON Server is intended for local development and automated tests. It has no authentication or authorization, allows CORS from every origin, persists accepted writes directly to the configured files and does not enforce referential integrity. Keep the default loopback host unless the surrounding environment provides its own access controls; do not expose the server or file routes to an untrusted network.
|
|
283
401
|
|
|
284
402
|
## Programmatic API
|
|
285
403
|
|
|
286
404
|
```js
|
|
287
|
-
import { createServer, generateOpenApi, startServer } from '@kollors/deep-json-server';
|
|
288
|
-
|
|
289
|
-
|
|
405
|
+
import { createOpenApiDocument, createServer, generateOpenApi, startServer } from '@kollors/deep-json-server';
|
|
406
|
+
|
|
407
|
+
// Create an instance without opening a port, for example for tests.
|
|
408
|
+
const server = await createServer({
|
|
409
|
+
databasePath: 'mock/database.json',
|
|
410
|
+
filesDirectoryPath: 'mock/files',
|
|
411
|
+
filesMetadataPath: 'mock/files/_database.json',
|
|
412
|
+
logger: false,
|
|
413
|
+
maxFileSize: 100 * 1024 * 1024,
|
|
414
|
+
maxPageSize: 1000,
|
|
415
|
+
schemaPath: 'mock/database-schema.json',
|
|
416
|
+
});
|
|
290
417
|
|
|
291
418
|
const response = await server.inject({ method: 'GET', url: '/movies' });
|
|
292
419
|
|
|
293
420
|
await server.close();
|
|
294
421
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
422
|
+
// Create an instance and start listening.
|
|
423
|
+
const listeningServer = await startServer({
|
|
424
|
+
databasePath: 'mock/database.json',
|
|
425
|
+
host: '127.0.0.1',
|
|
426
|
+
port: 4001,
|
|
427
|
+
schemaPath: 'mock/database-schema.json',
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
await listeningServer.close();
|
|
431
|
+
|
|
432
|
+
// Read the database and schema files, then write an OpenAPI YAML file.
|
|
433
|
+
await generateOpenApi({
|
|
434
|
+
databasePath: 'mock/database.json',
|
|
435
|
+
files: true,
|
|
436
|
+
host: '127.0.0.1',
|
|
437
|
+
outputPath: 'mock/openapi-schema.yaml',
|
|
438
|
+
port: 4001,
|
|
439
|
+
schemaPath: 'mock/database-schema.json',
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
// Build the same kind of OpenAPI document entirely in memory.
|
|
443
|
+
const document = createOpenApiDocument(
|
|
444
|
+
{ movies: [{ id: '1', title: 'The Godfather' }] },
|
|
445
|
+
{ $info: { title: 'Movie API', version: '1.0.0' } },
|
|
446
|
+
{ files: true, host: '127.0.0.1', port: 4001 },
|
|
447
|
+
);
|
|
298
448
|
```
|
|
299
449
|
|
|
300
|
-
|
|
450
|
+
Programmatic options:
|
|
451
|
+
|
|
452
|
+
| Option | Used by | Meaning |
|
|
453
|
+
| --- | --- | --- |
|
|
454
|
+
| `databasePath` | `createServer`, `startServer`, `generateOpenApi` | Required JSON database path |
|
|
455
|
+
| `schemaPath` | The same three functions | Optional database-schema path |
|
|
456
|
+
| `filesDirectoryPath`, `filesMetadataPath` | `createServer`, `startServer` | Optional pair enabling file routes |
|
|
457
|
+
| `files` | `generateOpenApi`, `createOpenApiDocument` | Whether file routes appear in OpenAPI |
|
|
458
|
+
| `host`, `port` | `startServer`, `generateOpenApi`, `createOpenApiDocument` | Listening address or generated `servers` URL |
|
|
459
|
+
| `logger` | `createServer`, `startServer` | Fastify logger settings; defaults to `true` |
|
|
460
|
+
| `maxPageSize`, `maxFileSize` | `createServer`, `startServer` | Runtime limits; defaults are 1000 records and 100 MiB |
|
|
461
|
+
| `outputPath` | `generateOpenApi` | Required generated YAML path |
|
|
462
|
+
|
|
463
|
+
`createServer()` returns a Fastify instance without opening a network port, which is useful with `server.inject()` in tests. `startServer()` also starts listening. `generateOpenApi()` reads files and writes YAML, while `createOpenApiDocument()` works with in-memory database and schema objects and does not write a file. These functions do not read `server.config.js`; pass their options explicitly. The package includes generated TypeScript declarations for all exported functions.
|