@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
package/src/entity.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Fields } from './fields/Field.js';
|
|
2
|
-
import { type EntityDeclarations } from './EntityDeclarations.js';
|
|
1
|
+
import { type Fields } from './schema/fields/Field.js';
|
|
2
|
+
import { type EntityDeclarations } from './entity/EntityDeclarations.js';
|
|
3
3
|
import { Schema, type SchemaConstructor } from './schema/Schema.js';
|
|
4
4
|
|
|
5
5
|
export function entity<TFields extends Fields>(
|
package/src/index.ts
CHANGED
|
@@ -1,31 +1,42 @@
|
|
|
1
|
-
export { Field, type Fields } from './fields/Field.js';
|
|
2
|
-
export { FieldSet } from './fields/FieldSet.js';
|
|
3
|
-
export { type Shape, Anatomy } from './axis/shape/Shape.js';
|
|
4
|
-
export {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
12
|
-
export { type
|
|
13
|
-
export {
|
|
14
|
-
export {
|
|
1
|
+
export { Field, type Fields } from './schema/fields/Field.js';
|
|
2
|
+
export { FieldSet } from './schema/fields/FieldSet.js';
|
|
3
|
+
export { type Shape, Anatomy } from './schema/axis/shape/Shape.js';
|
|
4
|
+
export {
|
|
5
|
+
type StringFormat,
|
|
6
|
+
type FormatPredicate,
|
|
7
|
+
Formats,
|
|
8
|
+
} from './schema/axis/shape/Formats.js';
|
|
9
|
+
export { Role, type RoleRules } from './schema/axis/role/Role.js';
|
|
10
|
+
export { type Relation, type EntityConstructor } from './schema/axis/role/Relation.js';
|
|
11
|
+
export { Lifecycle, type LifecycleRules } from './schema/axis/lifecycle/Lifecycle.js';
|
|
12
|
+
export { type GeneratorRef, Generators } from './schema/axis/lifecycle/Generators.js';
|
|
13
|
+
export { Clock } from './schema/axis/lifecycle/Clock.js';
|
|
14
|
+
export {
|
|
15
|
+
Boundary,
|
|
16
|
+
type BoundaryRules,
|
|
17
|
+
type BoundaryRef,
|
|
18
|
+
} from './schema/axis/boundary/Boundary.js';
|
|
19
|
+
export { type Decoder, type Encoder, Boundaries } from './schema/axis/boundary/Boundaries.js';
|
|
20
|
+
export { type Meta } from './schema/axis/Meta.js';
|
|
21
|
+
export { FieldGroup } from './schema/fields/constraint/FieldGroup.js';
|
|
22
|
+
export { Unique } from './schema/fields/constraint/Unique.js';
|
|
15
23
|
|
|
16
|
-
export {
|
|
24
|
+
export {
|
|
25
|
+
Schema,
|
|
26
|
+
ANONYMOUS_SCHEMA_NAME,
|
|
27
|
+
type SchemaConstructor,
|
|
28
|
+
} from './schema/Schema.js';
|
|
17
29
|
export { SchemaDerivation } from './schema/SchemaDerivation.js';
|
|
18
|
-
export {
|
|
19
|
-
export { Cases, type Case } from './judge/Cases.js';
|
|
30
|
+
export { Cases, type Case } from './projection/Cases.js';
|
|
20
31
|
export { RowRefusal } from './judge/RowRefusal.js';
|
|
21
32
|
export { type SchemaView, type Row, type PartialRow } from './schema/SchemaView.js';
|
|
22
|
-
export { type FougereEntityAdapters, type EntityAdapters } from './EntityAdapters.js';
|
|
33
|
+
export { type FougereEntityAdapters, type EntityAdapters } from './entity/EntityAdapters.js';
|
|
23
34
|
export {
|
|
24
35
|
type EntityDeclarations,
|
|
25
36
|
type CompositeUnique,
|
|
26
37
|
type PreviousNames,
|
|
27
|
-
} from './EntityDeclarations.js';
|
|
28
|
-
export { lowerFirst, upperFirst } from './utils.js';
|
|
38
|
+
} from './entity/EntityDeclarations.js';
|
|
39
|
+
export { lowerFirst, upperFirst, isObject } from './utils.js';
|
|
29
40
|
|
|
30
41
|
export { primary } from './vocabulary/primary.js';
|
|
31
42
|
export { text } from './vocabulary/text.js';
|
|
@@ -49,14 +60,36 @@ export { readOnly } from './vocabulary/readOnly.js';
|
|
|
49
60
|
export { writeOnly } from './vocabulary/writeOnly.js';
|
|
50
61
|
export { json } from './vocabulary/json.js';
|
|
51
62
|
|
|
52
|
-
export { applyCreate, applyUpdate } from './axis/lifecycle/apply.js';
|
|
63
|
+
export { applyCreate, applyUpdate } from './schema/axis/lifecycle/apply.js';
|
|
53
64
|
export { Visibility } from './projection/Visibility.js';
|
|
54
|
-
export { Card } from './card/Card.js';
|
|
55
|
-
export { Bundle } from './card/Bundle.js';
|
|
56
|
-
export type {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
export { Card } from './projection/card/Card.js';
|
|
66
|
+
export { Bundle } from './projection/card/Bundle.js';
|
|
67
|
+
export type {
|
|
68
|
+
Change,
|
|
69
|
+
Diff,
|
|
70
|
+
DiffOptions,
|
|
71
|
+
SetDiff,
|
|
72
|
+
SetDiffOptions,
|
|
73
|
+
RenameCandidate,
|
|
74
|
+
TypeSet,
|
|
75
|
+
} from './projection/card/diff.js';
|
|
76
|
+
export {
|
|
77
|
+
EntityTypeSource,
|
|
78
|
+
type EntityTypeSourceOptions,
|
|
79
|
+
} from './projection/card/EntityTypeSource.js';
|
|
80
|
+
export {
|
|
81
|
+
FacadeTypeSource,
|
|
82
|
+
type FacadeTypeSourceOptions,
|
|
83
|
+
type OpDescriptor,
|
|
84
|
+
} from './projection/card/FacadeTypeSource.js';
|
|
85
|
+
export {
|
|
86
|
+
type SchemaBundle,
|
|
87
|
+
type SchemaDescriptor,
|
|
88
|
+
type FieldDescriptor,
|
|
89
|
+
type FieldExtension,
|
|
90
|
+
type RoleDescriptor,
|
|
91
|
+
type RelationDescriptor,
|
|
92
|
+
} from './projection/card/Descriptor.js';
|
|
60
93
|
export { type SchemaOrCard, schemaOf, fieldsOf } from './projection/SchemaOrCard.js';
|
|
61
94
|
export type { StandardSchemaV1 } from './projection/standard.js';
|
|
62
95
|
|
|
@@ -66,4 +99,8 @@ export { FieldJudge } from './judge/FieldJudge.js';
|
|
|
66
99
|
export { ValueJudge } from './judge/ValueJudge.js';
|
|
67
100
|
export { RowJudge } from './judge/RowJudge.js';
|
|
68
101
|
export { type ValidateOptions } from './judge/options.js';
|
|
69
|
-
export {
|
|
102
|
+
export {
|
|
103
|
+
type ValidationError,
|
|
104
|
+
type ValidationResult,
|
|
105
|
+
type Checked,
|
|
106
|
+
} from './judge/result.js';
|
package/src/judge/FieldJudge.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { EXTENSION_AXES } from
|
|
2
|
-
import { Anatomy } from
|
|
3
|
-
import type { Field } from
|
|
4
|
-
import { isObject } from
|
|
5
|
-
import type { ValidationError, ValidationResult } from
|
|
1
|
+
import { EXTENSION_AXES } from '../schema/axis/Axis.js';
|
|
2
|
+
import { Anatomy } from '../schema/axis/shape/Shape.js';
|
|
3
|
+
import type { Field } from '../schema/fields/Field.js';
|
|
4
|
+
import { isObject } from '../utils.js';
|
|
5
|
+
import type { ValidationError, ValidationResult } from './result.js';
|
|
6
6
|
|
|
7
7
|
export class FieldJudge {
|
|
8
8
|
private constructor(private readonly declaration: unknown) {}
|
|
@@ -19,7 +19,7 @@ export class FieldJudge {
|
|
|
19
19
|
success: false,
|
|
20
20
|
errors: [
|
|
21
21
|
{
|
|
22
|
-
path:
|
|
22
|
+
path: '.',
|
|
23
23
|
message: `Expected an object — got ${JSON.stringify(declaration)}`,
|
|
24
24
|
},
|
|
25
25
|
],
|
|
@@ -30,7 +30,7 @@ export class FieldJudge {
|
|
|
30
30
|
|
|
31
31
|
if (!Anatomy.is(declaration.shape)) {
|
|
32
32
|
errors.push({
|
|
33
|
-
path:
|
|
33
|
+
path: 'shape',
|
|
34
34
|
message: `Every field states a shape — got ${JSON.stringify(declaration.shape)}`,
|
|
35
35
|
});
|
|
36
36
|
}
|
|
@@ -43,14 +43,14 @@ export class FieldJudge {
|
|
|
43
43
|
if (declaration.meta !== undefined) {
|
|
44
44
|
if (!isObject(declaration.meta)) {
|
|
45
45
|
errors.push({
|
|
46
|
-
path:
|
|
46
|
+
path: 'meta',
|
|
47
47
|
message: `Expected an object — got ${JSON.stringify(declaration.meta)}`,
|
|
48
48
|
});
|
|
49
49
|
} else if (
|
|
50
50
|
declaration.meta.description !== undefined &&
|
|
51
|
-
typeof declaration.meta.description !==
|
|
51
|
+
typeof declaration.meta.description !== 'string'
|
|
52
52
|
) {
|
|
53
|
-
errors.push({ path:
|
|
53
|
+
errors.push({ path: 'meta.description', message: 'Expected a string' });
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
package/src/judge/RowJudge.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Boundary } from '../axis/boundary/Boundary.js';
|
|
2
|
-
import { Lifecycle } from '../axis/lifecycle/Lifecycle.js';
|
|
3
|
-
import { Role } from '../axis/role/Role.js';
|
|
4
|
-
import type { Field, Fields } from '../fields/Field.js';
|
|
1
|
+
import { Boundary } from '../schema/axis/boundary/Boundary.js';
|
|
2
|
+
import { Lifecycle } from '../schema/axis/lifecycle/Lifecycle.js';
|
|
3
|
+
import { Role } from '../schema/axis/role/Role.js';
|
|
4
|
+
import type { Field, Fields } from '../schema/fields/Field.js';
|
|
5
5
|
import type { ValidateOptions } from './options.js';
|
|
6
6
|
import type { ValidationError, ValidationResult } from './result.js';
|
|
7
7
|
import { ValueJudge } from './ValueJudge.js';
|
package/src/judge/ValueJudge.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Validator, format as engineFormats } from '@cfworker/json-schema';
|
|
2
|
-
import { Formats, type FormatPredicate } from '../axis/shape/Formats.js';
|
|
3
|
-
import { Anatomy, type Shape } from '../axis/shape/Shape.js';
|
|
4
|
-
import type { Field } from '../fields/Field.js';
|
|
2
|
+
import { Formats, type FormatPredicate } from '../schema/axis/shape/Formats.js';
|
|
3
|
+
import { Anatomy, type Shape } from '../schema/axis/shape/Shape.js';
|
|
4
|
+
import type { Field } from '../schema/fields/Field.js';
|
|
5
5
|
import type { Checked } from './result.js';
|
|
6
6
|
|
|
7
7
|
interface ShapePlan {
|
|
@@ -24,7 +24,11 @@ export class ValueJudge {
|
|
|
24
24
|
const base = Anatomy.of(shape).base;
|
|
25
25
|
if (value !== null) {
|
|
26
26
|
if (base?.type === 'object' && !base.properties) return { value };
|
|
27
|
-
if (
|
|
27
|
+
if (
|
|
28
|
+
base?.type === 'string' &&
|
|
29
|
+
base.format === 'date-time' &&
|
|
30
|
+
value instanceof Date
|
|
31
|
+
) {
|
|
28
32
|
return Number.isNaN(value.getTime()) ? { error: 'Invalid date' } : { value };
|
|
29
33
|
}
|
|
30
34
|
if (
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Anatomy } from '../axis/shape/Shape.js';
|
|
2
|
-
import { Boundary } from '../axis/boundary/Boundary.js';
|
|
3
|
-
import { Lifecycle } from '../axis/lifecycle/Lifecycle.js';
|
|
4
|
-
import { Role } from '../axis/role/Role.js';
|
|
5
|
-
import type { Field } from '../fields/Field.js';
|
|
1
|
+
import { Anatomy } from '../schema/axis/shape/Shape.js';
|
|
2
|
+
import { Boundary } from '../schema/axis/boundary/Boundary.js';
|
|
3
|
+
import { Lifecycle } from '../schema/axis/lifecycle/Lifecycle.js';
|
|
4
|
+
import { Role } from '../schema/axis/role/Role.js';
|
|
5
|
+
import type { Field } from '../schema/fields/Field.js';
|
|
6
6
|
import type { SchemaView } from '../schema/SchemaView.js';
|
|
7
|
-
import { RowJudge } from '
|
|
8
|
-
import { RowRefusal } from '
|
|
7
|
+
import { RowJudge } from '../judge/RowJudge.js';
|
|
8
|
+
import { RowRefusal } from '../judge/RowRefusal.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* One input, and what the judge must answer.
|
|
@@ -50,14 +50,19 @@ function outOfBoundsFor(field: Field): { why: string; value: unknown }[] {
|
|
|
50
50
|
if (shape.enum) out.push({ why: 'outside the stated set', value: '__not-in-enum__' });
|
|
51
51
|
}
|
|
52
52
|
if (shape?.type === 'number' || shape?.type === 'integer') {
|
|
53
|
-
if (typeof shape.minimum === 'number')
|
|
54
|
-
|
|
53
|
+
if (typeof shape.minimum === 'number')
|
|
54
|
+
out.push({ why: 'below minimum', value: shape.minimum - 1 });
|
|
55
|
+
if (typeof shape.maximum === 'number')
|
|
56
|
+
out.push({ why: 'above maximum', value: shape.maximum + 1 });
|
|
55
57
|
}
|
|
56
58
|
if (shape?.type === 'array') {
|
|
57
59
|
if (typeof shape.minItems === 'number' && shape.minItems > 0)
|
|
58
60
|
out.push({ why: 'fewer items than min', value: [] });
|
|
59
61
|
if (typeof shape.maxItems === 'number')
|
|
60
|
-
out.push({
|
|
62
|
+
out.push({
|
|
63
|
+
why: 'more items than max',
|
|
64
|
+
value: Array.from({ length: shape.maxItems + 1 }, () => null),
|
|
65
|
+
});
|
|
61
66
|
}
|
|
62
67
|
return out;
|
|
63
68
|
}
|
|
@@ -69,9 +74,7 @@ function outOfBoundsFor(field: Field): { why: string; value: unknown }[] {
|
|
|
69
74
|
* supplies a valid row; generating data belongs to the testing package.
|
|
70
75
|
*/
|
|
71
76
|
export class Cases {
|
|
72
|
-
private constructor(
|
|
73
|
-
readonly all: readonly Case[],
|
|
74
|
-
) {}
|
|
77
|
+
private constructor(readonly all: readonly Case[]) {}
|
|
75
78
|
|
|
76
79
|
static of(entity: SchemaView, valid: Record<string, unknown>): Cases {
|
|
77
80
|
return new Cases(enumerate(entity, valid));
|
|
@@ -83,7 +86,10 @@ export class Cases {
|
|
|
83
86
|
* Takes the RESULT rather than the input so the same reader serves the local judge, the
|
|
84
87
|
* façade and a door — the three that have to agree.
|
|
85
88
|
*/
|
|
86
|
-
static holds(
|
|
89
|
+
static holds(
|
|
90
|
+
expected: Case['expect'],
|
|
91
|
+
result: { success: boolean; errors?: { path: string }[] },
|
|
92
|
+
): boolean {
|
|
87
93
|
if (expected === 'accept') return result.success;
|
|
88
94
|
if (result.success) return false;
|
|
89
95
|
return (result.errors ?? []).some((error) => error.path === expected.reject);
|
|
@@ -106,8 +112,18 @@ function enumerate(entity: SchemaView, valid: Record<string, unknown>): Case[] {
|
|
|
106
112
|
const withField = (name: string, value: unknown) => ({ ...valid, [name]: value });
|
|
107
113
|
|
|
108
114
|
cases.push({ why: 'a valid body', body: valid, patch: false, expect: 'accept' });
|
|
109
|
-
cases.push({
|
|
110
|
-
|
|
115
|
+
cases.push({
|
|
116
|
+
why: 'a key outside the contract',
|
|
117
|
+
body: { ...valid, __unknown__: 'x' },
|
|
118
|
+
patch: false,
|
|
119
|
+
expect: { reject: '__unknown__' },
|
|
120
|
+
});
|
|
121
|
+
cases.push({
|
|
122
|
+
why: 'not an object at all',
|
|
123
|
+
body: 'a string',
|
|
124
|
+
patch: false,
|
|
125
|
+
expect: { reject: '.' },
|
|
126
|
+
});
|
|
111
127
|
|
|
112
128
|
for (const [name, field] of Object.entries(fields) as [string, Field][]) {
|
|
113
129
|
// A reference names a row that must exist; the caller supplied its id and we do not
|
|
@@ -121,17 +137,37 @@ function enumerate(entity: SchemaView, valid: Record<string, unknown>): Case[] {
|
|
|
121
137
|
}
|
|
122
138
|
|
|
123
139
|
if (Boundary.of(field).readOnly) {
|
|
124
|
-
cases.push({
|
|
140
|
+
cases.push({
|
|
141
|
+
why: `${name} supplied although read-only`,
|
|
142
|
+
body: withField(name, wrongTypeFor(field)),
|
|
143
|
+
patch: false,
|
|
144
|
+
expect: { reject: name },
|
|
145
|
+
});
|
|
125
146
|
}
|
|
126
147
|
|
|
127
148
|
if (Lifecycle.of(field).immutable && !Role.of(field).isPrimary) {
|
|
128
|
-
cases.push({
|
|
149
|
+
cases.push({
|
|
150
|
+
why: `${name} supplied on an update`,
|
|
151
|
+
body: { [name]: valid[name] ?? wrongTypeFor(field) },
|
|
152
|
+
patch: true,
|
|
153
|
+
expect: { reject: name },
|
|
154
|
+
});
|
|
129
155
|
}
|
|
130
156
|
|
|
131
157
|
if (name in valid && !isRef) {
|
|
132
|
-
cases.push({
|
|
158
|
+
cases.push({
|
|
159
|
+
why: `${name} of the wrong type`,
|
|
160
|
+
body: withField(name, wrongTypeFor(field)),
|
|
161
|
+
patch: false,
|
|
162
|
+
expect: { reject: name },
|
|
163
|
+
});
|
|
133
164
|
for (const { why, value } of outOfBoundsFor(field))
|
|
134
|
-
cases.push({
|
|
165
|
+
cases.push({
|
|
166
|
+
why: `${name} ${why}`,
|
|
167
|
+
body: withField(name, value),
|
|
168
|
+
patch: false,
|
|
169
|
+
expect: { reject: name },
|
|
170
|
+
});
|
|
135
171
|
}
|
|
136
172
|
}
|
|
137
173
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Fields } from '../fields/Field.js';
|
|
1
|
+
import type { Fields } from '../schema/fields/Field.js';
|
|
2
2
|
import type { SchemaView } from '../schema/SchemaView.js';
|
|
3
|
-
import type { SchemaDescriptor } from '
|
|
4
|
-
import { Card } from '
|
|
3
|
+
import type { SchemaDescriptor } from './card/Descriptor.js';
|
|
4
|
+
import { Card } from './card/Card.js';
|
|
5
5
|
|
|
6
6
|
export type SchemaOrCard = SchemaView | SchemaDescriptor;
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Boundary } from '../axis/boundary/Boundary.js';
|
|
2
|
-
import { Lifecycle } from '../axis/lifecycle/Lifecycle.js';
|
|
3
|
-
import { Role } from '../axis/role/Role.js';
|
|
4
|
-
import type { Fields } from '../fields/Field.js';
|
|
1
|
+
import { Boundary } from '../schema/axis/boundary/Boundary.js';
|
|
2
|
+
import { Lifecycle } from '../schema/axis/lifecycle/Lifecycle.js';
|
|
3
|
+
import { Role } from '../schema/axis/role/Role.js';
|
|
4
|
+
import type { Fields } from '../schema/fields/Field.js';
|
|
5
5
|
|
|
6
6
|
export class Visibility {
|
|
7
7
|
private constructor(private readonly fields: Fields) {}
|
|
@@ -37,7 +37,10 @@ export class Visibility {
|
|
|
37
37
|
for (const [key, field] of Object.entries(this.fields)) {
|
|
38
38
|
if (!(key in record)) continue;
|
|
39
39
|
const boundary = Boundary.of(field);
|
|
40
|
-
if (boundary.writeOnly) {
|
|
40
|
+
if (boundary.writeOnly) {
|
|
41
|
+
delete out[key];
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
41
44
|
const value = record[key];
|
|
42
45
|
if (value === null || value === undefined) continue;
|
|
43
46
|
out[key] = boundary.encode(value);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Resolver } from '
|
|
2
|
-
import type { EntityConstructor } from '
|
|
3
|
-
import { lowerFirst } from '
|
|
4
|
-
import type { SchemaView } from '
|
|
1
|
+
import type { Resolver } from '../../schema/axis/Axis.js';
|
|
2
|
+
import type { EntityConstructor } from '../../schema/axis/role/Relation.js';
|
|
3
|
+
import { lowerFirst } from '../../utils.js';
|
|
4
|
+
import type { SchemaView } from '../../schema/SchemaView.js';
|
|
5
5
|
import { Card } from './Card.js';
|
|
6
6
|
import type { SchemaBundle, SchemaDescriptor } from './Descriptor.js';
|
|
7
7
|
import type { Diff, SetDiff, SetDiffOptions } from './diff.js';
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { EXTENSION_AXES, EXTENSION_SLOTS, type Resolver } from '
|
|
1
|
+
import { EXTENSION_AXES, EXTENSION_SLOTS, type Resolver } from '../../schema/axis/Axis.js';
|
|
2
2
|
import { dequal } from 'dequal';
|
|
3
|
-
import { clean } from '
|
|
4
|
-
import { Field, type Fields } from '
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import type { Row, SchemaView } from '../schema/SchemaView.js';
|
|
3
|
+
import { clean, isObject } from '../../utils.js';
|
|
4
|
+
import { Field, type Fields } from '../../schema/fields/Field.js';
|
|
5
|
+
import { RowJudge } from '../../judge/RowJudge.js';
|
|
6
|
+
import { Schema, type SchemaConstructor } from '../../schema/Schema.js';
|
|
7
|
+
import type { Row, SchemaView } from '../../schema/SchemaView.js';
|
|
9
8
|
import { refuse } from './admission.js';
|
|
10
9
|
import type {
|
|
11
10
|
DerivedFrom,
|
|
@@ -21,7 +20,10 @@ type FieldsOf<T> = { [K in keyof T]-?: Field<T[K]> };
|
|
|
21
20
|
export class Card<T = Row<Fields>> {
|
|
22
21
|
private constructor(readonly descriptor: SchemaDescriptor) {}
|
|
23
22
|
|
|
24
|
-
static fromSchema<TFields extends Fields>(
|
|
23
|
+
static fromSchema<TFields extends Fields>(
|
|
24
|
+
schema: SchemaView<TFields>,
|
|
25
|
+
name?: string,
|
|
26
|
+
): Card<Row<TFields>> {
|
|
25
27
|
const fields = schema.getFields();
|
|
26
28
|
const judge = RowJudge.of(fields);
|
|
27
29
|
const properties: Record<string, FieldDescriptor> = {};
|
|
@@ -62,7 +64,8 @@ export class Card<T = Row<Fields>> {
|
|
|
62
64
|
toSchema(resolve?: Resolver, name?: string): SchemaConstructor<FieldsOf<T>> {
|
|
63
65
|
const descriptor = this.descriptor;
|
|
64
66
|
const where = name ? `schema '${name}'` : 'this schema';
|
|
65
|
-
if (!isObject(descriptor))
|
|
67
|
+
if (!isObject(descriptor))
|
|
68
|
+
refuse(`${where} is not an object`, 'A card carries one JSON Schema per door.');
|
|
66
69
|
const version = descriptor['x-fougere-version'];
|
|
67
70
|
if (version !== 1) {
|
|
68
71
|
refuse(
|
|
@@ -71,7 +74,10 @@ export class Card<T = Row<Fields>> {
|
|
|
71
74
|
);
|
|
72
75
|
}
|
|
73
76
|
if (!isObject(descriptor.properties)) {
|
|
74
|
-
refuse(
|
|
77
|
+
refuse(
|
|
78
|
+
`${where} carries no \`properties\` object`,
|
|
79
|
+
'A schema is its fields; there is nothing to rebuild.',
|
|
80
|
+
);
|
|
75
81
|
}
|
|
76
82
|
|
|
77
83
|
const fields: Fields = {};
|
|
@@ -80,7 +86,8 @@ export class Card<T = Row<Fields>> {
|
|
|
80
86
|
}
|
|
81
87
|
const schema = Schema.of({ fields });
|
|
82
88
|
const title = name ?? descriptor.title;
|
|
83
|
-
if (title)
|
|
89
|
+
if (title)
|
|
90
|
+
Object.defineProperty(schema, 'name', { value: title, configurable: true });
|
|
84
91
|
return schema as unknown as SchemaConstructor<FieldsOf<T>>;
|
|
85
92
|
}
|
|
86
93
|
|
|
@@ -104,11 +111,13 @@ export class Card<T = Row<Fields>> {
|
|
|
104
111
|
continue;
|
|
105
112
|
}
|
|
106
113
|
|
|
107
|
-
if (now !== field)
|
|
114
|
+
if (now !== field)
|
|
115
|
+
changes.push({ kind: 'renamed', from: field, to: now, field: target });
|
|
108
116
|
|
|
109
117
|
const wasType = typesOf(descriptor);
|
|
110
118
|
const isType = typesOf(target);
|
|
111
|
-
if (!dequal(wasType, isType))
|
|
119
|
+
if (!dequal(wasType, isType))
|
|
120
|
+
changes.push({ kind: 'retyped', field: now, from: wasType, to: isType });
|
|
112
121
|
else if (!dequal(boundsOf(descriptor), boundsOf(target))) {
|
|
113
122
|
changes.push({ kind: 'reshaped', field: now, from: descriptor, to: target });
|
|
114
123
|
}
|
|
@@ -122,12 +131,24 @@ export class Card<T = Row<Fields>> {
|
|
|
122
131
|
}
|
|
123
132
|
|
|
124
133
|
const claimed = new Set(Object.values(renamed));
|
|
125
|
-
const added = Object.keys(after).filter(
|
|
134
|
+
const added = Object.keys(after).filter(
|
|
135
|
+
(field) => !(field in before) && !claimed.has(field),
|
|
136
|
+
);
|
|
126
137
|
for (const field of removed) {
|
|
127
|
-
changes.push({
|
|
138
|
+
changes.push({
|
|
139
|
+
kind: 'removed',
|
|
140
|
+
field,
|
|
141
|
+
from: before[field],
|
|
142
|
+
required: requiredBefore.has(field),
|
|
143
|
+
});
|
|
128
144
|
}
|
|
129
145
|
for (const field of added) {
|
|
130
|
-
changes.push({
|
|
146
|
+
changes.push({
|
|
147
|
+
kind: 'added',
|
|
148
|
+
field,
|
|
149
|
+
to: after[field],
|
|
150
|
+
required: requiredAfter.has(field),
|
|
151
|
+
});
|
|
131
152
|
}
|
|
132
153
|
|
|
133
154
|
return { changes, ambiguous: candidates(removed, added, before, after) };
|
|
@@ -160,18 +181,29 @@ function describeField(field: Field, key: string): FieldDescriptor {
|
|
|
160
181
|
function originOf(schema: SchemaView): DerivedFrom | undefined {
|
|
161
182
|
const { derivation } = schema;
|
|
162
183
|
if (!derivation) return undefined;
|
|
163
|
-
const survived = Object.fromEntries(
|
|
184
|
+
const survived = Object.fromEntries(
|
|
185
|
+
Object.entries(derivation.survived).map(([key, value]) => [key, value ?? null]),
|
|
186
|
+
);
|
|
164
187
|
return { from: derivation.sourceName, survived };
|
|
165
188
|
}
|
|
166
189
|
|
|
167
190
|
function reconstructShape(property: FieldDescriptor): Field['shape'] | undefined {
|
|
168
|
-
const types = Array.isArray(property.type)
|
|
191
|
+
const types = Array.isArray(property.type)
|
|
192
|
+
? property.type
|
|
193
|
+
: property.type
|
|
194
|
+
? [property.type]
|
|
195
|
+
: [];
|
|
169
196
|
const base = types.find((type) => type !== 'null');
|
|
170
197
|
if (base === undefined) return undefined;
|
|
171
198
|
const type = property.type as Field['shape']['type'];
|
|
172
199
|
if (base === 'array') {
|
|
173
200
|
const items = property.items ? reconstructShape(property.items) : undefined;
|
|
174
|
-
return clean({
|
|
201
|
+
return clean({
|
|
202
|
+
type,
|
|
203
|
+
items,
|
|
204
|
+
minItems: property.minItems,
|
|
205
|
+
maxItems: property.maxItems,
|
|
206
|
+
}) as Field['shape'];
|
|
175
207
|
}
|
|
176
208
|
switch (base) {
|
|
177
209
|
case 'string':
|
|
@@ -185,20 +217,32 @@ function reconstructShape(property: FieldDescriptor): Field['shape'] | undefined
|
|
|
185
217
|
}) as Field['shape'];
|
|
186
218
|
case 'number':
|
|
187
219
|
case 'integer':
|
|
188
|
-
return clean({
|
|
220
|
+
return clean({
|
|
221
|
+
type,
|
|
222
|
+
minimum: property.minimum,
|
|
223
|
+
maximum: property.maximum,
|
|
224
|
+
}) as Field['shape'];
|
|
189
225
|
case 'boolean':
|
|
190
226
|
return { type } as Field['shape'];
|
|
191
227
|
default:
|
|
192
|
-
return clean({
|
|
228
|
+
return clean({
|
|
229
|
+
type,
|
|
230
|
+
properties: property.properties,
|
|
231
|
+
required: property.required,
|
|
232
|
+
}) as Field['shape'];
|
|
193
233
|
}
|
|
194
234
|
}
|
|
195
235
|
|
|
196
|
-
function reconstructField(
|
|
236
|
+
function reconstructField(
|
|
237
|
+
property: FieldDescriptor,
|
|
238
|
+
key: string,
|
|
239
|
+
resolve?: Resolver,
|
|
240
|
+
): Field {
|
|
197
241
|
const shape = reconstructShape(property);
|
|
198
242
|
if (!shape) {
|
|
199
243
|
throw new Error(
|
|
200
|
-
`Field '${key}': the card carries no \`type\` for it, so there is no shape to rebuild. `
|
|
201
|
-
|
|
244
|
+
`Field '${key}': the card carries no \`type\` for it, so there is no shape to rebuild. ` +
|
|
245
|
+
'A field always states one.',
|
|
202
246
|
);
|
|
203
247
|
}
|
|
204
248
|
const extension = property['x-fougere'];
|
|
@@ -210,13 +254,27 @@ function reconstructField(property: FieldDescriptor, key: string, resolve?: Reso
|
|
|
210
254
|
return new Field({
|
|
211
255
|
shape,
|
|
212
256
|
...axes,
|
|
213
|
-
meta:
|
|
257
|
+
meta:
|
|
258
|
+
property.description !== undefined
|
|
259
|
+
? { description: property.description }
|
|
260
|
+
: undefined,
|
|
214
261
|
} as never);
|
|
215
262
|
}
|
|
216
263
|
|
|
217
|
-
function restated(
|
|
264
|
+
function restated(
|
|
265
|
+
field: string,
|
|
266
|
+
before: FieldExtension | undefined,
|
|
267
|
+
after: FieldExtension | undefined,
|
|
268
|
+
): Change[] {
|
|
218
269
|
return EXTENSION_SLOTS.filter((axis) => !dequal(before?.[axis], after?.[axis])).map(
|
|
219
|
-
(axis) =>
|
|
270
|
+
(axis) =>
|
|
271
|
+
({
|
|
272
|
+
kind: 'restated',
|
|
273
|
+
field,
|
|
274
|
+
axis,
|
|
275
|
+
from: before?.[axis],
|
|
276
|
+
to: after?.[axis],
|
|
277
|
+
}) as Change,
|
|
220
278
|
);
|
|
221
279
|
}
|
|
222
280
|
|
|
@@ -245,7 +303,8 @@ function candidates(
|
|
|
245
303
|
const found: RenameCandidate[] = [];
|
|
246
304
|
for (const gone of removed) {
|
|
247
305
|
for (const appeared of added) {
|
|
248
|
-
if (dequal(shapeOf(before[gone]), shapeOf(after[appeared])))
|
|
306
|
+
if (dequal(shapeOf(before[gone]), shapeOf(after[appeared])))
|
|
307
|
+
found.push({ removed: gone, added: appeared });
|
|
249
308
|
}
|
|
250
309
|
}
|
|
251
310
|
const was = Object.keys(before);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { BoundaryRef } from '
|
|
2
|
-
import type { LifecycleRules } from '
|
|
3
|
-
import type { Relation } from '
|
|
4
|
-
import type { RoleRules } from '
|
|
5
|
-
import type { Shape } from '
|
|
1
|
+
import type { BoundaryRef } from '../../schema/axis/boundary/Boundary.js';
|
|
2
|
+
import type { LifecycleRules } from '../../schema/axis/lifecycle/Lifecycle.js';
|
|
3
|
+
import type { Relation } from '../../schema/axis/role/Relation.js';
|
|
4
|
+
import type { RoleRules } from '../../schema/axis/role/Role.js';
|
|
5
|
+
import type { Shape } from '../../schema/axis/shape/Shape.js';
|
|
6
6
|
|
|
7
7
|
type JsonSchemaType =
|
|
8
8
|
| 'string'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ValidationError } from '
|
|
1
|
+
import type { ValidationError } from '../../judge/result.js';
|
|
2
2
|
|
|
3
3
|
/** A card is refused by naming what is wrong AND the remedy — never by a bare throw. */
|
|
4
4
|
export function refuse(what: string, fix: string): never {
|
|
@@ -23,3 +23,8 @@ export function admitWire(
|
|
|
23
23
|
);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
+
|
|
27
|
+
export const oneOfTokens = <T extends readonly string[]>(
|
|
28
|
+
value: unknown,
|
|
29
|
+
tokens: T,
|
|
30
|
+
): value is T[number] => typeof value === 'string' && (tokens as readonly string[]).includes(value);
|