@fougere/schema 0.5.0-alpha.0 → 0.6.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/{EntityAdapters.d.ts → entity/EntityAdapters.d.ts} +1 -1
- package/dist/entity/EntityAdapters.d.ts.map +1 -0
- package/dist/{EntityAdapters.js → entity/EntityAdapters.js} +1 -1
- package/dist/entity/EntityAdapters.js.map +1 -0
- package/dist/{EntityDeclarations.d.ts → entity/EntityDeclarations.d.ts} +2 -7
- package/dist/entity/EntityDeclarations.d.ts.map +1 -0
- package/dist/entity/EntityDeclarations.js.map +1 -0
- package/dist/entity.d.ts +2 -2
- package/dist/entity.d.ts.map +1 -1
- package/dist/index.d.ts +27 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -21
- package/dist/index.js.map +1 -1
- package/dist/judge/FieldJudge.d.ts +2 -2
- package/dist/judge/FieldJudge.d.ts.map +1 -1
- package/dist/judge/FieldJudge.js +8 -8
- package/dist/judge/FieldJudge.js.map +1 -1
- package/dist/judge/RowJudge.d.ts +1 -1
- package/dist/judge/RowJudge.d.ts.map +1 -1
- package/dist/judge/RowJudge.js +3 -3
- package/dist/judge/RowJudge.js.map +1 -1
- package/dist/judge/ValueJudge.d.ts +1 -1
- package/dist/judge/ValueJudge.d.ts.map +1 -1
- package/dist/judge/ValueJudge.js +5 -3
- package/dist/judge/ValueJudge.js.map +1 -1
- package/dist/projection/Cases.d.ts.map +1 -0
- package/dist/{judge → projection}/Cases.js +46 -13
- package/dist/projection/Cases.js.map +1 -0
- package/dist/projection/SchemaOrCard.d.ts +2 -2
- package/dist/projection/SchemaOrCard.d.ts.map +1 -1
- package/dist/projection/SchemaOrCard.js +1 -1
- package/dist/projection/SchemaOrCard.js.map +1 -1
- package/dist/projection/Visibility.d.ts +1 -1
- package/dist/projection/Visibility.d.ts.map +1 -1
- package/dist/projection/Visibility.js +3 -3
- package/dist/projection/Visibility.js.map +1 -1
- package/dist/{card → projection/card}/Bundle.d.ts +1 -1
- package/dist/projection/card/Bundle.d.ts.map +1 -0
- package/dist/{card → projection/card}/Bundle.js +1 -1
- package/dist/projection/card/Bundle.js.map +1 -0
- package/dist/{card → projection/card}/Card.d.ts +4 -4
- package/dist/projection/card/Card.d.ts.map +1 -0
- package/dist/{card → projection/card}/Card.js +50 -16
- package/dist/projection/card/Card.js.map +1 -0
- package/dist/{card → projection/card}/Descriptor.d.ts +5 -5
- package/dist/projection/card/Descriptor.d.ts.map +1 -0
- package/dist/projection/card/Descriptor.js.map +1 -0
- package/dist/projection/card/EntityTypeSource.d.ts.map +1 -0
- package/dist/{card → projection/card}/EntityTypeSource.js +1 -1
- package/dist/projection/card/EntityTypeSource.js.map +1 -0
- package/dist/projection/card/FacadeTypeSource.d.ts.map +1 -0
- package/dist/projection/card/FacadeTypeSource.js.map +1 -0
- package/dist/{card → projection/card}/admission.d.ts +2 -1
- package/dist/projection/card/admission.d.ts.map +1 -0
- package/dist/{card → projection/card}/admission.js +1 -0
- package/dist/projection/card/admission.js.map +1 -0
- package/dist/{card → projection/card}/diff.d.ts +3 -3
- package/dist/projection/card/diff.d.ts.map +1 -0
- package/dist/{card → projection/card}/diff.js.map +1 -1
- package/dist/schema/Schema.d.ts +6 -6
- package/dist/schema/Schema.d.ts.map +1 -1
- package/dist/schema/Schema.js +53 -27
- package/dist/schema/Schema.js.map +1 -1
- package/dist/schema/SchemaDefinition.d.ts +3 -3
- package/dist/schema/SchemaDefinition.d.ts.map +1 -1
- package/dist/schema/SchemaDefinition.js +2 -2
- package/dist/schema/SchemaDefinition.js.map +1 -1
- package/dist/schema/SchemaDerivation.d.ts +1 -1
- package/dist/schema/SchemaDerivation.d.ts.map +1 -1
- package/dist/schema/SchemaDerivation.js +7 -2
- package/dist/schema/SchemaDerivation.js.map +1 -1
- package/dist/schema/SchemaView.d.ts +3 -3
- package/dist/schema/SchemaView.d.ts.map +1 -1
- package/dist/{axis → schema/axis}/Axis.d.ts +1 -1
- package/dist/schema/axis/Axis.d.ts.map +1 -0
- package/dist/schema/axis/Axis.js.map +1 -0
- package/dist/schema/axis/Meta.d.ts.map +1 -0
- package/dist/{axis → schema/axis}/Meta.js.map +1 -1
- package/dist/schema/axis/boundary/Boundaries.d.ts.map +1 -0
- package/dist/schema/axis/boundary/Boundaries.js.map +1 -0
- package/dist/schema/axis/boundary/Boundary.d.ts.map +1 -0
- package/dist/{axis → schema/axis}/boundary/Boundary.js +10 -3
- package/dist/schema/axis/boundary/Boundary.js.map +1 -0
- package/dist/schema/axis/boundary/BoundaryAxis.d.ts.map +1 -0
- package/dist/{axis → schema/axis}/boundary/BoundaryAxis.js +2 -2
- package/dist/schema/axis/boundary/BoundaryAxis.js.map +1 -0
- package/dist/schema/axis/lifecycle/Clock.d.ts.map +1 -0
- package/dist/schema/axis/lifecycle/Clock.js.map +1 -0
- package/dist/schema/axis/lifecycle/Generators.d.ts.map +1 -0
- package/dist/schema/axis/lifecycle/Generators.js.map +1 -0
- package/dist/schema/axis/lifecycle/Lifecycle.d.ts.map +1 -0
- package/dist/schema/axis/lifecycle/Lifecycle.js.map +1 -0
- package/dist/schema/axis/lifecycle/LifecycleAxis.d.ts.map +1 -0
- package/dist/{axis → schema/axis}/lifecycle/LifecycleAxis.js +2 -2
- package/dist/schema/axis/lifecycle/LifecycleAxis.js.map +1 -0
- package/dist/schema/axis/lifecycle/apply.d.ts.map +1 -0
- package/dist/schema/axis/lifecycle/apply.js.map +1 -0
- package/dist/schema/axis/role/Relation.d.ts.map +1 -0
- package/dist/schema/axis/role/Relation.js.map +1 -0
- package/dist/{axis → schema/axis}/role/Role.d.ts +1 -1
- package/dist/schema/axis/role/Role.d.ts.map +1 -0
- package/dist/{axis → schema/axis}/role/Role.js +2 -2
- package/dist/schema/axis/role/Role.js.map +1 -0
- package/dist/{axis → schema/axis}/role/RoleAxis.d.ts +1 -1
- package/dist/schema/axis/role/RoleAxis.d.ts.map +1 -0
- package/dist/{axis → schema/axis}/role/RoleAxis.js +4 -5
- package/dist/schema/axis/role/RoleAxis.js.map +1 -0
- package/dist/schema/axis/shape/Formats.d.ts.map +1 -0
- package/dist/schema/axis/shape/Formats.js.map +1 -0
- package/dist/schema/axis/shape/Shape.d.ts.map +1 -0
- package/dist/schema/axis/shape/Shape.js.map +1 -0
- package/dist/{fields → schema/fields}/Field.d.ts +7 -7
- package/dist/schema/fields/Field.d.ts.map +1 -0
- package/dist/{fields → schema/fields}/Field.js +8 -8
- package/dist/schema/fields/Field.js.map +1 -0
- package/dist/{fields → schema/fields}/FieldSet.d.ts +2 -2
- package/dist/schema/fields/FieldSet.d.ts.map +1 -0
- package/dist/{fields → schema/fields}/FieldSet.js +3 -3
- package/dist/schema/fields/FieldSet.js.map +1 -0
- package/dist/{constraint → schema/fields/constraint}/FieldGroup.d.ts +1 -1
- package/dist/schema/fields/constraint/FieldGroup.d.ts.map +1 -0
- package/dist/{constraint → schema/fields/constraint}/FieldGroup.js +3 -3
- package/dist/schema/fields/constraint/FieldGroup.js.map +1 -0
- package/dist/schema/fields/constraint/Unique.d.ts.map +1 -0
- package/dist/schema/fields/constraint/Unique.js.map +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1 -0
- package/dist/utils.js.map +1 -1
- 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 -1
- package/dist/vocabulary/created.d.ts.map +1 -1
- package/dist/vocabulary/created.js +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 -1
- package/dist/vocabulary/email.d.ts.map +1 -1
- package/dist/vocabulary/immutable.d.ts +1 -1
- package/dist/vocabulary/immutable.d.ts.map +1 -1
- package/dist/vocabulary/immutable.js.map +1 -1
- package/dist/vocabulary/indexed.d.ts +1 -1
- package/dist/vocabulary/indexed.d.ts.map +1 -1
- package/dist/vocabulary/indexed.js +3 -1
- package/dist/vocabulary/indexed.js.map +1 -1
- package/dist/vocabulary/json.d.ts +1 -1
- package/dist/vocabulary/json.d.ts.map +1 -1
- package/dist/vocabulary/json.js +1 -1
- package/dist/vocabulary/json.js.map +1 -1
- package/dist/vocabulary/list.d.ts +1 -1
- package/dist/vocabulary/list.d.ts.map +1 -1
- package/dist/vocabulary/list.js +1 -1
- package/dist/vocabulary/list.js.map +1 -1
- package/dist/vocabulary/many.d.ts +2 -2
- package/dist/vocabulary/many.d.ts.map +1 -1
- package/dist/vocabulary/many.js +2 -2
- package/dist/vocabulary/many.js.map +1 -1
- package/dist/vocabulary/nullable.d.ts +1 -1
- package/dist/vocabulary/nullable.d.ts.map +1 -1
- package/dist/vocabulary/nullable.js +1 -1
- 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 +6 -2
- package/dist/vocabulary/number.js.map +1 -1
- package/dist/vocabulary/oneOf.d.ts +1 -1
- 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 +1 -1
- package/dist/vocabulary/optional.d.ts.map +1 -1
- package/dist/vocabulary/optional.js +4 -2
- package/dist/vocabulary/optional.js.map +1 -1
- package/dist/vocabulary/primary.d.ts +2 -2
- package/dist/vocabulary/primary.d.ts.map +1 -1
- package/dist/vocabulary/primary.js +6 -6
- package/dist/vocabulary/primary.js.map +1 -1
- package/dist/vocabulary/readOnly.d.ts +1 -1
- package/dist/vocabulary/readOnly.d.ts.map +1 -1
- package/dist/vocabulary/readOnly.js +1 -1
- package/dist/vocabulary/readOnly.js.map +1 -1
- package/dist/vocabulary/ref.d.ts +2 -2
- package/dist/vocabulary/ref.d.ts.map +1 -1
- package/dist/vocabulary/ref.js +2 -2
- 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 +8 -2
- package/dist/vocabulary/text.js.map +1 -1
- package/dist/vocabulary/unique.d.ts +1 -1
- package/dist/vocabulary/unique.d.ts.map +1 -1
- package/dist/vocabulary/unique.js +3 -3
- package/dist/vocabulary/unique.js.map +1 -1
- package/dist/vocabulary/updated.d.ts +1 -1
- package/dist/vocabulary/updated.d.ts.map +1 -1
- package/dist/vocabulary/url.d.ts +1 -1
- package/dist/vocabulary/url.d.ts.map +1 -1
- package/dist/vocabulary/vocabulary.d.ts +1 -1
- package/dist/vocabulary/vocabulary.d.ts.map +1 -1
- package/dist/vocabulary/vocabulary.js +1 -1
- package/dist/vocabulary/vocabulary.js.map +1 -1
- package/dist/vocabulary/writeOnly.d.ts +1 -1
- package/dist/vocabulary/writeOnly.d.ts.map +1 -1
- package/dist/vocabulary/writeOnly.js +1 -1
- package/dist/vocabulary/writeOnly.js.map +1 -1
- package/package.json +1 -1
- package/src/{EntityAdapters.ts → entity/EntityAdapters.ts} +2 -2
- package/src/entity/EntityDeclarations.ts +16 -0
- package/src/entity.ts +2 -2
- package/src/index.ts +65 -28
- package/src/judge/FieldJudge.ts +10 -10
- package/src/judge/RowJudge.ts +4 -4
- package/src/judge/ValueJudge.ts +8 -4
- package/src/{judge → projection}/Cases.ts +56 -20
- package/src/projection/SchemaOrCard.ts +3 -3
- package/src/projection/Visibility.ts +8 -5
- package/src/{card → projection/card}/Bundle.ts +4 -4
- package/src/{card → projection/card}/Card.ts +87 -28
- package/src/{card → projection/card}/Descriptor.ts +5 -5
- package/src/{card → projection/card}/EntityTypeSource.ts +1 -1
- package/src/{card → projection/card}/admission.ts +6 -1
- package/src/{card → projection/card}/diff.ts +3 -3
- package/src/schema/Schema.ts +95 -41
- package/src/schema/SchemaDefinition.ts +41 -11
- package/src/schema/SchemaDerivation.ts +12 -4
- package/src/schema/SchemaView.ts +3 -3
- package/src/{axis → schema/axis}/Axis.ts +1 -1
- package/src/{axis → schema/axis}/boundary/Boundary.ts +16 -5
- package/src/{axis → schema/axis}/boundary/BoundaryAxis.ts +2 -2
- package/src/{axis → schema/axis}/lifecycle/LifecycleAxis.ts +3 -3
- package/src/{axis → schema/axis}/lifecycle/apply.ts +2 -1
- package/src/{axis → schema/axis}/role/Role.ts +2 -2
- package/src/{axis → schema/axis}/role/RoleAxis.ts +6 -7
- package/src/{fields → schema/fields}/Field.ts +14 -15
- package/src/{fields → schema/fields}/FieldSet.ts +8 -7
- package/src/{constraint → schema/fields/constraint}/FieldGroup.ts +7 -14
- package/src/utils.ts +3 -0
- package/src/vocabulary/bool.ts +3 -2
- package/src/vocabulary/created.ts +2 -2
- package/src/vocabulary/date.ts +1 -1
- package/src/vocabulary/email.ts +1 -1
- package/src/vocabulary/immutable.ts +7 -4
- package/src/vocabulary/indexed.ts +4 -2
- package/src/vocabulary/json.ts +4 -2
- package/src/vocabulary/list.ts +5 -2
- package/src/vocabulary/many.ts +5 -3
- package/src/vocabulary/nullable.ts +8 -5
- package/src/vocabulary/number.ts +8 -3
- package/src/vocabulary/oneOf.ts +6 -3
- package/src/vocabulary/optional.ts +11 -6
- package/src/vocabulary/primary.ts +6 -6
- package/src/vocabulary/readOnly.ts +8 -5
- package/src/vocabulary/ref.ts +6 -3
- package/src/vocabulary/text.ts +11 -4
- package/src/vocabulary/unique.ts +6 -9
- package/src/vocabulary/updated.ts +1 -1
- package/src/vocabulary/url.ts +1 -1
- package/src/vocabulary/vocabulary.ts +2 -3
- package/src/vocabulary/writeOnly.ts +8 -5
- package/dist/EntityAdapters.d.ts.map +0 -1
- package/dist/EntityAdapters.js.map +0 -1
- package/dist/EntityDeclarations.d.ts.map +0 -1
- package/dist/EntityDeclarations.js.map +0 -1
- package/dist/axis/Axis.d.ts.map +0 -1
- package/dist/axis/Axis.js.map +0 -1
- package/dist/axis/Meta.d.ts.map +0 -1
- package/dist/axis/boundary/Boundaries.d.ts.map +0 -1
- package/dist/axis/boundary/Boundaries.js.map +0 -1
- package/dist/axis/boundary/Boundary.d.ts.map +0 -1
- package/dist/axis/boundary/Boundary.js.map +0 -1
- package/dist/axis/boundary/BoundaryAxis.d.ts.map +0 -1
- package/dist/axis/boundary/BoundaryAxis.js.map +0 -1
- package/dist/axis/lifecycle/Clock.d.ts.map +0 -1
- package/dist/axis/lifecycle/Clock.js.map +0 -1
- package/dist/axis/lifecycle/Generators.d.ts.map +0 -1
- package/dist/axis/lifecycle/Generators.js.map +0 -1
- package/dist/axis/lifecycle/Lifecycle.d.ts.map +0 -1
- package/dist/axis/lifecycle/Lifecycle.js.map +0 -1
- package/dist/axis/lifecycle/LifecycleAxis.d.ts.map +0 -1
- package/dist/axis/lifecycle/LifecycleAxis.js.map +0 -1
- package/dist/axis/lifecycle/apply.d.ts.map +0 -1
- package/dist/axis/lifecycle/apply.js.map +0 -1
- package/dist/axis/role/Relation.d.ts.map +0 -1
- package/dist/axis/role/Relation.js.map +0 -1
- package/dist/axis/role/Role.d.ts.map +0 -1
- package/dist/axis/role/Role.js.map +0 -1
- package/dist/axis/role/RoleAxis.d.ts.map +0 -1
- package/dist/axis/role/RoleAxis.js.map +0 -1
- package/dist/axis/shape/Formats.d.ts.map +0 -1
- package/dist/axis/shape/Formats.js.map +0 -1
- package/dist/axis/shape/Shape.d.ts.map +0 -1
- package/dist/axis/shape/Shape.js.map +0 -1
- package/dist/card/Bundle.d.ts.map +0 -1
- package/dist/card/Bundle.js.map +0 -1
- package/dist/card/Card.d.ts.map +0 -1
- package/dist/card/Card.js.map +0 -1
- package/dist/card/Descriptor.d.ts.map +0 -1
- package/dist/card/Descriptor.js.map +0 -1
- package/dist/card/EntityTypeSource.d.ts.map +0 -1
- package/dist/card/EntityTypeSource.js.map +0 -1
- package/dist/card/FacadeTypeSource.d.ts.map +0 -1
- package/dist/card/FacadeTypeSource.js.map +0 -1
- package/dist/card/admission.d.ts.map +0 -1
- package/dist/card/admission.js.map +0 -1
- package/dist/card/diff.d.ts.map +0 -1
- package/dist/constraint/FieldGroup.d.ts.map +0 -1
- package/dist/constraint/FieldGroup.js.map +0 -1
- package/dist/constraint/Unique.d.ts.map +0 -1
- package/dist/constraint/Unique.js.map +0 -1
- package/dist/fields/Field.d.ts.map +0 -1
- package/dist/fields/Field.js.map +0 -1
- package/dist/fields/FieldSet.d.ts.map +0 -1
- package/dist/fields/FieldSet.js.map +0 -1
- package/dist/judge/Cases.d.ts.map +0 -1
- package/dist/judge/Cases.js.map +0 -1
- package/dist/judge/ValueForm.d.ts +0 -3
- package/dist/judge/ValueForm.d.ts.map +0 -1
- package/dist/judge/ValueForm.js +0 -3
- package/dist/judge/ValueForm.js.map +0 -1
- package/src/EntityDeclarations.ts +0 -19
- package/src/judge/ValueForm.ts +0 -7
- /package/dist/{EntityDeclarations.js → entity/EntityDeclarations.js} +0 -0
- /package/dist/{judge → projection}/Cases.d.ts +0 -0
- /package/dist/{card → projection/card}/Descriptor.js +0 -0
- /package/dist/{card → projection/card}/EntityTypeSource.d.ts +0 -0
- /package/dist/{card → projection/card}/FacadeTypeSource.d.ts +0 -0
- /package/dist/{card → projection/card}/FacadeTypeSource.js +0 -0
- /package/dist/{card → projection/card}/diff.js +0 -0
- /package/dist/{axis → schema/axis}/Axis.js +0 -0
- /package/dist/{axis → schema/axis}/Meta.d.ts +0 -0
- /package/dist/{axis → schema/axis}/Meta.js +0 -0
- /package/dist/{axis → schema/axis}/boundary/Boundaries.d.ts +0 -0
- /package/dist/{axis → schema/axis}/boundary/Boundaries.js +0 -0
- /package/dist/{axis → schema/axis}/boundary/Boundary.d.ts +0 -0
- /package/dist/{axis → schema/axis}/boundary/BoundaryAxis.d.ts +0 -0
- /package/dist/{axis → schema/axis}/lifecycle/Clock.d.ts +0 -0
- /package/dist/{axis → schema/axis}/lifecycle/Clock.js +0 -0
- /package/dist/{axis → schema/axis}/lifecycle/Generators.d.ts +0 -0
- /package/dist/{axis → schema/axis}/lifecycle/Generators.js +0 -0
- /package/dist/{axis → schema/axis}/lifecycle/Lifecycle.d.ts +0 -0
- /package/dist/{axis → schema/axis}/lifecycle/Lifecycle.js +0 -0
- /package/dist/{axis → schema/axis}/lifecycle/LifecycleAxis.d.ts +0 -0
- /package/dist/{axis → schema/axis}/lifecycle/apply.d.ts +0 -0
- /package/dist/{axis → schema/axis}/lifecycle/apply.js +0 -0
- /package/dist/{axis → schema/axis}/role/Relation.d.ts +0 -0
- /package/dist/{axis → schema/axis}/role/Relation.js +0 -0
- /package/dist/{axis → schema/axis}/shape/Formats.d.ts +0 -0
- /package/dist/{axis → schema/axis}/shape/Formats.js +0 -0
- /package/dist/{axis → schema/axis}/shape/Shape.d.ts +0 -0
- /package/dist/{axis → schema/axis}/shape/Shape.js +0 -0
- /package/dist/{constraint → schema/fields/constraint}/Unique.d.ts +0 -0
- /package/dist/{constraint → schema/fields/constraint}/Unique.js +0 -0
- /package/src/{card → projection/card}/FacadeTypeSource.ts +0 -0
- /package/src/{axis → schema/axis}/Meta.ts +0 -0
- /package/src/{axis → schema/axis}/boundary/Boundaries.ts +0 -0
- /package/src/{axis → schema/axis}/lifecycle/Clock.ts +0 -0
- /package/src/{axis → schema/axis}/lifecycle/Generators.ts +0 -0
- /package/src/{axis → schema/axis}/lifecycle/Lifecycle.ts +0 -0
- /package/src/{axis → schema/axis}/role/Relation.ts +0 -0
- /package/src/{axis → schema/axis}/shape/Formats.ts +0 -0
- /package/src/{axis → schema/axis}/shape/Shape.ts +0 -0
- /package/src/{constraint → schema/fields/constraint}/Unique.ts +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { BoundaryRef } from '
|
|
2
|
-
import type { LifecycleRules } from '
|
|
1
|
+
import type { BoundaryRef } from '../../schema/axis/boundary/Boundary.js';
|
|
2
|
+
import type { LifecycleRules } from '../../schema/axis/lifecycle/Lifecycle.js';
|
|
3
3
|
import type { FieldDescriptor, RoleDescriptor } from './Descriptor.js';
|
|
4
4
|
|
|
5
5
|
/** One named difference, at one place. Each kind exists because a reader asks for it. */
|
|
@@ -8,7 +8,7 @@ export type Change =
|
|
|
8
8
|
| { kind: 'added'; field: string; to: FieldDescriptor; required: boolean }
|
|
9
9
|
/** DDL: drop the column. Codec: the old caller still sends it, and it goes nowhere. */
|
|
10
10
|
| { kind: 'removed'; field: string; from: FieldDescriptor; required: boolean }
|
|
11
|
-
/** DDL: rename the column. Codec and
|
|
11
|
+
/** DDL: rename the column. Codec and storage: one more entry in the field-to-column map. */
|
|
12
12
|
| { kind: 'renamed'; from: string; to: string; field: FieldDescriptor }
|
|
13
13
|
/** DDL: alter the type. Codec: convert the value, when it can. */
|
|
14
14
|
| { kind: 'retyped'; field: string; from: TypeSet; to: TypeSet }
|
package/src/schema/Schema.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Boundary } from '
|
|
2
|
-
import { type Fields } from '
|
|
1
|
+
import { Boundary } from './axis/boundary/Boundary.js';
|
|
2
|
+
import { type Fields } from './fields/Field.js';
|
|
3
3
|
import {
|
|
4
4
|
type CompositeUnique,
|
|
5
5
|
type EntityDeclarations,
|
|
6
6
|
type PreviousNames,
|
|
7
|
-
} from '../EntityDeclarations.js';
|
|
8
|
-
import { EntityAdapterSet, type EntityAdapters } from '../EntityAdapters.js';
|
|
9
|
-
import { FieldGroup } from '
|
|
10
|
-
import { Unique } from '
|
|
7
|
+
} from '../entity/EntityDeclarations.js';
|
|
8
|
+
import { EntityAdapterSet, type EntityAdapters } from '../entity/EntityAdapters.js';
|
|
9
|
+
import { FieldGroup } from './fields/constraint/FieldGroup.js';
|
|
10
|
+
import { Unique } from './fields/constraint/Unique.js';
|
|
11
11
|
import { RowJudge } from '../judge/RowJudge.js';
|
|
12
12
|
import { SchemaDerivation } from './SchemaDerivation.js';
|
|
13
13
|
import { SchemaDefinition } from './SchemaDefinition.js';
|
|
@@ -15,50 +15,79 @@ import { type ValidateOptions } from '../judge/options.js';
|
|
|
15
15
|
import type { StandardSchemaV1 } from '../projection/standard.js';
|
|
16
16
|
import type { PartialRow, Row, SchemaView } from './SchemaView.js';
|
|
17
17
|
|
|
18
|
-
export const ANONYMOUS_SCHEMA_NAME =
|
|
18
|
+
export const ANONYMOUS_SCHEMA_NAME = 'Schema';
|
|
19
19
|
|
|
20
20
|
export interface SchemaConstructor<TFields extends Fields> extends SchemaView<TFields> {
|
|
21
21
|
new (data: PartialRow<TFields>): Row<TFields>;
|
|
22
|
-
readonly
|
|
22
|
+
readonly '~standard': StandardSchemaV1.Props<Record<string, unknown>, Row<TFields>>;
|
|
23
23
|
readonly derivation?: SchemaDerivation;
|
|
24
24
|
readonly previous?: PreviousNames<TFields>;
|
|
25
25
|
readonly anchored?: boolean;
|
|
26
26
|
from(data: Record<string, unknown>): Row<TFields>;
|
|
27
|
-
pick<K extends string & keyof TFields>(
|
|
28
|
-
|
|
27
|
+
pick<K extends string & keyof TFields>(
|
|
28
|
+
...keys: K[]
|
|
29
|
+
): SchemaConstructor<Pick<TFields, K>>;
|
|
30
|
+
omit<K extends string & keyof TFields>(
|
|
31
|
+
...keys: K[]
|
|
32
|
+
): SchemaConstructor<Omit<TFields, K>>;
|
|
29
33
|
partial(): SchemaConstructor<TFields>;
|
|
30
34
|
extend<E extends Fields>(extra: E): SchemaConstructor<TFields & E>;
|
|
31
35
|
declares(declarations: EntityDeclarations<TFields>): SchemaConstructor<TFields>;
|
|
32
36
|
anchor(): SchemaConstructor<TFields>;
|
|
33
37
|
named(name: string): SchemaConstructor<TFields>;
|
|
34
|
-
rename(
|
|
38
|
+
rename(
|
|
39
|
+
mapping: Partial<Record<string & keyof TFields, string>>,
|
|
40
|
+
): SchemaConstructor<Fields>;
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
export class Schema {
|
|
38
44
|
/** The one place a schema holds what it is. The readings below are its projections. */
|
|
39
45
|
static definition: SchemaDefinition = SchemaDefinition.stated({ fields: {} });
|
|
40
46
|
|
|
41
|
-
static get fields(): Fields {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
static get
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
static get fields(): Fields {
|
|
48
|
+
return this.definition.fields;
|
|
49
|
+
}
|
|
50
|
+
static get adapters(): EntityAdapters<Fields> | undefined {
|
|
51
|
+
return this.definition.adapters;
|
|
52
|
+
}
|
|
53
|
+
static get opts(): ValidateOptions {
|
|
54
|
+
return this.definition.opts;
|
|
55
|
+
}
|
|
56
|
+
static get derivation(): SchemaDerivation | undefined {
|
|
57
|
+
return this.definition.derivation;
|
|
58
|
+
}
|
|
59
|
+
static get previous(): PreviousNames<Fields> | undefined {
|
|
60
|
+
return this.definition.previous;
|
|
61
|
+
}
|
|
62
|
+
static get anchored(): boolean {
|
|
63
|
+
return this.definition.anchored;
|
|
64
|
+
}
|
|
47
65
|
|
|
48
66
|
constructor(data?: Record<string, unknown>) {
|
|
49
67
|
if (!data) return;
|
|
50
68
|
for (const [key, value] of Object.entries(data)) {
|
|
51
|
-
Object.defineProperty(this, key, {
|
|
69
|
+
Object.defineProperty(this, key, {
|
|
70
|
+
value,
|
|
71
|
+
writable: true,
|
|
72
|
+
enumerable: true,
|
|
73
|
+
configurable: true,
|
|
74
|
+
});
|
|
52
75
|
}
|
|
53
76
|
}
|
|
54
77
|
|
|
55
|
-
static getFields() {
|
|
56
|
-
|
|
78
|
+
static getFields() {
|
|
79
|
+
return this.fields;
|
|
80
|
+
}
|
|
81
|
+
static getAdapters() {
|
|
82
|
+
return this.adapters;
|
|
83
|
+
}
|
|
57
84
|
static getUnique(): CompositeUnique<Fields> | undefined {
|
|
58
85
|
const groups = FieldGroup.groupsOf(this.fields, Unique);
|
|
59
86
|
return groups.length ? groups.map((group) => [...group.members]) : undefined;
|
|
60
87
|
}
|
|
61
|
-
static getOpts() {
|
|
88
|
+
static getOpts() {
|
|
89
|
+
return this.opts;
|
|
90
|
+
}
|
|
62
91
|
|
|
63
92
|
static validate(input: unknown) {
|
|
64
93
|
return RowJudge.of(this.fields, this.opts).check(input);
|
|
@@ -69,25 +98,28 @@ export class Schema {
|
|
|
69
98
|
for (const [key, field] of Object.entries(this.fields)) {
|
|
70
99
|
if (!(key in data)) continue;
|
|
71
100
|
const value = data[key];
|
|
72
|
-
if (value === null || value === undefined) {
|
|
101
|
+
if (value === null || value === undefined) {
|
|
102
|
+
out[key] = value;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
73
105
|
const decoded = Boundary.of(field).decode(value);
|
|
74
|
-
out[key] =
|
|
106
|
+
out[key] = 'error' in decoded ? value : decoded.value;
|
|
75
107
|
}
|
|
76
108
|
return out;
|
|
77
109
|
}
|
|
78
110
|
|
|
79
|
-
static get [
|
|
111
|
+
static get ['~standard'](): StandardSchemaV1.Props<Record<string, unknown>> {
|
|
80
112
|
const { fields, opts } = this;
|
|
81
113
|
return {
|
|
82
114
|
version: 1,
|
|
83
|
-
vendor:
|
|
115
|
+
vendor: 'fougere',
|
|
84
116
|
validate(value: unknown) {
|
|
85
117
|
const result = RowJudge.of(fields, opts).check(value);
|
|
86
118
|
if (result.success) return { value: result.data };
|
|
87
119
|
return {
|
|
88
120
|
issues: result.errors.map((e) => ({
|
|
89
121
|
message: e.message,
|
|
90
|
-
path: e.path && e.path !==
|
|
122
|
+
path: e.path && e.path !== '.' ? [{ key: e.path }] : undefined,
|
|
91
123
|
})),
|
|
92
124
|
};
|
|
93
125
|
},
|
|
@@ -95,23 +127,25 @@ export class Schema {
|
|
|
95
127
|
}
|
|
96
128
|
|
|
97
129
|
static pick(...keys: string[]) {
|
|
98
|
-
assertKnownKeys(
|
|
130
|
+
assertKnownKeys('pick', keys, this.fields);
|
|
99
131
|
const picked: Fields = {};
|
|
100
132
|
for (const key of keys) if (this.fields[key]) picked[key] = this.fields[key];
|
|
101
133
|
return this.derive(picked, (k) => (keys.includes(k) ? k : undefined));
|
|
102
134
|
}
|
|
103
135
|
|
|
104
136
|
static omit(...keys: string[]) {
|
|
105
|
-
assertKnownKeys(
|
|
137
|
+
assertKnownKeys('omit', keys, this.fields);
|
|
106
138
|
const kept: Fields = {};
|
|
107
|
-
for (const [key, field] of Object.entries(this.fields))
|
|
139
|
+
for (const [key, field] of Object.entries(this.fields))
|
|
140
|
+
if (!keys.includes(key)) kept[key] = field;
|
|
108
141
|
return this.derive(kept, (k) => (keys.includes(k) ? undefined : k));
|
|
109
142
|
}
|
|
110
143
|
|
|
111
144
|
static rename(mapping: Record<string, string>) {
|
|
112
|
-
assertKnownKeys(
|
|
145
|
+
assertKnownKeys('rename', Object.keys(mapping), this.fields);
|
|
113
146
|
const renamed: Fields = {};
|
|
114
|
-
for (const [key, field] of Object.entries(this.fields))
|
|
147
|
+
for (const [key, field] of Object.entries(this.fields))
|
|
148
|
+
renamed[mapping[key] ?? key] = field;
|
|
115
149
|
return this.derive(renamed, (k) => mapping[k] ?? k);
|
|
116
150
|
}
|
|
117
151
|
|
|
@@ -121,7 +155,11 @@ export class Schema {
|
|
|
121
155
|
*/
|
|
122
156
|
static declares(declarations: EntityDeclarations<Fields>) {
|
|
123
157
|
const addressed = EntityAdapterSet.of(declarations.adapters)?.fieldNames ?? [];
|
|
124
|
-
assertKnownKeys(
|
|
158
|
+
assertKnownKeys(
|
|
159
|
+
'declares',
|
|
160
|
+
[...addressed, ...Object.keys(declarations.previous ?? {})],
|
|
161
|
+
this.fields,
|
|
162
|
+
);
|
|
125
163
|
|
|
126
164
|
return Schema.subclass(this.definition.declaring(declarations));
|
|
127
165
|
}
|
|
@@ -150,14 +188,18 @@ export class Schema {
|
|
|
150
188
|
throw new Error(`named(): \`${name}\` is not a valid class name.`);
|
|
151
189
|
}
|
|
152
190
|
if (this.name !== ANONYMOUS_SCHEMA_NAME) {
|
|
153
|
-
throw new Error(
|
|
191
|
+
throw new Error(
|
|
192
|
+
`named(): \`${this.name}\` is already named by its class declaration.`,
|
|
193
|
+
);
|
|
154
194
|
}
|
|
155
|
-
Object.defineProperty(this,
|
|
195
|
+
Object.defineProperty(this, 'name', { value: name, configurable: true });
|
|
156
196
|
return this;
|
|
157
197
|
}
|
|
158
198
|
|
|
159
199
|
static compose<T extends SchemaView[]>(...sources: T): SchemaConstructor<Merged<T>> {
|
|
160
|
-
return Schema.subclass(
|
|
200
|
+
return Schema.subclass(
|
|
201
|
+
SchemaDefinition.merged(sources),
|
|
202
|
+
) as unknown as SchemaConstructor<Merged<T>>;
|
|
161
203
|
}
|
|
162
204
|
|
|
163
205
|
static of<TFields extends Fields>(stated: {
|
|
@@ -168,14 +210,19 @@ export class Schema {
|
|
|
168
210
|
previous?: PreviousNames<TFields>;
|
|
169
211
|
anchored?: boolean;
|
|
170
212
|
}): SchemaConstructor<TFields> {
|
|
171
|
-
return Schema.subclass(
|
|
213
|
+
return Schema.subclass(
|
|
214
|
+
SchemaDefinition.stated(stated),
|
|
215
|
+
) as unknown as SchemaConstructor<TFields>;
|
|
172
216
|
}
|
|
173
217
|
|
|
174
218
|
/** The class a definition becomes. The one place a Schema subclass is born. */
|
|
175
219
|
private static subclass(definition: SchemaDefinition): SchemaConstructor<Fields> {
|
|
176
220
|
class Derived extends Schema {}
|
|
177
221
|
Derived.definition = definition;
|
|
178
|
-
Object.defineProperty(Derived,
|
|
222
|
+
Object.defineProperty(Derived, 'name', {
|
|
223
|
+
value: ANONYMOUS_SCHEMA_NAME,
|
|
224
|
+
configurable: true,
|
|
225
|
+
});
|
|
179
226
|
return Derived as unknown as SchemaConstructor<Fields>;
|
|
180
227
|
}
|
|
181
228
|
|
|
@@ -188,10 +235,17 @@ function assertKnownKeys(operation: string, keys: string[], fields: Fields): voi
|
|
|
188
235
|
const strangers = keys.filter((key) => !(key in fields));
|
|
189
236
|
if (strangers.length === 0) return;
|
|
190
237
|
throw new Error(
|
|
191
|
-
`${operation}(): unknown field ${strangers.map((s) => `\`${s}\``).join(
|
|
192
|
-
`This schema carries ${Object.keys(fields).join(
|
|
238
|
+
`${operation}(): unknown field ${strangers.map((s) => `\`${s}\``).join(', ')}. ` +
|
|
239
|
+
`This schema carries ${Object.keys(fields).join(', ')}.`,
|
|
193
240
|
);
|
|
194
241
|
}
|
|
195
242
|
|
|
196
|
-
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (
|
|
197
|
-
|
|
243
|
+
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (
|
|
244
|
+
k: infer I,
|
|
245
|
+
) => void
|
|
246
|
+
? I
|
|
247
|
+
: never;
|
|
248
|
+
type Merged<T extends SchemaView[]> = UnionToIntersection<
|
|
249
|
+
T[number] extends { getFields(): infer F } ? F : Fields
|
|
250
|
+
> &
|
|
251
|
+
Fields;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { type Fields } from '
|
|
2
|
-
import { FieldSet } from '
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { type Fields } from './fields/Field.js';
|
|
2
|
+
import { FieldSet } from './fields/FieldSet.js';
|
|
3
|
+
import {
|
|
4
|
+
type EntityDeclarations,
|
|
5
|
+
type PreviousNames,
|
|
6
|
+
} from '../entity/EntityDeclarations.js';
|
|
7
|
+
import { EntityAdapterSet, type EntityAdapters } from '../entity/EntityAdapters.js';
|
|
5
8
|
import { SchemaDerivation } from './SchemaDerivation.js';
|
|
6
9
|
import { type ValidateOptions } from '../judge/options.js';
|
|
7
10
|
import type { SchemaView } from './SchemaView.js';
|
|
@@ -36,7 +39,12 @@ export class SchemaDefinition {
|
|
|
36
39
|
anchored?: boolean;
|
|
37
40
|
}): SchemaDefinition {
|
|
38
41
|
return new SchemaDefinition(
|
|
39
|
-
said.fields,
|
|
42
|
+
said.fields,
|
|
43
|
+
EntityAdapterSet.of(said.adapters)?.stated,
|
|
44
|
+
said.opts ?? {},
|
|
45
|
+
said.previous,
|
|
46
|
+
said.derivation,
|
|
47
|
+
said.anchored ?? false,
|
|
40
48
|
);
|
|
41
49
|
}
|
|
42
50
|
|
|
@@ -60,7 +68,12 @@ export class SchemaDefinition {
|
|
|
60
68
|
*/
|
|
61
69
|
anchoring(): SchemaDefinition {
|
|
62
70
|
return new SchemaDefinition(
|
|
63
|
-
this.fields,
|
|
71
|
+
this.fields,
|
|
72
|
+
this.adapters,
|
|
73
|
+
this.opts,
|
|
74
|
+
this.previous,
|
|
75
|
+
this.derivation,
|
|
76
|
+
true,
|
|
64
77
|
);
|
|
65
78
|
}
|
|
66
79
|
|
|
@@ -68,9 +81,14 @@ export class SchemaDefinition {
|
|
|
68
81
|
* `pick`, `omit` and `rename` are one gesture: the fields that remain, and what became
|
|
69
82
|
* of each name. What each adapter was handed follows the same correspondence, and so does the origin.
|
|
70
83
|
*/
|
|
71
|
-
cut(
|
|
84
|
+
cut(
|
|
85
|
+
fields: Fields,
|
|
86
|
+
survives: (key: string) => string | undefined,
|
|
87
|
+
root: SchemaView,
|
|
88
|
+
): SchemaDefinition {
|
|
72
89
|
const renamed: Fields = {};
|
|
73
|
-
for (const [key, field] of Object.entries(fields))
|
|
90
|
+
for (const [key, field] of Object.entries(fields))
|
|
91
|
+
renamed[key] = field.rename(survives);
|
|
74
92
|
return new SchemaDefinition(
|
|
75
93
|
renamed,
|
|
76
94
|
EntityAdapterSet.of(this.adapters)?.cut(survives)?.stated,
|
|
@@ -84,14 +102,24 @@ export class SchemaDefinition {
|
|
|
84
102
|
/** The same fields, judged as an update. */
|
|
85
103
|
patched(root: SchemaView): SchemaDefinition {
|
|
86
104
|
return new SchemaDefinition(
|
|
87
|
-
{ ...this.fields },
|
|
105
|
+
{ ...this.fields },
|
|
106
|
+
this.adapters,
|
|
107
|
+
{ ...this.opts, patch: true },
|
|
108
|
+
undefined,
|
|
109
|
+
this.origin(root),
|
|
110
|
+
false,
|
|
88
111
|
);
|
|
89
112
|
}
|
|
90
113
|
|
|
91
114
|
/** The added fields have no origin, so the derivation is unchanged: it speaks of the root. */
|
|
92
115
|
extended(extra: Fields, root: SchemaView): SchemaDefinition {
|
|
93
116
|
return new SchemaDefinition(
|
|
94
|
-
{ ...this.fields, ...extra },
|
|
117
|
+
{ ...this.fields, ...extra },
|
|
118
|
+
this.adapters,
|
|
119
|
+
this.opts,
|
|
120
|
+
undefined,
|
|
121
|
+
this.origin(root),
|
|
122
|
+
false,
|
|
95
123
|
);
|
|
96
124
|
}
|
|
97
125
|
|
|
@@ -103,7 +131,9 @@ export class SchemaDefinition {
|
|
|
103
131
|
Object.assign(fields, view.getFields());
|
|
104
132
|
opts = { ...opts, ...view.getOpts() };
|
|
105
133
|
}
|
|
106
|
-
const adapters = EntityAdapterSet.merged(
|
|
134
|
+
const adapters = EntityAdapterSet.merged(
|
|
135
|
+
views.map((view) => view.getAdapters()),
|
|
136
|
+
)?.stated;
|
|
107
137
|
|
|
108
138
|
return new SchemaDefinition(fields, adapters, opts, undefined, undefined, false);
|
|
109
139
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Fields } from '
|
|
1
|
+
import { type Fields } from './fields/Field.js';
|
|
2
2
|
import type { SchemaView } from './SchemaView.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -18,7 +18,10 @@ export class SchemaDerivation {
|
|
|
18
18
|
|
|
19
19
|
/** The first cut: every field of the origin still answers to its own name. */
|
|
20
20
|
static first(source: SchemaView, fields: Fields): SchemaDerivation {
|
|
21
|
-
return new SchemaDerivation(
|
|
21
|
+
return new SchemaDerivation(
|
|
22
|
+
source,
|
|
23
|
+
Object.fromEntries(Object.keys(fields).map((key) => [key, key])),
|
|
24
|
+
);
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
/** The same origin, seen through one more cut. */
|
|
@@ -26,7 +29,10 @@ export class SchemaDerivation {
|
|
|
26
29
|
return new SchemaDerivation(
|
|
27
30
|
this.source,
|
|
28
31
|
Object.fromEntries(
|
|
29
|
-
Object.entries(this.survived).map(([origin, here]) => [
|
|
32
|
+
Object.entries(this.survived).map(([origin, here]) => [
|
|
33
|
+
origin,
|
|
34
|
+
here === undefined ? undefined : survives(here),
|
|
35
|
+
]),
|
|
30
36
|
),
|
|
31
37
|
);
|
|
32
38
|
}
|
|
@@ -43,7 +49,9 @@ export class SchemaDerivation {
|
|
|
43
49
|
get anchor(): SchemaView {
|
|
44
50
|
const source = this.source;
|
|
45
51
|
|
|
46
|
-
return source.anchored !== undefined || !source.derivation
|
|
52
|
+
return source.anchored !== undefined || !source.derivation
|
|
53
|
+
? source
|
|
54
|
+
: source.derivation.anchor;
|
|
47
55
|
}
|
|
48
56
|
|
|
49
57
|
/**
|
package/src/schema/SchemaView.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Field, Fields } from '
|
|
2
|
-
import type { CompositeUnique, PreviousNames } from '../EntityDeclarations.js';
|
|
3
|
-
import type { EntityAdapters } from '../EntityAdapters.js';
|
|
1
|
+
import type { Field, Fields } from './fields/Field.js';
|
|
2
|
+
import type { CompositeUnique, PreviousNames } from '../entity/EntityDeclarations.js';
|
|
3
|
+
import type { EntityAdapters } from '../entity/EntityAdapters.js';
|
|
4
4
|
import type { ValidationResult } from '../judge/result.js';
|
|
5
5
|
import type { ValidateOptions } from '../judge/options.js';
|
|
6
6
|
import type { SchemaDerivation } from './SchemaDerivation.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { roleAxis } from './role/RoleAxis.js';
|
|
2
2
|
import { lifecycleAxis } from './lifecycle/LifecycleAxis.js';
|
|
3
3
|
import { boundaryAxis } from './boundary/BoundaryAxis.js';
|
|
4
|
-
import type { ValidationError } from '
|
|
4
|
+
import type { ValidationError } from '../../judge/result.js';
|
|
5
5
|
|
|
6
6
|
export interface Axis<Declared = unknown, Wire = unknown> {
|
|
7
7
|
readonly slot: 'role' | 'lifecycle' | 'boundary';
|
|
@@ -19,7 +19,10 @@ export class Boundary implements BoundaryRules {
|
|
|
19
19
|
readonly decode: Decoder;
|
|
20
20
|
readonly encode: Encoder;
|
|
21
21
|
|
|
22
|
-
private constructor(
|
|
22
|
+
private constructor(
|
|
23
|
+
rules: BoundaryRules = {},
|
|
24
|
+
codecs?: { decode: Decoder; encode: Encoder },
|
|
25
|
+
) {
|
|
23
26
|
this.in = rules.in;
|
|
24
27
|
this.out = rules.out;
|
|
25
28
|
this.decode = codecs?.decode ?? identityDecoder;
|
|
@@ -39,10 +42,19 @@ export class Boundary implements BoundaryRules {
|
|
|
39
42
|
static of(field: Field): Boundary {
|
|
40
43
|
const declared = Boundary.declared(field);
|
|
41
44
|
const derived = Boundary.forShape(field.shape);
|
|
42
|
-
const rules: BoundaryRules = {
|
|
45
|
+
const rules: BoundaryRules = {
|
|
46
|
+
in: declared.in ?? derived.in,
|
|
47
|
+
out: declared.out ?? derived.out,
|
|
48
|
+
};
|
|
43
49
|
return new Boundary(rules, {
|
|
44
|
-
decode:
|
|
45
|
-
|
|
50
|
+
decode:
|
|
51
|
+
typeof rules.in === 'object'
|
|
52
|
+
? Boundaries.decoder(rules.in.decode)
|
|
53
|
+
: identityDecoder,
|
|
54
|
+
encode:
|
|
55
|
+
typeof rules.out === 'object'
|
|
56
|
+
? Boundaries.encoder(rules.out.encode)
|
|
57
|
+
: identityEncoder,
|
|
46
58
|
});
|
|
47
59
|
}
|
|
48
60
|
|
|
@@ -65,5 +77,4 @@ export class Boundary implements BoundaryRules {
|
|
|
65
77
|
get writeOnly(): boolean {
|
|
66
78
|
return this.out === 'closed';
|
|
67
79
|
}
|
|
68
|
-
|
|
69
80
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Axis } from '../Axis.js';
|
|
2
|
-
import { admitWire } from '
|
|
3
|
-
import { isObject } from '
|
|
2
|
+
import { admitWire } from '../../../projection/card/admission.js';
|
|
3
|
+
import { isObject } from '../../../utils.js';
|
|
4
4
|
import type { BoundaryRef } from './Boundary.js';
|
|
5
5
|
|
|
6
6
|
export const boundaryAxis: Axis<BoundaryRef, BoundaryRef> = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Axis } from '../Axis.js';
|
|
2
|
-
import type { ValidationError } from '
|
|
3
|
-
import { admitWire } from '
|
|
4
|
-
import { isObject
|
|
2
|
+
import type { ValidationError } from '../../../judge/result.js';
|
|
3
|
+
import { admitWire, oneOfTokens } from '../../../projection/card/admission.js';
|
|
4
|
+
import { isObject } from '../../../utils.js';
|
|
5
5
|
import { CREATE_TOKENS, UPDATE_TOKENS, type LifecycleRules } from './Lifecycle.js';
|
|
6
6
|
|
|
7
7
|
export const lifecycleAxis: Axis<LifecycleRules, LifecycleRules> = {
|
|
@@ -31,7 +31,8 @@ export function applyUpdate(fields: Fields, patch: Row): Row {
|
|
|
31
31
|
const instant = Clock.now();
|
|
32
32
|
|
|
33
33
|
for (const [name, field] of Object.entries(fields) as [string, Field][]) {
|
|
34
|
-
if (Lifecycle.of(field).stampedOnUpdate && !(name in out))
|
|
34
|
+
if (Lifecycle.of(field).stampedOnUpdate && !(name in out))
|
|
35
|
+
out[name] = new Date(instant);
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
return out;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FieldGroup } from "../../constraint/FieldGroup.js";
|
|
2
|
-
import { Unique } from "../../constraint/Unique.js";
|
|
1
|
+
import { FieldGroup } from "../../fields/constraint/FieldGroup.js";
|
|
2
|
+
import { Unique } from "../../fields/constraint/Unique.js";
|
|
3
3
|
import type { EntityConstructor, Relation } from "./Relation.js";
|
|
4
4
|
|
|
5
5
|
export interface RoleRules {
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { Axis, Resolver } from '../Axis.js';
|
|
2
|
-
import { refuse } from '
|
|
3
|
-
import { isObject,
|
|
4
|
-
import type { ValidationError } from '
|
|
2
|
+
import { refuse, oneOfTokens } from '../../../projection/card/admission.js';
|
|
3
|
+
import { isObject, lowerFirst } from '../../../utils.js';
|
|
4
|
+
import type { ValidationError } from '../../../judge/result.js';
|
|
5
5
|
import { ON_DELETE, RELATION_KINDS, type EntityConstructor, type Relation } from './Relation.js';
|
|
6
6
|
import { type RoleRules } from './Role.js';
|
|
7
|
-
import { FieldGroup } from '../../constraint/FieldGroup.js';
|
|
8
|
-
import { Unique } from '../../constraint/Unique.js';
|
|
9
|
-
import type { RoleDescriptor } from '
|
|
10
|
-
import { lowerFirst } from '../../utils.js';
|
|
7
|
+
import { FieldGroup } from '../../fields/constraint/FieldGroup.js';
|
|
8
|
+
import { Unique } from '../../fields/constraint/Unique.js';
|
|
9
|
+
import type { RoleDescriptor } from '../../../projection/card/Descriptor.js';
|
|
11
10
|
|
|
12
11
|
export const roleAxis: Axis<RoleRules, RoleDescriptor> = {
|
|
13
12
|
slot: 'role',
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { Shape } from
|
|
2
|
-
import { Role, type RoleRules } from
|
|
3
|
-
import type { LifecycleRules } from
|
|
4
|
-
import type { BoundaryRef } from
|
|
5
|
-
import type { Meta } from
|
|
6
|
-
import type { Axis } from
|
|
7
|
-
import { FieldJudge } from
|
|
8
|
-
import { ValueJudge } from
|
|
1
|
+
import type { Shape } from '../axis/shape/Shape.js';
|
|
2
|
+
import { Role, type RoleRules } from '../axis/role/Role.js';
|
|
3
|
+
import type { LifecycleRules } from '../axis/lifecycle/Lifecycle.js';
|
|
4
|
+
import type { BoundaryRef } from '../axis/boundary/Boundary.js';
|
|
5
|
+
import type { Meta } from '../axis/Meta.js';
|
|
6
|
+
import type { Axis } from '../axis/Axis.js';
|
|
7
|
+
import { FieldJudge } from '../../judge/FieldJudge.js';
|
|
8
|
+
import { ValueJudge } from '../../judge/ValueJudge.js';
|
|
9
9
|
|
|
10
10
|
export type Fields = Record<string, Field>;
|
|
11
11
|
|
|
@@ -13,7 +13,7 @@ export type Fields = Record<string, Field>;
|
|
|
13
13
|
export type FieldName<TFields extends Fields> = Extract<keyof TFields, string>;
|
|
14
14
|
|
|
15
15
|
/** The carrier, the three extension axes, the annotation — the five the judge reads. */
|
|
16
|
-
export type FieldDeclaration = Pick<Field,
|
|
16
|
+
export type FieldDeclaration = Pick<Field, 'shape' | Axis['slot'] | 'meta'>;
|
|
17
17
|
|
|
18
18
|
export class Field<T = unknown> {
|
|
19
19
|
readonly shape: Shape;
|
|
@@ -29,8 +29,8 @@ export class Field<T = unknown> {
|
|
|
29
29
|
|
|
30
30
|
if (!verdict.success) {
|
|
31
31
|
throw new Error(
|
|
32
|
-
`${key ? `Field '${key}': ` :
|
|
33
|
-
verdict.errors.map((e) => `${e.path}: ${e.message}`).join(
|
|
32
|
+
`${key ? `Field '${key}': ` : ''}` +
|
|
33
|
+
verdict.errors.map((e) => `${e.path}: ${e.message}`).join('; '),
|
|
34
34
|
);
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -41,11 +41,11 @@ export class Field<T = unknown> {
|
|
|
41
41
|
this.meta = init.meta;
|
|
42
42
|
|
|
43
43
|
const create = this.lifecycle?.create;
|
|
44
|
-
if (typeof create ===
|
|
44
|
+
if (typeof create === 'object' && create !== null && 'value' in create) {
|
|
45
45
|
const checked = ValueJudge.of(this).check(create.value);
|
|
46
|
-
if (
|
|
46
|
+
if ('error' in checked)
|
|
47
47
|
throw new Error(
|
|
48
|
-
`${key ? `Field '${key}': ` :
|
|
48
|
+
`${key ? `Field '${key}': ` : ''}the declared default ${JSON.stringify(create.value)} ` +
|
|
49
49
|
`is not a legal value for it — ${checked.error}.`,
|
|
50
50
|
);
|
|
51
51
|
}
|
|
@@ -77,4 +77,3 @@ export class Field<T = unknown> {
|
|
|
77
77
|
});
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Role } from '../axis/role/Role.js';
|
|
2
|
-
import { FieldGroup } from '
|
|
3
|
-
import { Unique } from '
|
|
4
|
-
import type { CompositeUnique } from '
|
|
2
|
+
import { FieldGroup } from './constraint/FieldGroup.js';
|
|
3
|
+
import { Unique } from './constraint/Unique.js';
|
|
4
|
+
import type { CompositeUnique } from '../../entity/EntityDeclarations.js';
|
|
5
5
|
import { Field, type FieldName, type Fields } from './Field.js';
|
|
6
6
|
|
|
7
7
|
export class FieldSet<TFields extends Fields = Fields> {
|
|
@@ -21,7 +21,8 @@ export class FieldSet<TFields extends Fields = Fields> {
|
|
|
21
21
|
unique?: CompositeUnique<TFields>,
|
|
22
22
|
): TFields {
|
|
23
23
|
let fields: Fields = {};
|
|
24
|
-
for (const [key, field] of Object.entries(declared))
|
|
24
|
+
for (const [key, field] of Object.entries(declared))
|
|
25
|
+
fields[key] = new Field(field, key);
|
|
25
26
|
for (const group of unique ?? []) fields = new Unique(group).onto(fields);
|
|
26
27
|
return fields as TFields;
|
|
27
28
|
}
|
|
@@ -32,7 +33,7 @@ export class FieldSet<TFields extends Fields = Fields> {
|
|
|
32
33
|
* `Role.of(field).isPrimary` answers about ONE field; this answers about a shape, which
|
|
33
34
|
* is the question every reader actually had. It was the same three lines spelled five
|
|
34
35
|
* times — a mirror's key, a form's row identity, GraphQL's node id, the DDL's primary
|
|
35
|
-
* key and the
|
|
36
|
+
* key and the storage's `findById` column — so a shape with two primaries meant whichever
|
|
36
37
|
* one that loop happened to see first, five times over.
|
|
37
38
|
*
|
|
38
39
|
* The absence is answered and not defaulted: `'id'` is a fine fallback for a form and a
|
|
@@ -46,7 +47,7 @@ export class FieldSet<TFields extends Fields = Fields> {
|
|
|
46
47
|
if (primaries.length > 1) {
|
|
47
48
|
throw new Error(
|
|
48
49
|
`FieldSet.primary: ${primaries.map((name) => JSON.stringify(name)).join(', ')} all declare ` +
|
|
49
|
-
|
|
50
|
+
'`primary`; a field set can have only one primary field.',
|
|
50
51
|
);
|
|
51
52
|
}
|
|
52
53
|
|
|
@@ -56,7 +57,7 @@ export class FieldSet<TFields extends Fields = Fields> {
|
|
|
56
57
|
get uniqueGroups(): CompositeUnique<TFields> | undefined {
|
|
57
58
|
const groups = FieldGroup.groupsOf(this.fields, Unique);
|
|
58
59
|
return groups.length
|
|
59
|
-
? groups.map((group) => [...group.members]) as unknown as CompositeUnique<TFields>
|
|
60
|
+
? (groups.map((group) => [...group.members]) as unknown as CompositeUnique<TFields>)
|
|
60
61
|
: undefined;
|
|
61
62
|
}
|
|
62
63
|
}
|