@fougere/schema 0.2.0-alpha.2 → 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/{hints.js → EntityDeclarations.js} +1 -5
- 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/schema.d.ts → Schema.d.ts} +27 -34
- package/dist/Schema.d.ts.map +1 -0
- package/dist/{schema/schema.js → Schema.js} +49 -59
- 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/{field/shape.js → axis/shape/Shape.js} +10 -25
- 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 -19
- package/dist/entity.d.ts.map +1 -1
- package/dist/entity.js +13 -39
- package/dist/entity.js.map +1 -1
- package/dist/index.d.ts +54 -37
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -48
- 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 -6
- package/dist/name.d.ts.map +1 -1
- package/dist/name.js +3 -6
- 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 +1 -1
- package/dist/vocabulary/bool.js.map +1 -1
- package/dist/vocabulary/created.d.ts +1 -5
- package/dist/vocabulary/created.d.ts.map +1 -1
- package/dist/vocabulary/created.js +1 -5
- 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 +1 -1
- 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 -6
- package/dist/vocabulary/immutable.d.ts.map +1 -1
- package/dist/vocabulary/immutable.js +4 -7
- package/dist/vocabulary/immutable.js.map +1 -1
- package/dist/vocabulary/indexed.d.ts +2 -7
- package/dist/vocabulary/indexed.d.ts.map +1 -1
- package/dist/vocabulary/indexed.js +2 -8
- package/dist/vocabulary/indexed.js.map +1 -1
- package/dist/vocabulary/json.d.ts +2 -10
- package/dist/vocabulary/json.d.ts.map +1 -1
- package/dist/vocabulary/json.js +10 -7
- package/dist/vocabulary/json.js.map +1 -1
- package/dist/vocabulary/list.d.ts +1 -12
- package/dist/vocabulary/list.d.ts.map +1 -1
- package/dist/vocabulary/list.js +1 -14
- package/dist/vocabulary/list.js.map +1 -1
- package/dist/vocabulary/many.d.ts +2 -5
- package/dist/vocabulary/many.d.ts.map +1 -1
- package/dist/vocabulary/many.js +2 -5
- package/dist/vocabulary/many.js.map +1 -1
- package/dist/vocabulary/nullable.d.ts +2 -6
- package/dist/vocabulary/nullable.d.ts.map +1 -1
- package/dist/vocabulary/nullable.js +5 -8
- 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 +1 -1
- 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 +1 -1
- 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 +2 -15
- package/dist/vocabulary/primary.d.ts.map +1 -1
- package/dist/vocabulary/primary.js +3 -9
- package/dist/vocabulary/primary.js.map +1 -1
- package/dist/vocabulary/readOnly.d.ts +2 -6
- package/dist/vocabulary/readOnly.d.ts.map +1 -1
- package/dist/vocabulary/readOnly.js +5 -8
- 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 +2 -7
- 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 +1 -1
- package/dist/vocabulary/text.js.map +1 -1
- package/dist/vocabulary/unique.d.ts +2 -12
- package/dist/vocabulary/unique.d.ts.map +1 -1
- package/dist/vocabulary/unique.js +5 -13
- package/dist/vocabulary/unique.js.map +1 -1
- package/dist/vocabulary/updated.d.ts +1 -6
- package/dist/vocabulary/updated.d.ts.map +1 -1
- package/dist/vocabulary/updated.js +0 -5
- 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 -6
- package/dist/vocabulary/writeOnly.d.ts.map +1 -1
- package/dist/vocabulary/writeOnly.js +5 -8
- package/dist/vocabulary/writeOnly.js.map +1 -1
- package/package.json +1 -1
- package/dist/field/boundary.d.ts +0 -69
- package/dist/field/boundary.d.ts.map +0 -1
- package/dist/field/boundary.js +0 -82
- package/dist/field/boundary.js.map +0 -1
- package/dist/field/field.d.ts +0 -21
- package/dist/field/field.d.ts.map +0 -1
- package/dist/field/field.js +0 -24
- package/dist/field/field.js.map +0 -1
- package/dist/field/format.d.ts +0 -29
- package/dist/field/format.d.ts.map +0 -1
- package/dist/field/format.js +0 -24
- package/dist/field/format.js.map +0 -1
- package/dist/field/index.d.ts +0 -8
- package/dist/field/index.d.ts.map +0 -1
- package/dist/field/index.js +0 -10
- package/dist/field/index.js.map +0 -1
- package/dist/field/lifecycle.d.ts +0 -31
- package/dist/field/lifecycle.d.ts.map +0 -1
- package/dist/field/lifecycle.js +0 -20
- package/dist/field/lifecycle.js.map +0 -1
- package/dist/field/meta.d.ts +0 -5
- package/dist/field/meta.d.ts.map +0 -1
- package/dist/field/meta.js +0 -5
- package/dist/field/meta.js.map +0 -1
- package/dist/field/role.d.ts +0 -47
- package/dist/field/role.d.ts.map +0 -1
- package/dist/field/role.js +0 -35
- package/dist/field/role.js.map +0 -1
- package/dist/field/shape.d.ts +0 -89
- package/dist/field/shape.d.ts.map +0 -1
- package/dist/field/shape.js.map +0 -1
- package/dist/hints.d.ts +0 -28
- package/dist/hints.d.ts.map +0 -1
- package/dist/hints.js.map +0 -1
- package/dist/projections/card.d.ts +0 -98
- 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 -131
- 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 -24
- package/dist/projections/io.d.ts.map +0 -1
- package/dist/projections/io.js +0 -46
- package/dist/projections/io.js.map +0 -1
- package/dist/projections/lifecycle.d.ts +0 -29
- package/dist/projections/lifecycle.d.ts.map +0 -1
- package/dist/projections/lifecycle.js +0 -93
- package/dist/projections/lifecycle.js.map +0 -1
- package/dist/projections/reconstruct.d.ts +0 -31
- package/dist/projections/reconstruct.d.ts.map +0 -1
- package/dist/projections/reconstruct.js +0 -146
- package/dist/projections/reconstruct.js.map +0 -1
- package/dist/projections/source.d.ts +0 -18
- package/dist/projections/source.d.ts.map +0 -1
- package/dist/projections/source.js +0 -18
- 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 -37
- package/dist/projections/typescript.d.ts.map +0 -1
- package/dist/projections/typescript.js +0 -157
- package/dist/projections/typescript.js.map +0 -1
- package/dist/schema/index.d.ts +0 -3
- package/dist/schema/index.d.ts.map +0 -1
- package/dist/schema/index.js +0 -2
- package/dist/schema/index.js.map +0 -1
- package/dist/schema/schema.d.ts.map +0 -1
- package/dist/schema/schema.js.map +0 -1
- package/dist/schema/view.d.ts +0 -26
- package/dist/schema/view.d.ts.map +0 -1
- package/dist/schema/view.js +0 -2
- package/dist/schema/view.js.map +0 -1
- package/dist/unique.d.ts +0 -40
- package/dist/unique.d.ts.map +0 -1
- package/dist/unique.js +0 -57
- package/dist/unique.js.map +0 -1
- package/dist/validation/index.d.ts +0 -4
- package/dist/validation/index.d.ts.map +0 -1
- package/dist/validation/index.js +0 -2
- package/dist/validation/index.js.map +0 -1
- package/dist/validation/judge.d.ts +0 -55
- package/dist/validation/judge.d.ts.map +0 -1
- package/dist/validation/judge.js +0 -351
- package/dist/validation/judge.js.map +0 -1
- package/dist/validation/options.d.ts +0 -6
- package/dist/validation/options.d.ts.map +0 -1
- package/dist/validation/options.js +0 -3
- package/dist/validation/options.js.map +0 -1
- package/dist/validation/result.d.ts +0 -20
- package/dist/validation/result.d.ts.map +0 -1
- package/dist/validation/result.js +0 -3
- package/dist/validation/result.js.map +0 -1
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import type { BoundaryRef, Lifecycle, Relation, Role, Shape } from '../field/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* The portable schema descriptor — an entity's "carte d'identité".
|
|
4
|
-
*
|
|
5
|
-
* A JSON Schema document: the `shape` axis at the top level, the three axes JSON Schema
|
|
6
|
-
* cannot express under one `x-fougere` key per field. The normal forms ARE the wire form —
|
|
7
|
-
* lifecycle and boundary travel verbatim, no descriptor twin to maintain.
|
|
8
|
-
*
|
|
9
|
-
* What cannot travel becomes a NAME, re-resolved against the consumer's registry: a
|
|
10
|
-
* relation's thunk, a custom generator, a boundary codec.
|
|
11
|
-
*/
|
|
12
|
-
/** JSON Schema's `type` values, plus `null` for the nullable union form. */
|
|
13
|
-
export type JsonSchemaType = 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | 'null';
|
|
14
|
-
/**
|
|
15
|
-
* A shape's constraint keywords, all optional and flattened — the union's branches merged.
|
|
16
|
-
* `type` is NOT here: intersecting the branches would make the discriminant impossible,
|
|
17
|
-
* and the wire genuinely allows a form memory never produces (see below).
|
|
18
|
-
*/
|
|
19
|
-
type ShapeKeywords = UnionToIntersection<KeywordsOf<Shape>>;
|
|
20
|
-
type KeywordsOf<S> = S extends unknown ? Partial<Omit<S, 'type' | 'items' | 'properties'>> : never;
|
|
21
|
-
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
22
|
-
/**
|
|
23
|
-
* One field as a JSON Schema property. The shape keywords sit at the top level
|
|
24
|
-
* (so an external JSON Schema tool reads them directly); the Fougère-only axes
|
|
25
|
-
* live under `x-fougere`. A nullable field folds into the union `type: ['T','null']`.
|
|
26
|
-
*/
|
|
27
|
-
export type FieldDescriptor = ShapeKeywords & {
|
|
28
|
-
/**
|
|
29
|
-
* WIDER than `Shape`, which only ever emits `T` or the canonical `[T,'null']` tuple.
|
|
30
|
-
* A card can come from another language, so the door judges the form; `reconstruct`
|
|
31
|
-
* refuses what it cannot represent rather than pretending it read it.
|
|
32
|
-
*/
|
|
33
|
-
type?: JsonSchemaType | JsonSchemaType[];
|
|
34
|
-
/** A value list's element shape (`list(text())`). A bare `many` relation has none. */
|
|
35
|
-
items?: FieldDescriptor;
|
|
36
|
-
/** An embedded value object (`json(Entity)`): the nested shape-only properties. */
|
|
37
|
-
properties?: Record<string, FieldDescriptor>;
|
|
38
|
-
/** JSON Schema standard keyword — mirrors the field's `description`. */
|
|
39
|
-
description?: string;
|
|
40
|
-
'x-fougere'?: FieldExtension;
|
|
41
|
-
};
|
|
42
|
-
/** The three axes JSON Schema can't express, namespaced under a field's `x-fougere`. */
|
|
43
|
-
export interface FieldExtension {
|
|
44
|
-
role?: RoleDescriptor;
|
|
45
|
-
/** The normal form travels verbatim — named tokens, pure JSON. */
|
|
46
|
-
lifecycle?: Lifecycle;
|
|
47
|
-
boundary?: BoundaryRef;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* The role, with its one unportable member replaced: `unique` names its members on the
|
|
51
|
-
* wire, where in memory a lone `unique()` holds `[]` — a field does not know its own key,
|
|
52
|
-
* a reader of the card must not have to guess it.
|
|
53
|
-
*
|
|
54
|
-
* Names what it KEEPS, like `describeRole` and `reconstructRole` do. Two of the four
|
|
55
|
-
* members do not travel as they are, so portability is not the default a new one gets.
|
|
56
|
-
*/
|
|
57
|
-
export type RoleDescriptor = Pick<Role, 'primary' | 'index'> & {
|
|
58
|
-
unique?: string[][];
|
|
59
|
-
relation?: RelationDescriptor;
|
|
60
|
-
};
|
|
61
|
-
/** The relation, with its thunk replaced: the target is a NAME. */
|
|
62
|
-
export type RelationDescriptor = Pick<Relation, 'kind' | 'onDelete'> & {
|
|
63
|
-
to: string;
|
|
64
|
-
};
|
|
65
|
-
/**
|
|
66
|
-
* A whole entity as a JSON Schema object document. `version`/`vendor` mirror Standard
|
|
67
|
-
* Schema's own (versioned + vendored), under `x-` extension keywords so the document
|
|
68
|
-
* stays a valid JSON Schema for external tooling.
|
|
69
|
-
*/
|
|
70
|
-
export interface SchemaDescriptor {
|
|
71
|
-
title?: string;
|
|
72
|
-
type: 'object';
|
|
73
|
-
properties: Record<string, FieldDescriptor>;
|
|
74
|
-
/**
|
|
75
|
-
* Create-time semantics: the names a caller MUST supply — no `lifecycle.create`
|
|
76
|
-
* rule answers absence (nor a `many` relation, absent → `[]`). Presence only:
|
|
77
|
-
* a nullable-but-required field IS listed (supply `null`, don't omit the key).
|
|
78
|
-
* Narrower than JSON Schema's context-free `required`: it answers "what must a
|
|
79
|
-
* creation payload carry?", not "what is always present when read?".
|
|
80
|
-
*/
|
|
81
|
-
required?: string[];
|
|
82
|
-
'x-fougere-version': 1;
|
|
83
|
-
'x-fougere-vendor': 'fougere';
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* A self-contained set of entity cards. Every entity lives under `$defs`, keyed by name,
|
|
87
|
-
* and a relation's `to` is that key — a pointer, never an inlined sub-schema, so
|
|
88
|
-
* `Post → Author → Post` is two references and not infinite nesting.
|
|
89
|
-
*/
|
|
90
|
-
export interface SchemaBundle {
|
|
91
|
-
$defs: Record<string, SchemaDescriptor>;
|
|
92
|
-
'x-fougere-version': 1;
|
|
93
|
-
'x-fougere-vendor': 'fougere';
|
|
94
|
-
}
|
|
95
|
-
/** Drop keys whose value is `undefined`, so the descriptor stays clean JSON. */
|
|
96
|
-
export declare function clean<T extends Record<string, unknown>>(obj: T): T;
|
|
97
|
-
export {};
|
|
98
|
-
//# sourceMappingURL=card.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../src/projections/card.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEvF;;;;;;;;;GASG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,cAAc,GACtB,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,SAAS,GACT,QAAQ,GACR,OAAO,GACP,MAAM,CAAC;AAEX;;;;GAIG;AACH,KAAK,aAAa,GAAG,mBAAmB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;AAI5D,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,YAAY,CAAC,CAAC,GAAG,KAAK,CAAC;AACnG,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC;AAEpH;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG;IAC5C;;;;OAIG;IACH,IAAI,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAAC;IACzC,sFAAsF;IACtF,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B,CAAC;AAEF,wFAAwF;AACxF,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,kEAAkE;IAClE,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,WAAW,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG;IAC7D,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B,CAAC;AAEF,mEAAmE;AACnE,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,mBAAmB,EAAE,CAAC,CAAC;IACvB,kBAAkB,EAAE,SAAS,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACxC,mBAAmB,EAAE,CAAC,CAAC;IACvB,kBAAkB,EAAE,SAAS,CAAC;CAC/B;AAED,gFAAgF;AAChF,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAGlE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"card.js","sourceRoot":"","sources":["../../src/projections/card.ts"],"names":[],"mappings":"AAgHA,gFAAgF;AAChF,MAAM,UAAU,KAAK,CAAoC,GAAM;IAC7D,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;IAChF,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { SchemaView } from '../schema/index.js';
|
|
2
|
-
import { type SchemaBundle, type SchemaDescriptor } from './card.js';
|
|
3
|
-
/**
|
|
4
|
-
* Produce the portable card for a schema — THE single canonical serialiser
|
|
5
|
-
* (the hand-rolled copies in adapters call this). `name` titles the entity; it
|
|
6
|
-
* falls back to the schema's source/class name when omitted.
|
|
7
|
-
*/
|
|
8
|
-
export declare function describe(schema: SchemaView, name?: string): SchemaDescriptor;
|
|
9
|
-
/**
|
|
10
|
-
* The name of the schema a view came from — `Post` for `Post`, and `Post` for
|
|
11
|
-
* `Post.pick('title')` too, since a derivation carries its `source`.
|
|
12
|
-
*
|
|
13
|
-
* Exported because two projections need the SAME answer: the card titles an entity with it,
|
|
14
|
-
* and GraphQL names a field's enum type with it — an enum named after the view would give
|
|
15
|
-
* `Post.status` and `CreatePostInput.status` two incompatible types for one set of values.
|
|
16
|
-
*/
|
|
17
|
-
export declare function sourceNameOf(schema: SchemaView): string | undefined;
|
|
18
|
-
/**
|
|
19
|
-
* Describe a whole set of entities as one self-contained bundle (the `$defs`
|
|
20
|
-
* document). Accepts a name→schema record or an array (names taken from the
|
|
21
|
-
* schemas). Keys carry the registration key, the same spelling `describe` gives a
|
|
22
|
-
* relation's `to`, so `$ref`-by-name resolves cleanly in {@link reconstructSet}.
|
|
23
|
-
*/
|
|
24
|
-
export declare function describeSet(schemas: Record<string, SchemaView> | SchemaView[]): SchemaBundle;
|
|
25
|
-
//# sourceMappingURL=describe.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/projections/describe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,EAML,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,WAAW,CAAC;AAmEnB;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAiB5E;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAGnE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,UAAU,EAAE,GAAG,YAAY,CAU5F"}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { uniqueMembers, boundaryOf } from '../field/index.js';
|
|
2
|
-
import { registrationKeyOf } from '../name.js';
|
|
3
|
-
import { clean, } from './card.js';
|
|
4
|
-
// ─── describe — schema → card (the single canonical serialiser) ────
|
|
5
|
-
/**
|
|
6
|
-
* A caller must supply this field: no create rule answers absence, and it is not
|
|
7
|
-
* a `many` relation (absent → `[]`). Presence only — nullability is the OTHER
|
|
8
|
-
* axis: a `nullable()` field stays required (the caller may supply `null`, not
|
|
9
|
-
* omit the key), exactly what `validateFields` enforces.
|
|
10
|
-
*/
|
|
11
|
-
function isRequired(field) {
|
|
12
|
-
// Read `boundary` for the same reason `validateFields` does: a server-owned
|
|
13
|
-
// field is one a caller may never supply, so listing it as required states a
|
|
14
|
-
// demand the door then refuses with `Read-only`. Same stance as OpenAPI's
|
|
15
|
-
// readOnly+required, and the two readers now answer from the same axis.
|
|
16
|
-
if (boundaryOf(field).in === 'closed')
|
|
17
|
-
return false;
|
|
18
|
-
if (field.lifecycle?.create !== undefined)
|
|
19
|
-
return false;
|
|
20
|
-
if (field.role?.relation?.kind === 'many')
|
|
21
|
-
return false;
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
function describeRole(role, key) {
|
|
25
|
-
const out = {};
|
|
26
|
-
if (role.primary)
|
|
27
|
-
out.primary = true;
|
|
28
|
-
// Members are spelled out on the wire: in memory a lone `unique()` holds the empty
|
|
29
|
-
// self-reference (a field cannot name its own key), and a consumer has no way to know
|
|
30
|
-
// which field a group hangs on. `key` is that missing half, so it is resolved here.
|
|
31
|
-
if (role.unique?.length)
|
|
32
|
-
out.unique = role.unique.map((group) => uniqueMembers(group, key));
|
|
33
|
-
if (role.index)
|
|
34
|
-
out.index = true;
|
|
35
|
-
if (role.relation) {
|
|
36
|
-
out.relation = clean({
|
|
37
|
-
to: registrationKeyOf(role.relation.to().name ?? ''), // thunk → name
|
|
38
|
-
kind: role.relation.kind,
|
|
39
|
-
onDelete: role.relation.onDelete,
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
return Object.keys(out).length ? out : undefined;
|
|
43
|
-
}
|
|
44
|
-
function describeExtension(field, key) {
|
|
45
|
-
const ext = {};
|
|
46
|
-
if (field.role)
|
|
47
|
-
ext.role = describeRole(field.role, key);
|
|
48
|
-
// The normal forms are named tokens, pure JSON — they travel verbatim
|
|
49
|
-
// (a custom generator travels by NAME, re-resolved against the consumer's registry).
|
|
50
|
-
if (field.lifecycle)
|
|
51
|
-
ext.lifecycle = field.lifecycle;
|
|
52
|
-
// Carry only an explicit override; the derived default (date → isoDate) is
|
|
53
|
-
// re-derived from `shape.format` on reconstruction (convention over config).
|
|
54
|
-
if (field.boundary !== undefined)
|
|
55
|
-
ext.boundary = field.boundary;
|
|
56
|
-
clean(ext);
|
|
57
|
-
return Object.keys(ext).length ? ext : undefined;
|
|
58
|
-
}
|
|
59
|
-
function describeField(field, key) {
|
|
60
|
-
const out = {};
|
|
61
|
-
// Shape is already JSON Schema's vocabulary — nullability included, as the
|
|
62
|
-
// `[T,'null']` type union — so its keywords copy verbatim (an embedded object's
|
|
63
|
-
// `properties`/`required` too, themselves shape-only).
|
|
64
|
-
for (const [key, value] of Object.entries(field.shape)) {
|
|
65
|
-
if (value === undefined)
|
|
66
|
-
continue;
|
|
67
|
-
out[key] = value;
|
|
68
|
-
}
|
|
69
|
-
if (field.meta?.description)
|
|
70
|
-
out.description = field.meta.description;
|
|
71
|
-
const ext = describeExtension(field, key);
|
|
72
|
-
if (ext)
|
|
73
|
-
out['x-fougere'] = ext;
|
|
74
|
-
return out;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Produce the portable card for a schema — THE single canonical serialiser
|
|
78
|
-
* (the hand-rolled copies in adapters call this). `name` titles the entity; it
|
|
79
|
-
* falls back to the schema's source/class name when omitted.
|
|
80
|
-
*/
|
|
81
|
-
export function describe(schema, name) {
|
|
82
|
-
const properties = {};
|
|
83
|
-
const required = [];
|
|
84
|
-
for (const [key, field] of Object.entries(schema.getFields())) {
|
|
85
|
-
properties[key] = describeField(field, key);
|
|
86
|
-
if (isRequired(field))
|
|
87
|
-
required.push(key);
|
|
88
|
-
}
|
|
89
|
-
const descriptor = {
|
|
90
|
-
type: 'object',
|
|
91
|
-
properties,
|
|
92
|
-
'x-fougere-version': 1,
|
|
93
|
-
'x-fougere-vendor': 'fougere',
|
|
94
|
-
};
|
|
95
|
-
const title = name ?? sourceNameOf(schema);
|
|
96
|
-
if (title)
|
|
97
|
-
descriptor.title = title;
|
|
98
|
-
if (required.length)
|
|
99
|
-
descriptor.required = required;
|
|
100
|
-
return descriptor;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* The name of the schema a view came from — `Post` for `Post`, and `Post` for
|
|
104
|
-
* `Post.pick('title')` too, since a derivation carries its `source`.
|
|
105
|
-
*
|
|
106
|
-
* Exported because two projections need the SAME answer: the card titles an entity with it,
|
|
107
|
-
* and GraphQL names a field's enum type with it — an enum named after the view would give
|
|
108
|
-
* `Post.status` and `CreatePostInput.status` two incompatible types for one set of values.
|
|
109
|
-
*/
|
|
110
|
-
export function sourceNameOf(schema) {
|
|
111
|
-
const s = schema;
|
|
112
|
-
return s.source?.name ?? s.name;
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Describe a whole set of entities as one self-contained bundle (the `$defs`
|
|
116
|
-
* document). Accepts a name→schema record or an array (names taken from the
|
|
117
|
-
* schemas). Keys carry the registration key, the same spelling `describe` gives a
|
|
118
|
-
* relation's `to`, so `$ref`-by-name resolves cleanly in {@link reconstructSet}.
|
|
119
|
-
*/
|
|
120
|
-
export function describeSet(schemas) {
|
|
121
|
-
const entries = Array.isArray(schemas)
|
|
122
|
-
? schemas.map((s) => [sourceNameOf(s) ?? '', s])
|
|
123
|
-
: Object.entries(schemas);
|
|
124
|
-
const $defs = {};
|
|
125
|
-
for (const [name, schema] of entries) {
|
|
126
|
-
const key = registrationKeyOf(name);
|
|
127
|
-
$defs[key] = describe(schema, key);
|
|
128
|
-
}
|
|
129
|
-
return { $defs, 'x-fougere-version': 1, 'x-fougere-vendor': 'fougere' };
|
|
130
|
-
}
|
|
131
|
-
//# sourceMappingURL=describe.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"describe.js","sourceRoot":"","sources":["../../src/projections/describe.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Fields } from '../field/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Egress: encode a domain record into its wire form, field by field — the dual of
|
|
4
|
-
* `validateFields` (which decodes on ingress). A write-only field (boundary
|
|
5
|
-
* `out: 'closed'`, e.g. a password) is OMITTED — it never crosses outbound.
|
|
6
|
-
* Keys absent from `fields` (e.g. presenter computed fields) pass through
|
|
7
|
-
* untouched; null/undefined are left as-is.
|
|
8
|
-
* Shallow by design: a relation's nested rows are not deep-encoded here.
|
|
9
|
-
*/
|
|
10
|
-
export declare function encodeFields(fields: Fields, record: Record<string, unknown>): Record<string, unknown>;
|
|
11
|
-
//# sourceMappingURL=encode.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../src/projections/encode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUrG"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { boundaryOf, resolveBoundary } from '../field/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Egress: encode a domain record into its wire form, field by field — the dual of
|
|
4
|
-
* `validateFields` (which decodes on ingress). A write-only field (boundary
|
|
5
|
-
* `out: 'closed'`, e.g. a password) is OMITTED — it never crosses outbound.
|
|
6
|
-
* Keys absent from `fields` (e.g. presenter computed fields) pass through
|
|
7
|
-
* untouched; null/undefined are left as-is.
|
|
8
|
-
* Shallow by design: a relation's nested rows are not deep-encoded here.
|
|
9
|
-
*/
|
|
10
|
-
export function encodeFields(fields, record) {
|
|
11
|
-
const out = { ...record };
|
|
12
|
-
for (const [key, field] of Object.entries(fields)) {
|
|
13
|
-
if (!(key in record))
|
|
14
|
-
continue;
|
|
15
|
-
if (boundaryOf(field).out === 'closed') {
|
|
16
|
-
delete out[key];
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
19
|
-
const value = record[key];
|
|
20
|
-
if (value === null || value === undefined)
|
|
21
|
-
continue;
|
|
22
|
-
out[key] = resolveBoundary(field).encode(value);
|
|
23
|
-
}
|
|
24
|
-
return out;
|
|
25
|
-
}
|
|
26
|
-
//# sourceMappingURL=encode.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"encode.js","sourceRoot":"","sources":["../../src/projections/encode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEhE;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,MAA+B;IAC1E,MAAM,GAAG,GAA4B,EAAE,GAAG,MAAM,EAAE,CAAC;IACnD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC;YAAE,SAAS;QAC/B,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAAC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QACtE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QACpD,GAAG,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/projections/io.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { Fields } from '../field/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* The two dual projections of a field set onto a client surface — membership only. The
|
|
4
|
-
* create/patch MODE changes omissibility, which the view carries, never membership.
|
|
5
|
-
*
|
|
6
|
-
* ⚠️ The audience lives here and not in the data: no axis says "client". Surfaces are
|
|
7
|
-
* supposed to read these two functions, and the GraphQL input, the judge and the CLI each
|
|
8
|
-
* restate the rules with a different set — the judge being the most permissive.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Ingress: what a CLIENT may supply. Excluded —
|
|
12
|
-
* - `role.primary` → identity is system-owned
|
|
13
|
-
* - `lifecycle.create === 'now'` → managed timestamps are stamped, not supplied
|
|
14
|
-
* - `role.relation.kind 'many'` → the collection lives on the other side
|
|
15
|
-
* - `boundary.in === 'closed'` → read-only, never accepted from a client
|
|
16
|
-
*/
|
|
17
|
-
export declare function inputFields(fields: Fields): Fields;
|
|
18
|
-
/**
|
|
19
|
-
* Egress: what a CLIENT may read. Excluded —
|
|
20
|
-
* - `boundary.out === 'closed'` → write-only (password), never emitted
|
|
21
|
-
* (`encodeFields` also omits them at runtime; types and payloads agree.)
|
|
22
|
-
*/
|
|
23
|
-
export declare function outputFields(fields: Fields): Fields;
|
|
24
|
-
//# sourceMappingURL=io.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/projections/io.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAUlD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOnD"}
|
package/dist/projections/io.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { boundaryOf } from '../field/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* The two dual projections of a field set onto a client surface — membership only. The
|
|
4
|
-
* create/patch MODE changes omissibility, which the view carries, never membership.
|
|
5
|
-
*
|
|
6
|
-
* ⚠️ The audience lives here and not in the data: no axis says "client". Surfaces are
|
|
7
|
-
* supposed to read these two functions, and the GraphQL input, the judge and the CLI each
|
|
8
|
-
* restate the rules with a different set — the judge being the most permissive.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Ingress: what a CLIENT may supply. Excluded —
|
|
12
|
-
* - `role.primary` → identity is system-owned
|
|
13
|
-
* - `lifecycle.create === 'now'` → managed timestamps are stamped, not supplied
|
|
14
|
-
* - `role.relation.kind 'many'` → the collection lives on the other side
|
|
15
|
-
* - `boundary.in === 'closed'` → read-only, never accepted from a client
|
|
16
|
-
*/
|
|
17
|
-
export function inputFields(fields) {
|
|
18
|
-
const result = {};
|
|
19
|
-
for (const [name, field] of Object.entries(fields)) {
|
|
20
|
-
if (field.role?.primary)
|
|
21
|
-
continue;
|
|
22
|
-
if (field.lifecycle?.create === 'now')
|
|
23
|
-
continue;
|
|
24
|
-
if (field.role?.relation?.kind === 'many')
|
|
25
|
-
continue;
|
|
26
|
-
if (boundaryOf(field).in === 'closed')
|
|
27
|
-
continue;
|
|
28
|
-
result[name] = field;
|
|
29
|
-
}
|
|
30
|
-
return result;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Egress: what a CLIENT may read. Excluded —
|
|
34
|
-
* - `boundary.out === 'closed'` → write-only (password), never emitted
|
|
35
|
-
* (`encodeFields` also omits them at runtime; types and payloads agree.)
|
|
36
|
-
*/
|
|
37
|
-
export function outputFields(fields) {
|
|
38
|
-
const result = {};
|
|
39
|
-
for (const [name, field] of Object.entries(fields)) {
|
|
40
|
-
if (boundaryOf(field).out === 'closed')
|
|
41
|
-
continue;
|
|
42
|
-
result[name] = field;
|
|
43
|
-
}
|
|
44
|
-
return result;
|
|
45
|
-
}
|
|
46
|
-
//# sourceMappingURL=io.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/projections/io.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,MAAM,MAAM,GAAW,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,IAAI,KAAK,CAAC,IAAI,EAAE,OAAO;YAAE,SAAS;QAClC,IAAI,KAAK,CAAC,SAAS,EAAE,MAAM,KAAK,KAAK;YAAE,SAAS;QAChD,IAAI,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,KAAK,MAAM;YAAE,SAAS;QACpD,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,QAAQ;YAAE,SAAS;QAChD,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,MAAM,MAAM,GAAW,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,QAAQ;YAAE,SAAS;QACjD,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The lifecycle axis, realized — once, for every storage.
|
|
3
|
-
*
|
|
4
|
-
* The judge answers "is this value legal" and never fills a hole; filling it — stamp
|
|
5
|
-
* `'now'`, apply `{ value }`, call `{ generate }` — belongs to the storage at the point of
|
|
6
|
-
* persistence. Shipping the rule without its realization made each storage rewrite it, and
|
|
7
|
-
* they drifted: one entity with a `default` answered `'draft'` on SQL and `undefined` on
|
|
8
|
-
* Mongo. `update: 'forbidden'` is NOT here — refusing is a judgment.
|
|
9
|
-
*/
|
|
10
|
-
import { type Fields } from '../field/index.js';
|
|
11
|
-
type Row = Record<string, unknown>;
|
|
12
|
-
/**
|
|
13
|
-
* Fill what the entity says the system writes at creation.
|
|
14
|
-
*
|
|
15
|
-
* A value the caller supplied is never touched, including `null` — presence is the
|
|
16
|
-
* test, not truthiness, so `archivedAt: null` stays null rather than being re-filled.
|
|
17
|
-
*
|
|
18
|
-
* `'now'` produces a `Date`, the value the field declares. The storage converts it if
|
|
19
|
-
* its driver needs something else (`schema-sql/src/values.ts` does exactly that) —
|
|
20
|
-
* which is the same direction every other value travels.
|
|
21
|
-
*/
|
|
22
|
-
export declare function applyCreate(fields: Fields, input: Row): Row;
|
|
23
|
-
/**
|
|
24
|
-
* Fill what the entity says the system writes at every update — `updated()`, and
|
|
25
|
-
* nothing else. A supplied value wins, same rule as create.
|
|
26
|
-
*/
|
|
27
|
-
export declare function applyUpdate(fields: Fields, patch: Row): Row;
|
|
28
|
-
export {};
|
|
29
|
-
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/projections/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAsC,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGpF,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAsBnC;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,GAAG,CAqB3D;AAgBD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,GAAG,CAS3D"}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The lifecycle axis, realized — once, for every storage.
|
|
3
|
-
*
|
|
4
|
-
* The judge answers "is this value legal" and never fills a hole; filling it — stamp
|
|
5
|
-
* `'now'`, apply `{ value }`, call `{ generate }` — belongs to the storage at the point of
|
|
6
|
-
* persistence. Shipping the rule without its realization made each storage rewrite it, and
|
|
7
|
-
* they drifted: one entity with a `default` answered `'draft'` on SQL and `undefined` on
|
|
8
|
-
* Mongo. `update: 'forbidden'` is NOT here — refusing is a judgment.
|
|
9
|
-
*/
|
|
10
|
-
import { resolveCustomGenerator } from '../field/index.js';
|
|
11
|
-
import { createId } from '@paralleldrive/cuid2';
|
|
12
|
-
/** Resolve a generator TOKEN to a function — a registered name wins over a built-in. */
|
|
13
|
-
function generatorFor(ref) {
|
|
14
|
-
const custom = resolveCustomGenerator(ref);
|
|
15
|
-
if (custom)
|
|
16
|
-
return custom;
|
|
17
|
-
switch (ref) {
|
|
18
|
-
case 'cuid2': return createId;
|
|
19
|
-
case 'uuid': return () => globalThis.crypto.randomUUID();
|
|
20
|
-
case 'nanoid': {
|
|
21
|
-
return () => {
|
|
22
|
-
const bytes = new Uint8Array(21);
|
|
23
|
-
globalThis.crypto.getRandomValues(bytes);
|
|
24
|
-
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
|
25
|
-
return Array.from(bytes, (b) => alphabet[b & 63]).join('');
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
default:
|
|
29
|
-
throw new Error(`Unknown generator '${ref}' — register it with registerGenerator('${ref}', fn)`);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Fill what the entity says the system writes at creation.
|
|
34
|
-
*
|
|
35
|
-
* A value the caller supplied is never touched, including `null` — presence is the
|
|
36
|
-
* test, not truthiness, so `archivedAt: null` stays null rather than being re-filled.
|
|
37
|
-
*
|
|
38
|
-
* `'now'` produces a `Date`, the value the field declares. The storage converts it if
|
|
39
|
-
* its driver needs something else (`schema-sql/src/values.ts` does exactly that) —
|
|
40
|
-
* which is the same direction every other value travels.
|
|
41
|
-
*/
|
|
42
|
-
export function applyCreate(fields, input) {
|
|
43
|
-
const out = { ...input };
|
|
44
|
-
const instant = Date.now();
|
|
45
|
-
for (const [name, field] of Object.entries(fields)) {
|
|
46
|
-
if (name in out)
|
|
47
|
-
continue;
|
|
48
|
-
const create = field.lifecycle?.create;
|
|
49
|
-
if (create === 'now') {
|
|
50
|
-
// One instant, one Date PER FIELD. `created()` and `updated()` on the same entity
|
|
51
|
-
// would otherwise hold the same object, so mutating `updatedAt` would move an
|
|
52
|
-
// immutable `createdAt` with it — invisible where a storage serializes on write
|
|
53
|
-
// (SQL), lasting where it does not (an in-memory store keeps the row as handed).
|
|
54
|
-
out[name] = new Date(instant);
|
|
55
|
-
}
|
|
56
|
-
else if (typeof create === 'object' && create !== null) {
|
|
57
|
-
if ('value' in create)
|
|
58
|
-
out[name] = freshValue(create.value);
|
|
59
|
-
else if ('generate' in create)
|
|
60
|
-
out[name] = generatorFor(String(create.generate))();
|
|
61
|
-
}
|
|
62
|
-
// `'optional'` and an absent rule both mean: the system writes nothing here.
|
|
63
|
-
}
|
|
64
|
-
return out;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* A declared default is written into every row, so handing out the declaration itself
|
|
68
|
-
* would alias every row to it — mutate one, mutate the field and all its siblings.
|
|
69
|
-
*
|
|
70
|
-
* Every default the vocabulary can express is a primitive (`text`, `number`, `bool`,
|
|
71
|
-
* `oneOf`; `list` and `json` take none), so this only pays for itself under the escape
|
|
72
|
-
* hatch — `new Field({ shape, lifecycle: { create: { value: {…} } } })`. Cheap insurance
|
|
73
|
-
* against the one failure mode nobody would ever debug from the symptom.
|
|
74
|
-
*/
|
|
75
|
-
function freshValue(value) {
|
|
76
|
-
if (value === null || typeof value !== 'object')
|
|
77
|
-
return value;
|
|
78
|
-
return structuredClone(value);
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Fill what the entity says the system writes at every update — `updated()`, and
|
|
82
|
-
* nothing else. A supplied value wins, same rule as create.
|
|
83
|
-
*/
|
|
84
|
-
export function applyUpdate(fields, patch) {
|
|
85
|
-
const out = { ...patch };
|
|
86
|
-
const instant = Date.now();
|
|
87
|
-
for (const [name, field] of Object.entries(fields)) {
|
|
88
|
-
if (field.lifecycle?.update === 'now' && !(name in out))
|
|
89
|
-
out[name] = new Date(instant);
|
|
90
|
-
}
|
|
91
|
-
return out;
|
|
92
|
-
}
|
|
93
|
-
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/projections/lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Field, type Fields } from '../field/index.js';
|
|
2
|
-
import { type SchemaConstructor, type SchemaView, type Row } from '../schema/index.js';
|
|
3
|
-
import { type SchemaBundle, type SchemaDescriptor } from './card.js';
|
|
4
|
-
/**
|
|
5
|
-
* The field map a stated row shape implies. A card describes rows as they are READ, so
|
|
6
|
-
* `required` answers what a creation payload must carry — a question a synced consumer
|
|
7
|
-
* never asks, since it calls the host rather than constructing.
|
|
8
|
-
*/
|
|
9
|
-
type FieldsOf<T> = {
|
|
10
|
-
[K in keyof T]-?: Field<T[K]>;
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Read a lone card back into a working schema — THE single reconstructor. The result
|
|
14
|
-
* carries its `~standard` (live validation) rebuilt locally: the descriptor crosses
|
|
15
|
-
* the wire as data, the behaviour is reconstituted here. Relations stay name stand-ins
|
|
16
|
-
* (no set to resolve against — use {@link reconstructSet} for live targets).
|
|
17
|
-
*
|
|
18
|
-
* `T` states the row, which is what makes a rebuilt schema a CLASS and not a type beside a
|
|
19
|
-
* value: `class Post extends reconstruct<{…}>(card) {}`, one declaration carrying both.
|
|
20
|
-
* Without it the instance type is an index signature, so `post.titel` compiled.
|
|
21
|
-
*/
|
|
22
|
-
export declare function reconstruct<T = Row<Fields>>(descriptor: SchemaDescriptor): SchemaConstructor<FieldsOf<T>>;
|
|
23
|
-
/**
|
|
24
|
-
* Read a whole bundle back into live schemas, keyed by name — THE set reconstructor.
|
|
25
|
-
* Every entity is rebuilt against a shared `$defs` resolver, so a relation's `to()`
|
|
26
|
-
* hands back the real reconstructed target (feeds adapters), not a name stand-in.
|
|
27
|
-
* Targets absent from the set (external/cross-frond `$ref`) keep the stand-in.
|
|
28
|
-
*/
|
|
29
|
-
export declare function reconstructSet(bundle: SchemaBundle): Record<string, SchemaView>;
|
|
30
|
-
export {};
|
|
31
|
-
//# sourceMappingURL=reconstruct.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reconstruct.d.ts","sourceRoot":"","sources":["../../src/projections/reconstruct.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EAEL,KAAK,MAAM,EAGZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAU,KAAK,iBAAiB,EAAE,KAAK,UAAU,EAAE,KAAK,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,WAAW,CAAC;AAyHnB;;;;GAIG;AACH,KAAK,QAAQ,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAErD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,EACzC,UAAU,EAAE,gBAAgB,GAC3B,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAEhC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAa/E"}
|