@fougere/schema 0.2.0-alpha.1 → 0.3.0-alpha.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/dist/EntityDeclarations.d.ts +22 -0
- package/dist/EntityDeclarations.d.ts.map +1 -0
- package/dist/EntityDeclarations.js +19 -0
- package/dist/EntityDeclarations.js.map +1 -0
- package/dist/Field.d.ts +21 -0
- package/dist/Field.d.ts.map +1 -0
- package/dist/Field.js +50 -0
- package/dist/Field.js.map +1 -0
- package/dist/Schema.d.ts +67 -0
- package/dist/Schema.d.ts.map +1 -0
- package/dist/Schema.js +152 -0
- package/dist/Schema.js.map +1 -0
- package/dist/SchemaView.d.ts +18 -0
- package/dist/SchemaView.d.ts.map +1 -0
- package/dist/SchemaView.js +2 -0
- package/dist/SchemaView.js.map +1 -0
- package/dist/axis/Axis.d.ts +10 -0
- package/dist/axis/Axis.d.ts.map +1 -0
- package/dist/axis/Axis.js +9 -0
- package/dist/axis/Axis.js.map +1 -0
- package/dist/axis/Meta.d.ts +4 -0
- package/dist/axis/Meta.d.ts.map +1 -0
- package/dist/axis/Meta.js +2 -0
- package/dist/axis/Meta.js.map +1 -0
- package/dist/axis/boundary/Boundaries.d.ts +20 -0
- package/dist/axis/boundary/Boundaries.d.ts.map +1 -0
- package/dist/axis/boundary/Boundaries.js +31 -0
- package/dist/axis/boundary/Boundaries.js.map +1 -0
- package/dist/axis/boundary/Boundary.d.ts +26 -0
- package/dist/axis/boundary/Boundary.d.ts.map +1 -0
- package/dist/axis/boundary/Boundary.js +53 -0
- package/dist/axis/boundary/Boundary.js.map +1 -0
- package/dist/axis/boundary/axis.d.ts +4 -0
- package/dist/axis/boundary/axis.d.ts.map +1 -0
- package/dist/axis/boundary/axis.js +29 -0
- package/dist/axis/boundary/axis.js.map +1 -0
- package/dist/axis/lifecycle/Generators.d.ts +4 -0
- package/dist/axis/lifecycle/Generators.d.ts.map +1 -0
- package/dist/axis/lifecycle/Generators.js +8 -0
- package/dist/axis/lifecycle/Generators.js.map +1 -0
- package/dist/axis/lifecycle/Lifecycle.d.ts +28 -0
- package/dist/axis/lifecycle/Lifecycle.d.ts.map +1 -0
- package/dist/axis/lifecycle/Lifecycle.js +38 -0
- package/dist/axis/lifecycle/Lifecycle.js.map +1 -0
- package/dist/axis/lifecycle/apply.d.ts +8 -0
- package/dist/axis/lifecycle/apply.d.ts.map +1 -0
- package/dist/axis/lifecycle/apply.js +72 -0
- package/dist/axis/lifecycle/apply.js.map +1 -0
- package/dist/axis/lifecycle/axis.d.ts +4 -0
- package/dist/axis/lifecycle/axis.d.ts.map +1 -0
- package/dist/axis/lifecycle/axis.js +46 -0
- package/dist/axis/lifecycle/axis.js.map +1 -0
- package/dist/axis/role/Relation.d.ts +10 -0
- package/dist/axis/role/Relation.d.ts.map +1 -0
- package/dist/axis/role/Relation.js +6 -0
- package/dist/axis/role/Relation.js.map +1 -0
- package/dist/axis/role/Role.d.ts +38 -0
- package/dist/axis/role/Role.d.ts.map +1 -0
- package/dist/axis/role/Role.js +50 -0
- package/dist/axis/role/Role.js.map +1 -0
- package/dist/axis/role/axis.d.ts +5 -0
- package/dist/axis/role/axis.d.ts.map +1 -0
- package/dist/axis/role/axis.js +101 -0
- package/dist/axis/role/axis.js.map +1 -0
- package/dist/axis/shape/Formats.d.ts +8 -0
- package/dist/axis/shape/Formats.d.ts.map +1 -0
- package/dist/axis/shape/Formats.js +10 -0
- package/dist/axis/shape/Formats.js.map +1 -0
- package/dist/axis/shape/Shape.d.ts +58 -0
- package/dist/axis/shape/Shape.d.ts.map +1 -0
- package/dist/axis/shape/Shape.js +52 -0
- package/dist/axis/shape/Shape.js.map +1 -0
- package/dist/card/Descriptor.d.ts +55 -0
- package/dist/card/Descriptor.d.ts.map +1 -0
- package/dist/card/Descriptor.js +2 -0
- package/dist/card/Descriptor.js.map +1 -0
- package/dist/card/describe.d.ts +12 -0
- package/dist/card/describe.d.ts.map +1 -0
- package/dist/card/describe.js +83 -0
- package/dist/card/describe.js.map +1 -0
- package/dist/card/diff.d.ts +140 -0
- package/dist/card/diff.d.ts.map +1 -0
- package/dist/card/diff.js +123 -0
- package/dist/card/diff.js.map +1 -0
- package/dist/card/reconstruct.d.ts +11 -0
- package/dist/card/reconstruct.d.ts.map +1 -0
- package/dist/card/reconstruct.js +83 -0
- package/dist/card/reconstruct.js.map +1 -0
- package/dist/card/typescript.d.ts +17 -0
- package/dist/card/typescript.d.ts.map +1 -0
- package/dist/card/typescript.js +93 -0
- package/dist/card/typescript.js.map +1 -0
- package/dist/clean.d.ts +2 -0
- package/dist/clean.d.ts.map +1 -0
- package/dist/{projections/card.js → clean.js} +1 -2
- package/dist/clean.js.map +1 -0
- package/dist/constraint/FieldGroup.d.ts +21 -0
- package/dist/constraint/FieldGroup.d.ts.map +1 -0
- package/dist/constraint/FieldGroup.js +65 -0
- package/dist/constraint/FieldGroup.js.map +1 -0
- package/dist/constraint/Unique.d.ts +4 -0
- package/dist/constraint/Unique.d.ts.map +1 -0
- package/dist/constraint/Unique.js +4 -0
- package/dist/constraint/Unique.js.map +1 -0
- package/dist/entity.d.ts +4 -116
- package/dist/entity.d.ts.map +1 -1
- package/dist/entity.js +13 -289
- package/dist/entity.js.map +1 -1
- package/dist/index.d.ts +35 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -26
- package/dist/index.js.map +1 -1
- package/dist/judge/Judge.d.ts +14 -0
- package/dist/judge/Judge.d.ts.map +1 -0
- package/dist/judge/Judge.js +161 -0
- package/dist/judge/Judge.js.map +1 -0
- package/dist/judge/cases.d.ts +50 -0
- package/dist/judge/cases.d.ts.map +1 -0
- package/dist/judge/cases.js +100 -0
- package/dist/judge/cases.js.map +1 -0
- package/dist/judge/form.d.ts +11 -0
- package/dist/judge/form.d.ts.map +1 -0
- package/dist/judge/form.js +18 -0
- package/dist/judge/form.js.map +1 -0
- package/dist/judge/options.d.ts +4 -0
- package/dist/judge/options.d.ts.map +1 -0
- package/dist/judge/options.js +2 -0
- package/dist/judge/options.js.map +1 -0
- package/dist/judge/result.d.ts +17 -0
- package/dist/judge/result.d.ts.map +1 -0
- package/dist/judge/result.js +2 -0
- package/dist/judge/result.js.map +1 -0
- package/dist/name.d.ts +1 -14
- package/dist/name.d.ts.map +1 -1
- package/dist/name.js +3 -14
- package/dist/name.js.map +1 -1
- package/dist/projection/encode.d.ts +3 -0
- package/dist/projection/encode.d.ts.map +1 -0
- package/dist/projection/encode.js +19 -0
- package/dist/projection/encode.js.map +1 -0
- package/dist/projection/io.d.ts +4 -0
- package/dist/projection/io.d.ts.map +1 -0
- package/dist/projection/io.js +29 -0
- package/dist/projection/io.js.map +1 -0
- package/dist/projection/source.d.ts +7 -0
- package/dist/projection/source.d.ts.map +1 -0
- package/dist/projection/source.js +11 -0
- package/dist/projection/source.js.map +1 -0
- package/dist/{projections → projection}/standard.d.ts +0 -8
- package/dist/projection/standard.d.ts.map +1 -0
- package/dist/projection/standard.js +2 -0
- package/dist/projection/standard.js.map +1 -0
- package/dist/same.d.ts +6 -0
- package/dist/same.d.ts.map +1 -0
- package/dist/same.js +35 -0
- package/dist/same.js.map +1 -0
- package/dist/vocabulary/bool.d.ts +1 -1
- package/dist/vocabulary/bool.d.ts.map +1 -1
- package/dist/vocabulary/bool.js +2 -2
- package/dist/vocabulary/bool.js.map +1 -1
- package/dist/vocabulary/created.d.ts +2 -12
- package/dist/vocabulary/created.d.ts.map +1 -1
- package/dist/vocabulary/created.js +3 -14
- package/dist/vocabulary/created.js.map +1 -1
- package/dist/vocabulary/date.d.ts +1 -1
- package/dist/vocabulary/date.d.ts.map +1 -1
- package/dist/vocabulary/date.js +2 -2
- package/dist/vocabulary/date.js.map +1 -1
- package/dist/vocabulary/email.d.ts +1 -2
- package/dist/vocabulary/email.d.ts.map +1 -1
- package/dist/vocabulary/email.js +0 -1
- package/dist/vocabulary/email.js.map +1 -1
- package/dist/vocabulary/immutable.d.ts +2 -8
- package/dist/vocabulary/immutable.d.ts.map +1 -1
- package/dist/vocabulary/immutable.js +4 -10
- package/dist/vocabulary/immutable.js.map +1 -1
- package/dist/vocabulary/indexed.d.ts +2 -18
- package/dist/vocabulary/indexed.d.ts.map +1 -1
- package/dist/vocabulary/indexed.js +2 -20
- package/dist/vocabulary/indexed.js.map +1 -1
- package/dist/vocabulary/json.d.ts +3 -16
- package/dist/vocabulary/json.d.ts.map +1 -1
- package/dist/vocabulary/json.js +12 -9
- package/dist/vocabulary/json.js.map +1 -1
- package/dist/vocabulary/list.d.ts +2 -16
- package/dist/vocabulary/list.d.ts.map +1 -1
- package/dist/vocabulary/list.js +3 -15
- package/dist/vocabulary/list.js.map +1 -1
- package/dist/vocabulary/many.d.ts +2 -6
- package/dist/vocabulary/many.d.ts.map +1 -1
- package/dist/vocabulary/many.js +4 -7
- package/dist/vocabulary/many.js.map +1 -1
- package/dist/vocabulary/nullable.d.ts +2 -8
- package/dist/vocabulary/nullable.d.ts.map +1 -1
- package/dist/vocabulary/nullable.js +5 -12
- package/dist/vocabulary/nullable.js.map +1 -1
- package/dist/vocabulary/number.d.ts +1 -1
- package/dist/vocabulary/number.d.ts.map +1 -1
- package/dist/vocabulary/number.js +2 -2
- package/dist/vocabulary/number.js.map +1 -1
- package/dist/vocabulary/oneOf.d.ts +1 -8
- package/dist/vocabulary/oneOf.d.ts.map +1 -1
- package/dist/vocabulary/oneOf.js +2 -2
- package/dist/vocabulary/oneOf.js.map +1 -1
- package/dist/vocabulary/optional.d.ts +2 -9
- package/dist/vocabulary/optional.d.ts.map +1 -1
- package/dist/vocabulary/optional.js +6 -14
- package/dist/vocabulary/optional.js.map +1 -1
- package/dist/vocabulary/primary.d.ts +4 -17
- package/dist/vocabulary/primary.d.ts.map +1 -1
- package/dist/vocabulary/primary.js +10 -13
- package/dist/vocabulary/primary.js.map +1 -1
- package/dist/vocabulary/readOnly.d.ts +2 -9
- package/dist/vocabulary/readOnly.d.ts.map +1 -1
- package/dist/vocabulary/readOnly.js +5 -11
- package/dist/vocabulary/readOnly.js.map +1 -1
- package/dist/vocabulary/ref.d.ts +2 -7
- package/dist/vocabulary/ref.d.ts.map +1 -1
- package/dist/vocabulary/ref.js +3 -8
- package/dist/vocabulary/ref.js.map +1 -1
- package/dist/vocabulary/text.d.ts +2 -2
- package/dist/vocabulary/text.d.ts.map +1 -1
- package/dist/vocabulary/text.js +2 -2
- package/dist/vocabulary/text.js.map +1 -1
- package/dist/vocabulary/unique.d.ts +2 -22
- package/dist/vocabulary/unique.d.ts.map +1 -1
- package/dist/vocabulary/unique.js +5 -24
- package/dist/vocabulary/unique.js.map +1 -1
- package/dist/vocabulary/updated.d.ts +2 -7
- package/dist/vocabulary/updated.d.ts.map +1 -1
- package/dist/vocabulary/updated.js +1 -7
- package/dist/vocabulary/updated.js.map +1 -1
- package/dist/vocabulary/url.d.ts +1 -2
- package/dist/vocabulary/url.d.ts.map +1 -1
- package/dist/vocabulary/url.js +0 -1
- package/dist/vocabulary/url.js.map +1 -1
- package/dist/vocabulary/vocabulary.d.ts +5 -0
- package/dist/vocabulary/vocabulary.d.ts.map +1 -0
- package/dist/vocabulary/vocabulary.js +31 -0
- package/dist/vocabulary/vocabulary.js.map +1 -0
- package/dist/vocabulary/writeOnly.d.ts +2 -8
- package/dist/vocabulary/writeOnly.d.ts.map +1 -1
- package/dist/vocabulary/writeOnly.js +5 -10
- package/dist/vocabulary/writeOnly.js.map +1 -1
- package/package.json +2 -2
- package/dist/field/boundary.d.ts +0 -86
- package/dist/field/boundary.d.ts.map +0 -1
- package/dist/field/boundary.js +0 -94
- package/dist/field/boundary.js.map +0 -1
- package/dist/field/field.d.ts +0 -64
- package/dist/field/field.d.ts.map +0 -1
- package/dist/field/field.js +0 -28
- package/dist/field/field.js.map +0 -1
- package/dist/field/index.d.ts +0 -7
- package/dist/field/index.d.ts.map +0 -1
- package/dist/field/index.js +0 -9
- package/dist/field/index.js.map +0 -1
- package/dist/field/lifecycle.d.ts +0 -40
- package/dist/field/lifecycle.d.ts.map +0 -1
- package/dist/field/lifecycle.js +0 -27
- package/dist/field/lifecycle.js.map +0 -1
- package/dist/field/meta.d.ts +0 -9
- package/dist/field/meta.d.ts.map +0 -1
- package/dist/field/meta.js +0 -7
- package/dist/field/meta.js.map +0 -1
- package/dist/field/role.d.ts +0 -54
- package/dist/field/role.d.ts.map +0 -1
- package/dist/field/role.js +0 -55
- package/dist/field/role.js.map +0 -1
- package/dist/field/shape.d.ts +0 -77
- package/dist/field/shape.d.ts.map +0 -1
- package/dist/field/shape.js +0 -49
- package/dist/field/shape.js.map +0 -1
- package/dist/hints.d.ts +0 -33
- package/dist/hints.d.ts.map +0 -1
- package/dist/hints.js +0 -2
- package/dist/hints.js.map +0 -1
- package/dist/projections/card.d.ts +0 -117
- package/dist/projections/card.d.ts.map +0 -1
- package/dist/projections/card.js.map +0 -1
- package/dist/projections/describe.d.ts +0 -25
- package/dist/projections/describe.d.ts.map +0 -1
- package/dist/projections/describe.js +0 -136
- package/dist/projections/describe.js.map +0 -1
- package/dist/projections/encode.d.ts +0 -11
- package/dist/projections/encode.d.ts.map +0 -1
- package/dist/projections/encode.js +0 -26
- package/dist/projections/encode.js.map +0 -1
- package/dist/projections/io.d.ts +0 -30
- package/dist/projections/io.d.ts.map +0 -1
- package/dist/projections/io.js +0 -52
- package/dist/projections/io.js.map +0 -1
- package/dist/projections/lifecycle.d.ts +0 -43
- package/dist/projections/lifecycle.d.ts.map +0 -1
- package/dist/projections/lifecycle.js +0 -115
- package/dist/projections/lifecycle.js.map +0 -1
- package/dist/projections/reconstruct.d.ts +0 -36
- package/dist/projections/reconstruct.d.ts.map +0 -1
- package/dist/projections/reconstruct.js +0 -149
- package/dist/projections/reconstruct.js.map +0 -1
- package/dist/projections/source.d.ts +0 -41
- package/dist/projections/source.d.ts.map +0 -1
- package/dist/projections/source.js +0 -37
- package/dist/projections/source.js.map +0 -1
- package/dist/projections/standard.d.ts.map +0 -1
- package/dist/projections/standard.js +0 -10
- package/dist/projections/standard.js.map +0 -1
- package/dist/projections/typescript.d.ts +0 -53
- package/dist/projections/typescript.d.ts.map +0 -1
- package/dist/projections/typescript.js +0 -184
- package/dist/projections/typescript.js.map +0 -1
- package/dist/projections/validation.d.ts +0 -57
- package/dist/projections/validation.d.ts.map +0 -1
- package/dist/projections/validation.js +0 -148
- package/dist/projections/validation.js.map +0 -1
- package/dist/unique.d.ts +0 -65
- package/dist/unique.d.ts.map +0 -1
- package/dist/unique.js +0 -80
- package/dist/unique.js.map +0 -1
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* answers absence, and with a value rather than an omission.
|
|
8
|
-
*/
|
|
9
|
-
export function optional(field) {
|
|
10
|
-
return cloneField(field, {
|
|
11
|
-
shape: field.shape && nullableShape(field.shape),
|
|
12
|
-
lifecycle: { ...field.lifecycle, create: field.lifecycle?.create ?? 'optional' },
|
|
13
|
-
});
|
|
14
|
-
}
|
|
1
|
+
import { vocabulary } from './vocabulary.js';
|
|
2
|
+
import { Anatomy } from '../axis/shape/Shape.js';
|
|
3
|
+
export const optional = vocabulary('optional', (field) => ({
|
|
4
|
+
shape: Anatomy.nullable(field.shape),
|
|
5
|
+
...(field.lifecycle?.create === undefined ? { lifecycle: { create: 'optional' } } : {}),
|
|
6
|
+
}));
|
|
15
7
|
//# sourceMappingURL=optional.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optional.js","sourceRoot":"","sources":["../../src/vocabulary/optional.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"optional.js","sourceRoot":"","sources":["../../src/vocabulary/optional.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGjD,MAAM,CAAC,MAAM,QAAQ,GAA4C,UAAU,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAClG,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;IACpC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,UAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;CACjG,CAAC,CAAC,CAAC"}
|
|
@@ -1,22 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Field } from '../Field.js';
|
|
2
|
+
import { type GeneratorRef } from '../axis/lifecycle/Generators.js';
|
|
2
3
|
interface PrimaryOptions {
|
|
3
|
-
/**
|
|
4
|
-
* Generator token: a built-in preset, a name registered via
|
|
5
|
-
* `registerGenerator`, or the colocated `[name, fn]` tuple — which registers
|
|
6
|
-
* and names in one gesture (the Field only ever carries the name).
|
|
7
|
-
*/
|
|
8
4
|
generate?: GeneratorRef | [name: string, fn: () => string];
|
|
9
5
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*
|
|
13
|
-
* - `primary()` — auto-generated CUID2 string ID (default)
|
|
14
|
-
* - `primary({ generate: 'uuid' })` — auto-generated UUID v4
|
|
15
|
-
* - `primary({ generate: ['monId', fn] })` — custom generator, registered + named
|
|
16
|
-
* - `primary(field)` — promote any field to primary key (no auto-generation;
|
|
17
|
-
* the value must be supplied, so its `auto` flag is preserved)
|
|
18
|
-
*/
|
|
19
|
-
export declare function primary(opts?: PrimaryOptions): Field<string, true>;
|
|
20
|
-
export declare function primary<T, A extends boolean>(field: Field<T, A>): Field<T, A>;
|
|
6
|
+
export declare function primary(opts?: PrimaryOptions): Field<string>;
|
|
7
|
+
export declare function primary<T>(field: Field<T>): Field<T>;
|
|
21
8
|
export {};
|
|
22
9
|
//# sourceMappingURL=primary.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primary.d.ts","sourceRoot":"","sources":["../../src/vocabulary/primary.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"primary.d.ts","sourceRoot":"","sources":["../../src/vocabulary/primary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAGvF,UAAU,cAAc;IACtB,QAAQ,CAAC,EAAE,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC,CAAC;CAC5D;AAED,wBAAgB,OAAO,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;AAC9D,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Field } from '../Field.js';
|
|
2
|
+
import { registerGenerator } from '../axis/lifecycle/Generators.js';
|
|
3
|
+
import { Judge } from '../judge/Judge.js';
|
|
2
4
|
export function primary(fieldOrOptions) {
|
|
3
|
-
|
|
4
|
-
// every axis (boundary, meta…); the role gains `primary`, and identity in the
|
|
5
|
-
// graph implies immutability in time: `update: 'forbidden'` (decided 2026-07-15).
|
|
6
|
-
if (fieldOrOptions && '__brand' in fieldOrOptions && fieldOrOptions.__brand === 'fougere_field') {
|
|
5
|
+
if (Judge.isField(fieldOrOptions)) {
|
|
7
6
|
const field = fieldOrOptions;
|
|
8
|
-
return
|
|
7
|
+
return field.with({
|
|
9
8
|
role: { ...field.role, primary: true },
|
|
10
|
-
lifecycle: { ...field.lifecycle, update:
|
|
9
|
+
lifecycle: { ...field.lifecycle, update: "forbidden" },
|
|
11
10
|
});
|
|
12
11
|
}
|
|
13
|
-
// primary() or primary({ generate }) — auto-generated string ID
|
|
14
12
|
const opts = (fieldOrOptions ?? {});
|
|
15
13
|
let generate;
|
|
16
14
|
if (Array.isArray(opts.generate)) {
|
|
@@ -19,13 +17,12 @@ export function primary(fieldOrOptions) {
|
|
|
19
17
|
generate = name;
|
|
20
18
|
}
|
|
21
19
|
else {
|
|
22
|
-
generate = opts.generate ??
|
|
20
|
+
generate = opts.generate ?? "cuid2";
|
|
23
21
|
}
|
|
24
|
-
return
|
|
25
|
-
shape: { type:
|
|
22
|
+
return new Field({
|
|
23
|
+
shape: { type: "string" },
|
|
26
24
|
role: { primary: true },
|
|
27
|
-
|
|
28
|
-
lifecycle: { create: { generate }, update: 'forbidden' },
|
|
25
|
+
lifecycle: { create: { generate }, update: "forbidden" },
|
|
29
26
|
});
|
|
30
27
|
}
|
|
31
28
|
//# sourceMappingURL=primary.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primary.js","sourceRoot":"","sources":["../../src/vocabulary/primary.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"primary.js","sourceRoot":"","sources":["../../src/vocabulary/primary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAqB,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAQ1C,MAAM,UAAU,OAAO,CAAC,cAAuC;IAC7D,IAAI,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,cAAc,CAAC;QAC7B,OAAO,KAAK,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE;YACtC,SAAS,EAAE,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE;SACvD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,cAAc,IAAI,EAAE,CAAmB,CAAC;IACtD,IAAI,QAAsB,CAAC;IAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QACjC,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5B,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,KAAK,CAAS;QACvB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;QACvB,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE;KACzD,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
* Close the field's INBOUND direction — emitted normally, never accepted from
|
|
4
|
-
* a client (a server-owned field, e.g. a computed counter). Supplying it in a
|
|
5
|
-
* create or patch input is a validation error ("Read-only"); its absence is
|
|
6
|
-
* never "Required" (the server provides it). Input types exclude it.
|
|
7
|
-
* The outbound direction (and its conversion) is untouched.
|
|
8
|
-
*/
|
|
9
|
-
export declare function readOnly<T, A extends boolean>(field: Field<T, A>): Field<T, A>;
|
|
1
|
+
import { Field } from '../Field.js';
|
|
2
|
+
export declare const readOnly: <T>(field: Field<T>) => Field<T>;
|
|
10
3
|
//# sourceMappingURL=readOnly.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readOnly.d.ts","sourceRoot":"","sources":["../../src/vocabulary/readOnly.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"readOnly.d.ts","sourceRoot":"","sources":["../../src/vocabulary/readOnly.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,eAAO,MAAM,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAEnD,CAAC"}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* never "Required" (the server provides it). Input types exclude it.
|
|
7
|
-
* The outbound direction (and its conversion) is untouched.
|
|
8
|
-
*/
|
|
9
|
-
export function readOnly(field) {
|
|
10
|
-
return createField({ ...field, boundary: { ...declaredBoundary(field), in: 'closed' } });
|
|
11
|
-
}
|
|
1
|
+
import { vocabulary } from './vocabulary.js';
|
|
2
|
+
import { Boundary } from '../axis/boundary/Boundary.js';
|
|
3
|
+
export const readOnly = vocabulary('readOnly', (field) => ({
|
|
4
|
+
boundary: Boundary.declared(field).with({ in: 'closed' }),
|
|
5
|
+
}));
|
|
12
6
|
//# sourceMappingURL=readOnly.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readOnly.js","sourceRoot":"","sources":["../../src/vocabulary/readOnly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"readOnly.js","sourceRoot":"","sources":["../../src/vocabulary/readOnly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAGxD,MAAM,CAAC,MAAM,QAAQ,GAAqC,UAAU,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC3F,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;CAC1D,CAAC,CAAC,CAAC"}
|
package/dist/vocabulary/ref.d.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import { type EntityConstructor
|
|
1
|
+
import { type EntityConstructor } from '../axis/role/Relation.js';
|
|
2
|
+
import { Field } from '../Field.js';
|
|
2
3
|
export interface RefOptions {
|
|
3
4
|
cascade?: boolean;
|
|
4
5
|
}
|
|
5
|
-
/**
|
|
6
|
-
* A reference to another entity — a foreign-key string plus a one-relation role.
|
|
7
|
-
* Pass the target class (`ref(Author)`) or, for circular/forward references, a
|
|
8
|
-
* thunk (`ref(() => Author)`). For a nullable FK, wrap it: `optional(ref(Author))`
|
|
9
|
-
* — that path also flips the type to `string | null` (which `ref` alone never did).
|
|
10
|
-
*/
|
|
11
6
|
export declare function ref<E extends EntityConstructor>(target: E | (() => E), opts?: RefOptions): Field<string>;
|
|
12
7
|
//# sourceMappingURL=ref.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ref.d.ts","sourceRoot":"","sources":["../../src/vocabulary/ref.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ref.d.ts","sourceRoot":"","sources":["../../src/vocabulary/ref.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,GAAG,CAAC,CAAC,SAAS,iBAAiB,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAWxG"}
|
package/dist/vocabulary/ref.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
* A reference to another entity — a foreign-key string plus a one-relation role.
|
|
4
|
-
* Pass the target class (`ref(Author)`) or, for circular/forward references, a
|
|
5
|
-
* thunk (`ref(() => Author)`). For a nullable FK, wrap it: `optional(ref(Author))`
|
|
6
|
-
* — that path also flips the type to `string | null` (which `ref` alone never did).
|
|
7
|
-
*/
|
|
1
|
+
import { toTargetThunk } from '../axis/role/Relation.js';
|
|
2
|
+
import { Field } from '../Field.js';
|
|
8
3
|
export function ref(target, opts) {
|
|
9
|
-
return
|
|
4
|
+
return new Field({
|
|
10
5
|
shape: { type: 'string' },
|
|
11
6
|
role: {
|
|
12
7
|
relation: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ref.js","sourceRoot":"","sources":["../../src/vocabulary/ref.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ref.js","sourceRoot":"","sources":["../../src/vocabulary/ref.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA0B,MAAM,0BAA0B,CAAC;AACjF,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAMpC,MAAM,UAAU,GAAG,CAA8B,MAAqB,EAAE,IAAiB;IACvF,OAAO,IAAI,KAAK,CAAS;QACvB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,IAAI,EAAE;YACJ,QAAQ,EAAE;gBACR,EAAE,EAAE,aAAa,CAAC,MAAM,CAAC;gBACzB,IAAI,EAAE,KAAK;gBACX,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;aAChD;SACF;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Field } from '../Field.js';
|
|
2
|
+
import { type StringFormat } from '../axis/shape/Formats.js';
|
|
2
3
|
export interface TextOptions {
|
|
3
4
|
min?: number;
|
|
4
5
|
max?: number;
|
|
5
6
|
pattern?: string;
|
|
6
|
-
/** JSON Schema format predicate (email, uuid, uri, date, time…), asserted by the engine. */
|
|
7
7
|
format?: StringFormat;
|
|
8
8
|
default?: string;
|
|
9
9
|
description?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/vocabulary/text.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/vocabulary/text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,IAAI,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAMtD"}
|
package/dist/vocabulary/text.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Field } from '../Field.js';
|
|
2
2
|
export function text(opts) {
|
|
3
|
-
return
|
|
3
|
+
return new Field({
|
|
4
4
|
shape: { type: 'string', minLength: opts?.min, maxLength: opts?.max, pattern: opts?.pattern, format: opts?.format },
|
|
5
5
|
lifecycle: opts?.default !== undefined ? { create: { value: opts.default } } : undefined,
|
|
6
6
|
meta: opts?.description !== undefined ? { description: opts.description } : undefined,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/vocabulary/text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/vocabulary/text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAYpC,MAAM,UAAU,IAAI,CAAC,IAAkB;IACrC,OAAO,IAAI,KAAK,CAAS;QACvB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;QACnH,SAAS,EAAE,IAAI,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS;QACxF,IAAI,EAAE,IAAI,EAAE,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS;KACtF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,23 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
* No two rows may carry the same value — a unique constraint of one, on the role axis.
|
|
4
|
-
*
|
|
5
|
-
* The role axis is where it belongs because uniqueness is a fact about the field's
|
|
6
|
-
* place in the entity, not about the values it accepts: `text({ max: 80 })` says what
|
|
7
|
-
* a slug looks like, `unique(...)` says there is only one of each. A shape cannot
|
|
8
|
-
* express it — judging a single value can never see the other rows.
|
|
9
|
-
*
|
|
10
|
-
* So the realization is the storage's, and only the storage's: the DDL emits the
|
|
11
|
-
* constraint, the database enforces it on every write, including writes Fougere never
|
|
12
|
-
* saw. A collision surfaces as the driver's error, not as a `validate()` failure.
|
|
13
|
-
*
|
|
14
|
-
* It also travels: `describe()` carries `role.unique` on the card, so a consumer in
|
|
15
|
-
* another language reads the same promise — one that is now kept.
|
|
16
|
-
*
|
|
17
|
-
* The group is `[]` — the empty member list denoting THIS field, because a field does not
|
|
18
|
-
* know its own key here: `slug` is named by the object literal `entity({...})` receives,
|
|
19
|
-
* one call up. Keeping it empty rather than filling it in later means nothing to remap
|
|
20
|
-
* when `rename()` moves the key, and one shape shared with the composite form.
|
|
21
|
-
*/
|
|
22
|
-
export declare function unique<T, A extends boolean>(field: Field<T, A>): Field<T, A>;
|
|
1
|
+
import { Field } from "../Field.js";
|
|
2
|
+
export declare const unique: <T>(field: Field<T>) => Field<T>;
|
|
23
3
|
//# sourceMappingURL=unique.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unique.d.ts","sourceRoot":"","sources":["../../src/vocabulary/unique.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"unique.d.ts","sourceRoot":"","sources":["../../src/vocabulary/unique.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGpC,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAKnD,CAAC"}
|
|
@@ -1,25 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* place in the entity, not about the values it accepts: `text({ max: 80 })` says what
|
|
7
|
-
* a slug looks like, `unique(...)` says there is only one of each. A shape cannot
|
|
8
|
-
* express it — judging a single value can never see the other rows.
|
|
9
|
-
*
|
|
10
|
-
* So the realization is the storage's, and only the storage's: the DDL emits the
|
|
11
|
-
* constraint, the database enforces it on every write, including writes Fougere never
|
|
12
|
-
* saw. A collision surfaces as the driver's error, not as a `validate()` failure.
|
|
13
|
-
*
|
|
14
|
-
* It also travels: `describe()` carries `role.unique` on the card, so a consumer in
|
|
15
|
-
* another language reads the same promise — one that is now kept.
|
|
16
|
-
*
|
|
17
|
-
* The group is `[]` — the empty member list denoting THIS field, because a field does not
|
|
18
|
-
* know its own key here: `slug` is named by the object literal `entity({...})` receives,
|
|
19
|
-
* one call up. Keeping it empty rather than filling it in later means nothing to remap
|
|
20
|
-
* when `rename()` moves the key, and one shape shared with the composite form.
|
|
21
|
-
*/
|
|
22
|
-
export function unique(field) {
|
|
23
|
-
return createField({ ...field, role: { ...field.role, unique: [[]] } });
|
|
24
|
-
}
|
|
1
|
+
import { vocabulary } from "./vocabulary.js";
|
|
2
|
+
import { Unique } from "../constraint/Unique.js";
|
|
3
|
+
export const unique = vocabulary("unique", (field) => ({
|
|
4
|
+
role: { rules: [...(field.role?.rules ?? []), new Unique([])] },
|
|
5
|
+
}));
|
|
25
6
|
//# sourceMappingURL=unique.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unique.js","sourceRoot":"","sources":["../../src/vocabulary/unique.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"unique.js","sourceRoot":"","sources":["../../src/vocabulary/unique.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD,MAAM,CAAC,MAAM,MAAM,GAAqC,UAAU,CAChE,QAAQ,EACR,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACV,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE;CAChE,CAAC,CACH,CAAC"}
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
* `auto()`, plus the update stamp — the canonical `updatedAt` (Prisma
|
|
4
|
-
* `@updatedAt`, Kysely-side `$onUpdate` equivalents). The only new fact is `update: 'now'`;
|
|
5
|
-
* shape and creation rule are auto()'s, stated once there.
|
|
6
|
-
*/
|
|
7
|
-
export declare function updated(): Field<Date, true>;
|
|
1
|
+
import { Field } from '../Field.js';
|
|
2
|
+
export declare function updated(): Field<Date>;
|
|
8
3
|
//# sourceMappingURL=updated.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updated.d.ts","sourceRoot":"","sources":["../../src/vocabulary/updated.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"updated.d.ts","sourceRoot":"","sources":["../../src/vocabulary/updated.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,wBAAgB,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,CAGrC"}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { created } from './created.js';
|
|
2
|
-
import { createField } from '../field/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* `auto()`, plus the update stamp — the canonical `updatedAt` (Prisma
|
|
5
|
-
* `@updatedAt`, Kysely-side `$onUpdate` equivalents). The only new fact is `update: 'now'`;
|
|
6
|
-
* shape and creation rule are auto()'s, stated once there.
|
|
7
|
-
*/
|
|
8
2
|
export function updated() {
|
|
9
3
|
const base = created();
|
|
10
|
-
return
|
|
4
|
+
return base.with({ lifecycle: { ...base.lifecycle, update: 'now' } });
|
|
11
5
|
}
|
|
12
6
|
//# sourceMappingURL=updated.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updated.js","sourceRoot":"","sources":["../../src/vocabulary/updated.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"updated.js","sourceRoot":"","sources":["../../src/vocabulary/updated.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,MAAM,UAAU,OAAO;IACrB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;AACxE,CAAC"}
|
package/dist/vocabulary/url.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type TextOptions } from './text.js';
|
|
2
|
-
import type { Field } from '../
|
|
3
|
-
/** A string holding a URL — `text({ format: 'uri' })` (JSON Schema's name), named. */
|
|
2
|
+
import type { Field } from '../Field.js';
|
|
4
3
|
export declare function url(opts?: Omit<TextOptions, 'format'>): Field<string>;
|
|
5
4
|
//# sourceMappingURL=url.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/vocabulary/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/vocabulary/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,wBAAgB,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAErE"}
|
package/dist/vocabulary/url.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/vocabulary/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAoB,MAAM,WAAW,CAAC;AAGnD,
|
|
1
|
+
{"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/vocabulary/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAoB,MAAM,WAAW,CAAC;AAGnD,MAAM,UAAU,GAAG,CAAC,IAAkC;IACpD,OAAO,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Field } from '../Field.js';
|
|
2
|
+
import type { FieldData } from '../Field.js';
|
|
3
|
+
export declare function vocabulary(name: string, states: (field: Field) => Partial<FieldData>): FieldWord;
|
|
4
|
+
export type FieldWord = (field: Field<any>) => Field<any>;
|
|
5
|
+
//# sourceMappingURL=vocabulary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vocabulary.d.ts","sourceRoot":"","sources":["../../src/vocabulary/vocabulary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAM7C,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,SAAS,CAAC,GAC3C,SAAS,CAEX;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { EXTENSION_AXES } from '../axis/Axis.js';
|
|
2
|
+
import { same } from '../same.js';
|
|
3
|
+
const MEMBER_SLOTS = [...EXTENSION_AXES.map((axis) => axis.slot), 'meta'];
|
|
4
|
+
export function vocabulary(name, states) {
|
|
5
|
+
return (field) => field.with(merge(name, field, states(field)));
|
|
6
|
+
}
|
|
7
|
+
function merge(name, field, stated) {
|
|
8
|
+
const out = {};
|
|
9
|
+
if ('shape' in stated)
|
|
10
|
+
out.shape = stated.shape;
|
|
11
|
+
for (const slot of MEMBER_SLOTS) {
|
|
12
|
+
const members = stated[slot];
|
|
13
|
+
if (members === undefined)
|
|
14
|
+
continue;
|
|
15
|
+
const held = field[slot];
|
|
16
|
+
if (typeof members !== 'object' || members === null || typeof held !== 'object') {
|
|
17
|
+
out[slot] = members;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
for (const [member, value] of Object.entries(members)) {
|
|
21
|
+
const previous = held?.[member];
|
|
22
|
+
if (previous === undefined || same(previous, value))
|
|
23
|
+
continue;
|
|
24
|
+
throw new Error(`vocabulary: \`${name}\` states ${slot}.${member} = ${JSON.stringify(value)}, but the ` +
|
|
25
|
+
`field already states ${JSON.stringify(previous)}. Apply one or the other, not both.`);
|
|
26
|
+
}
|
|
27
|
+
out[slot] = { ...held, ...members };
|
|
28
|
+
}
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=vocabulary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vocabulary.js","sourceRoot":"","sources":["../../src/vocabulary/vocabulary.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,YAAY,GAAG,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAU,CAAC;AAEnF,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,MAA4C;IAE5C,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAID,SAAS,KAAK,CAAC,IAAY,EAAE,KAAY,EAAE,MAA0B;IACnE,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,IAAI,OAAO,IAAI,MAAM;QAAE,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAEhD,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,OAAO,KAAK,SAAS;YAAE,SAAS;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAwC,CAAC;QAChE,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAChF,GAAG,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;YACpB,SAAS;QACX,CAAC;QACD,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACtD,MAAM,QAAQ,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC;YAChC,IAAI,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC;gBAAE,SAAS;YAC9D,MAAM,IAAI,KAAK,CACb,iBAAiB,IAAI,aAAa,IAAI,IAAI,MAAM,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY;gBACrF,wBAAwB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,qCAAqC,CACxF,CAAC;QACJ,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC;IACtC,CAAC;IACD,OAAO,GAAyB,CAAC;AACnC,CAAC"}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
* Close the field's OUTBOUND direction — accepted at create/patch, never
|
|
4
|
-
* emitted (the canonical password). `encodeFields` omits it and the adapters
|
|
5
|
-
* exclude it from their output types. The inbound direction (and its
|
|
6
|
-
* conversion) is untouched.
|
|
7
|
-
*/
|
|
8
|
-
export declare function writeOnly<T, A extends boolean>(field: Field<T, A>): Field<T, A>;
|
|
1
|
+
import { Field } from '../Field.js';
|
|
2
|
+
export declare const writeOnly: <T>(field: Field<T>) => Field<T>;
|
|
9
3
|
//# sourceMappingURL=writeOnly.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeOnly.d.ts","sourceRoot":"","sources":["../../src/vocabulary/writeOnly.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"writeOnly.d.ts","sourceRoot":"","sources":["../../src/vocabulary/writeOnly.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,eAAO,MAAM,SAAS,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAEpD,CAAC"}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* conversion) is untouched.
|
|
7
|
-
*/
|
|
8
|
-
export function writeOnly(field) {
|
|
9
|
-
return createField({ ...field, boundary: { ...declaredBoundary(field), out: 'closed' } });
|
|
10
|
-
}
|
|
1
|
+
import { vocabulary } from './vocabulary.js';
|
|
2
|
+
import { Boundary } from '../axis/boundary/Boundary.js';
|
|
3
|
+
export const writeOnly = vocabulary('writeOnly', (field) => ({
|
|
4
|
+
boundary: Boundary.declared(field).with({ out: 'closed' }),
|
|
5
|
+
}));
|
|
11
6
|
//# sourceMappingURL=writeOnly.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeOnly.js","sourceRoot":"","sources":["../../src/vocabulary/writeOnly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"writeOnly.js","sourceRoot":"","sources":["../../src/vocabulary/writeOnly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAGxD,MAAM,CAAC,MAAM,SAAS,GAAqC,UAAU,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC7F,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;CAC3D,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fougere/schema",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "The entity and its 4 axes — shape, role, lifecycle, boundary.
|
|
3
|
+
"version": "0.3.0-alpha.0",
|
|
4
|
+
"description": "The entity and its 4 axes — shape, role, lifecycle, boundary. One judge, edge-safe.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fougere",
|
|
7
7
|
"typescript",
|
package/dist/field/boundary.d.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import type { AnyField } from './field.js';
|
|
2
|
-
/**
|
|
3
|
-
* Axis 4 · boundary — HOW AND IN WHICH DIRECTION a value crosses the CLIENT frontier.
|
|
4
|
-
*
|
|
5
|
-
* ⚠️ SCOPE — this axis covers the client frontier ONLY. A direction is meaningless
|
|
6
|
-
* unless stated relative to a centre, and this one is relative to the domain facing a
|
|
7
|
-
* client: `in` parses a request, `out` renders a response. It does NOT cover storage —
|
|
8
|
-
* no storage adapter reads it, which is exactly why `bool`, `list`, `json` and a judged
|
|
9
|
-
* `date` cannot be written today (they reach the driver unconverted). The domain↔column
|
|
10
|
-
* conversion belongs to the storage adapter, and naming that second frontier is an open
|
|
11
|
-
* design question — see the axes study.
|
|
12
|
-
*
|
|
13
|
-
* The normal form is indexed by DIRECTION. Each direction carries one of the two facets
|
|
14
|
-
* of the same frontier:
|
|
15
|
-
* a conversion (`{ decode }` / `{ encode }`, a NAMED rule) or the permission
|
|
16
|
-
* token `'closed'` — read-only closes `in` (never accepted from a client),
|
|
17
|
-
* write-only closes `out` (never emitted, e.g. a password). A key absent →
|
|
18
|
-
* that direction is open, identity conversion. Declarative and named — never
|
|
19
|
-
* an opaque closure, so adapters stay able to read what a field does.
|
|
20
|
-
*
|
|
21
|
-
* Two directional registries (decoders, encoders) are the pure base; an alias is
|
|
22
|
-
* just a named pair. A field rarely declares a boundary: the default is DERIVED
|
|
23
|
-
* from `shape` (convention over config). A declared boundary overrides that
|
|
24
|
-
* default PER DIRECTION — closing `out` on a date field leaves the derived
|
|
25
|
-
* isoDate decode on `in` intact.
|
|
26
|
-
*/
|
|
27
|
-
/** Inbound: a supplied wire value → domain value. May fail (transformOrFail-style). */
|
|
28
|
-
export type Decoder = (value: unknown) => {
|
|
29
|
-
value: unknown;
|
|
30
|
-
} | {
|
|
31
|
-
error: string;
|
|
32
|
-
};
|
|
33
|
-
/** Outbound: a domain value → wire value. Total — a valid domain value always encodes. */
|
|
34
|
-
export type Encoder = (value: unknown) => unknown;
|
|
35
|
-
/** The normal form, indexed by direction. Either direction absent → open, identity. */
|
|
36
|
-
export interface Boundary {
|
|
37
|
-
in?: 'closed' | {
|
|
38
|
-
decode: string;
|
|
39
|
-
};
|
|
40
|
-
out?: 'closed' | {
|
|
41
|
-
encode: string;
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* What a field may carry on its `boundary` slot:
|
|
46
|
-
* - a string — an ALIAS, resolved to a {@link Boundary} in the alias registry
|
|
47
|
-
* - a {@link Boundary} — directional rules directly (allows asymmetry)
|
|
48
|
-
*
|
|
49
|
-
* The bare string literals are the built-in aliases; `(string & {})` keeps
|
|
50
|
-
* autocomplete on them while leaving the set open to `registerBoundaryAlias`.
|
|
51
|
-
*/
|
|
52
|
-
export type BoundaryRef = 'isoDate' | (string & {}) | Boundary;
|
|
53
|
-
export declare function registerDecoder(name: string, fn: Decoder): void;
|
|
54
|
-
export declare function registerEncoder(name: string, fn: Encoder): void;
|
|
55
|
-
/** Register a named boundary — the alias a field can reference. */
|
|
56
|
-
export declare function registerBoundaryAlias(name: string, boundary: Boundary): void;
|
|
57
|
-
/** The field's DECLARED boundary in normal form (alias resolved) — no derived default. */
|
|
58
|
-
export declare function declaredBoundary(field: AnyField): Boundary;
|
|
59
|
-
/**
|
|
60
|
-
* The field's EFFECTIVE boundary: declared rules win per direction, the
|
|
61
|
-
* shape-derived default fills the rest. This is the reader every consumer of
|
|
62
|
-
* the axis goes through — `boundaryOf(f).in === 'closed'` is the read-only
|
|
63
|
-
* test, `.out === 'closed'` the write-only one.
|
|
64
|
-
*/
|
|
65
|
-
export declare function boundaryOf(field: AnyField): Boundary;
|
|
66
|
-
/**
|
|
67
|
-
* A field's effective conversion functions. The permission facet is not read
|
|
68
|
-
* here: a `'closed'` direction converts as identity — its rejection/omission
|
|
69
|
-
* happens in the readers (validation, encode) BEFORE any conversion.
|
|
70
|
-
*
|
|
71
|
-
* A NAMED codec that no one registered throws, exactly like an unknown alias
|
|
72
|
-
* (`declaredBoundary`). It used to fall back to identity: a frond declared
|
|
73
|
-
* `{ decode: 'celsius' }`, the consumer never called `registerDecoder`, and the
|
|
74
|
-
* value arrived unconverted while the card said it had been converted — the same
|
|
75
|
-
* silent loss this repo measured on Remult (`validate: [null, null]`) and on
|
|
76
|
-
* zod v4 (a computed default frozen at export). One axis, two spellings, one
|
|
77
|
-
* failure mode.
|
|
78
|
-
*
|
|
79
|
-
* It throws where the conversion is needed, not at boot: nothing walks every
|
|
80
|
-
* field at startup. Loud and late beats silent and never.
|
|
81
|
-
*/
|
|
82
|
-
export declare function resolveBoundary(field: AnyField): {
|
|
83
|
-
decode: Decoder;
|
|
84
|
-
encode: Encoder;
|
|
85
|
-
};
|
|
86
|
-
//# sourceMappingURL=boundary.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../../src/field/boundary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,uFAAuF;AACvF,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AACjF,0FAA0F;AAC1F,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;AAElD,uFAAuF;AACvF,MAAM,WAAW,QAAQ;IACvB,EAAE,CAAC,EAAE,QAAQ,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,GAAG,CAAC,EAAE,QAAQ,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC;AAQ/D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI,CAE/D;AACD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI,CAE/D;AACD,mEAAmE;AACnE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAE5E;AAgCD,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAS1D;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAIpD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAMrF"}
|