You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Introduce support for Standard Schema v1 validators across the project. Adds a new standard-schema module that detects ~standard validators, converts optional JSON Schema output into Async DB field metadata, merges overlays, and produces diagnostics. Runtime validators now support async validators via validateAsync/assertAsync; sync helpers throw DB_SCHEMA_ASYNC_VALIDATOR_REQUIRED when an async validator is encountered. Builder and schema generation were updated to accept validator-first shorthand and optionally emit validator-first .schema.mjs output (controlled by schema.standardSchema config). CLI bundling/unbundling, root bundle generation, and diagnostics were adjusted to import/reference executable validators and preserve behavior. Documentation and a runnable examples/standard-schema were added, plus corresponding type updates and tests.
Copy file name to clipboardExpand all lines: README.md
+18Lines changed: 18 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -48,6 +48,7 @@ Other useful paths:
48
48
-[`examples/computed-fields`](./examples/computed-fields): computed field patterns across several schema-backed models.
49
49
-[`examples/rest-client`](./examples/rest-client): calling @async/db from app or test code.
50
50
-[`examples/schema-manifest`](./examples/schema-manifest): schema metadata for admin/CMS UI.
51
+
-[`examples/standard-schema`](./examples/standard-schema): Standard Schema validators with Async DB metadata overlays.
51
52
-[`examples/hono-auth`](./examples/hono-auth): optional Hono auth and write hooks.
52
53
53
54
See [Which Example Should I Start With?](#which-example-should-i-start-with) for the full examples map.
@@ -200,6 +201,22 @@ In mixed mode, schema files define the contract and data files provide seed reco
200
201
201
202
Schema defaults fill omitted fields on create and safe additive runtime hydration. Updates, patches, and document puts preserve omitted fields; include a field in the write body when you want to change it.
202
203
204
+
Executable `.schema.mjs` files can also accept Standard Schema-compatible validators:
205
+
206
+
```js
207
+
import { collection, field } from'@async/db/schema';
displayName:field.computed(field.string(), ({ record }) =>record.email),
214
+
},
215
+
});
216
+
```
217
+
218
+
The validator owns runtime parsing through `~standard.validate`; Async DB overlays keep generated metadata, relations, defaults, and computed resolvers. Async validators run in package, REST, and GraphQL writes. Sync schema helpers throw `DB_SCHEMA_ASYNC_VALIDATOR_REQUIRED` when the validator returns a Promise; use `validateAsync()` or `assertAsync()` for that path.
219
+
203
220
See [docs/concepts.md](./docs/concepts.md) and [docs/fixtures-and-schemas.md](./docs/fixtures-and-schemas.md).
204
221
205
222
## Validate Or Resolve From Schema
@@ -393,6 +410,7 @@ The examples are a learning path. Run any example with `node ./src/cli.js sync -
393
410
| CSV as the source of truth | [`examples/csv`](./examples/csv) | CSV inference, source hashes, mirror refreshes |
394
411
| Admin/CMS-style field metadata | [`examples/schema-manifest`](./examples/schema-manifest) | `outputs.schemaManifest` and manifest customization |
395
412
| Schema JSON to simple CMS UI templates | [`examples/schema-ui`](./examples/schema-ui) | `serve.mjs` SSR view/editor HTML from manifest + mirror (`node ./examples/schema-ui/serve.mjs`); `/templates` route keeps static placeholders |
413
+
| Standard Schema validators | [`examples/standard-schema`](./examples/standard-schema) | Dependency-free Standard Schema validation, `field.meta(...)` overlays, async write validation, computed fields, and conservative type fallback |
396
414
| Diagnostics for schema/data drift | [`examples/diagnostics`](./examples/diagnostics) | Warnings surfaced without breaking unrelated resources |
397
415
| Several advanced features together | [`examples/advanced`](./examples/advanced) | `.schema.mjs`, mixed mode, defaults, nested objects |
398
416
| Hono auth and write hooks | [`examples/hono-auth`](./examples/hono-auth) | Optional Hono integration with auth lifecycle hooks |
-[Configuration](./configuration.md): `db.config.mjs`, fixture folders, resource naming, strictness, registered operations, mock delay/errors, server options, and forks.
16
16
-[Schema UI example](../examples/schema-ui/README.md): manifest-driven CMS HTML with **`serve.mjs`** SSR from live mirror rows (`node ./examples/schema-ui/serve.mjs`).
Keep the default `warn` while fixture shape is still changing.
241
243
244
+
## Standard Schema Output
245
+
246
+
@async/db detects Standard Schema validators by shape without installing a
247
+
validator dependency. Set `schema.standardSchema: true` when generated
248
+
`.schema.mjs` files should prefer the validator-first authoring form for
249
+
resources that have a Standard Schema validator:
250
+
251
+
```js
252
+
import { defineConfig } from'@async/db/config';
253
+
254
+
exportdefaultdefineConfig({
255
+
schema: {
256
+
standardSchema:true,
257
+
},
258
+
});
259
+
```
260
+
261
+
With that option, aggregate bundle/unbundle output can emit
262
+
`collection(UserSchema, { fields })` or `document(SettingsSchema, { fields })`
263
+
for Standard Schema-backed resources. Resources without a validator keep the
264
+
normal Async DB-first shape.
265
+
242
266
## Schema Defaults
243
267
244
268
Schema defaults apply when creating collection records through the package API, REST, GraphQL, SQLite adapter, and generated Hono SQLite starter. Updates, patches, and document puts preserve omitted fields instead of backfilling defaults; include a field in the write body when you want to change it.
This example shows the dependency-free integration path for validators that implement the Standard Schema v1 contract. The validator object lives in trusted project code; @async/db imports the schema module, recognizes `~standard.validate`, and calls it during schema helpers and runtime writes without bundling a validator-library dependency.
`db/users.schema.mjs` uses a small local Standard Schema-compatible validator. It lowercases email addresses during writes, exposes a Standard JSON Schema converter for field inference, and then layers Async DB metadata on top.
13
+
14
+
You can keep Async DB's object-first schema shape and mix the validator in:
displayName:field.computed(field.string(), ({ record }) =>record.email),
22
+
},
23
+
});
24
+
```
25
+
26
+
The validator-first shorthand is also supported when the external schema owns the field shape:
27
+
28
+
```js
29
+
exportdefaultcollection(UserSchema, {
30
+
idField:'id',
31
+
fields: {
32
+
email:field.meta({ unique:true }),
33
+
displayName:field.computed(field.string(), {
34
+
resolveMany({ records }) {
35
+
returnnewMap(records.map((record) => [
36
+
record.id,
37
+
`${record.firstName}${record.lastName}`,
38
+
]));
39
+
},
40
+
}),
41
+
},
42
+
});
43
+
```
44
+
45
+
`field.meta(...)` is for Async DB metadata such as `unique`, `description`, defaults, relations, and manifest hints. `field.computed(...)` remains the resolver entrypoint, and resolver functions are not written to generated schema or manifest output.
46
+
47
+
The validator can be async. Package API, REST, and GraphQL writes await it and store the returned `value`.
`db/settings.schema.mjs` intentionally uses an opaque Standard Schema validator with no JSON Schema converter and no field overlay. In that case generated TypeScript falls back to a conservative index signature, and diagnostics ask you to add `field.meta(...)` overlays or provide a JSON Schema converter when you want richer generated metadata.
0 commit comments