@fougere/schema 0.12.0-alpha.0 → 0.12.2-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/FougereFieldAxes.d.ts +3 -0
- package/dist/FougereFieldAxes.d.ts.map +1 -0
- package/dist/FougereFieldAxes.js +2 -0
- package/dist/FougereFieldAxes.js.map +1 -0
- package/dist/Schema.d.ts +4 -3
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +3 -0
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaConstraints.d.ts +13 -10
- package/dist/SchemaConstraints.d.ts.map +1 -1
- package/dist/SchemaConstraints.js +32 -20
- package/dist/SchemaConstraints.js.map +1 -1
- package/dist/SchemaDefinition.d.ts.map +1 -1
- package/dist/SchemaDefinition.js +6 -5
- package/dist/SchemaDefinition.js.map +1 -1
- package/dist/SchemaError.d.ts +4 -1
- package/dist/SchemaError.d.ts.map +1 -1
- package/dist/SchemaError.js +6 -3
- package/dist/SchemaError.js.map +1 -1
- package/dist/SchemaView.d.ts +3 -2
- package/dist/SchemaView.d.ts.map +1 -1
- package/dist/axis/Axes.d.ts +16 -0
- package/dist/axis/Axes.d.ts.map +1 -0
- package/dist/axis/Axes.js +27 -0
- package/dist/axis/Axes.js.map +1 -0
- package/dist/axis/Axis.d.ts +15 -9
- package/dist/axis/Axis.d.ts.map +1 -1
- package/dist/axis/Axis.js +1 -10
- package/dist/axis/Axis.js.map +1 -1
- package/dist/axis/boundary/Boundary.d.ts +38 -5
- package/dist/axis/boundary/Boundary.d.ts.map +1 -1
- package/dist/axis/boundary/Boundary.js +18 -11
- package/dist/axis/boundary/Boundary.js.map +1 -1
- package/dist/axis/boundary/Decoder.d.ts +8 -2
- package/dist/axis/boundary/Decoder.d.ts.map +1 -1
- package/dist/axis/boundary/Decoder.js.map +1 -1
- package/dist/axis/lifecycle/Lifecycle.d.ts +29 -8
- package/dist/axis/lifecycle/Lifecycle.d.ts.map +1 -1
- package/dist/axis/lifecycle/Lifecycle.js +26 -11
- package/dist/axis/lifecycle/Lifecycle.js.map +1 -1
- package/dist/axis/lifecycle/apply.d.ts.map +1 -1
- package/dist/axis/lifecycle/apply.js +3 -4
- package/dist/axis/lifecycle/apply.js.map +1 -1
- package/dist/axis/role/Role.d.ts +31 -12
- package/dist/axis/role/Role.d.ts.map +1 -1
- package/dist/axis/role/Role.js +56 -22
- package/dist/axis/role/Role.js.map +1 -1
- package/dist/axis/shape/Shape.d.ts +32 -9
- package/dist/axis/shape/Shape.d.ts.map +1 -1
- package/dist/axis/shape/Shape.js +43 -12
- package/dist/axis/shape/Shape.js.map +1 -1
- package/dist/axis/shape/ShapeFormat.d.ts +10 -0
- package/dist/axis/shape/ShapeFormat.d.ts.map +1 -0
- package/dist/axis/shape/ShapeFormat.js +32 -0
- package/dist/axis/shape/ShapeFormat.js.map +1 -0
- package/dist/axis/shape/{Formats.d.ts → StringFormats.d.ts} +3 -3
- package/dist/axis/shape/StringFormats.d.ts.map +1 -0
- package/dist/axis/shape/{Formats.js → StringFormats.js} +3 -3
- package/dist/axis/shape/StringFormats.js.map +1 -0
- package/dist/entity/EntityDeclarations.d.ts +3 -2
- package/dist/entity/EntityDeclarations.d.ts.map +1 -1
- package/dist/entity/FieldGroups.d.ts +9 -0
- package/dist/entity/FieldGroups.d.ts.map +1 -0
- package/dist/entity/FieldGroups.js +2 -0
- package/dist/entity/FieldGroups.js.map +1 -0
- package/dist/field/Field.d.ts +37 -12
- package/dist/field/Field.d.ts.map +1 -1
- package/dist/field/Field.js +55 -8
- package/dist/field/Field.js.map +1 -1
- package/dist/field/FieldFormat.d.ts +9 -0
- package/dist/field/FieldFormat.d.ts.map +1 -0
- package/dist/field/FieldFormat.js +12 -0
- package/dist/field/FieldFormat.js.map +1 -0
- package/dist/field/FieldSet.d.ts +12 -3
- package/dist/field/FieldSet.d.ts.map +1 -1
- package/dist/field/FieldSet.js +22 -15
- package/dist/field/FieldSet.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/Format.d.ts +75 -0
- package/dist/lib/Format.d.ts.map +1 -0
- package/dist/lib/Format.js +123 -0
- package/dist/lib/Format.js.map +1 -0
- package/dist/lib/JsonSchema.d.ts +2 -0
- package/dist/lib/JsonSchema.d.ts.map +1 -0
- package/dist/lib/JsonSchema.js +2 -0
- package/dist/lib/JsonSchema.js.map +1 -0
- package/dist/lib/Registry.d.ts +4 -2
- package/dist/lib/Registry.d.ts.map +1 -1
- package/dist/lib/Registry.js +11 -5
- package/dist/lib/Registry.js.map +1 -1
- package/dist/lib/UnionToIntersection.d.ts +7 -0
- package/dist/lib/UnionToIntersection.d.ts.map +1 -0
- package/dist/lib/UnionToIntersection.js +2 -0
- package/dist/lib/UnionToIntersection.js.map +1 -0
- package/dist/lib/ValidationResult.d.ts +2 -0
- package/dist/lib/ValidationResult.d.ts.map +1 -1
- package/dist/lib/ValidationResult.js +6 -0
- package/dist/lib/ValidationResult.js.map +1 -1
- package/dist/lib/utils.d.ts +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/projection/Cases.d.ts +1 -1
- package/dist/projection/Cases.d.ts.map +1 -1
- package/dist/projection/Cases.js +20 -8
- package/dist/projection/Cases.js.map +1 -1
- package/dist/projection/Visibility.d.ts +11 -0
- package/dist/projection/Visibility.d.ts.map +1 -1
- package/dist/projection/Visibility.js +28 -6
- package/dist/projection/Visibility.js.map +1 -1
- package/dist/projection/card/Bundle.d.ts.map +1 -1
- package/dist/projection/card/Bundle.js.map +1 -1
- package/dist/projection/card/Card.d.ts.map +1 -1
- package/dist/projection/card/Card.js +24 -30
- package/dist/projection/card/Card.js.map +1 -1
- package/dist/projection/card/CardForm.d.ts +7 -0
- package/dist/projection/card/CardForm.d.ts.map +1 -0
- package/dist/projection/card/CardForm.js +2 -0
- package/dist/projection/card/CardForm.js.map +1 -0
- package/dist/projection/card/CardForms.d.ts +10 -0
- package/dist/projection/card/CardForms.d.ts.map +1 -0
- package/dist/projection/card/CardForms.js +12 -0
- package/dist/projection/card/CardForms.js.map +1 -0
- package/dist/projection/card/Change.d.ts +2 -2
- package/dist/projection/card/Change.d.ts.map +1 -1
- package/dist/projection/card/Diff.js +2 -2
- package/dist/projection/card/Diff.js.map +1 -1
- package/dist/projection/card/FieldExtension.d.ts +4 -2
- package/dist/projection/card/FieldExtension.d.ts.map +1 -1
- package/dist/projection/card/RoleDescriptor.d.ts +15 -3
- package/dist/projection/card/RoleDescriptor.d.ts.map +1 -1
- package/dist/projection/card/RoleDescriptor.js +40 -1
- package/dist/projection/card/RoleDescriptor.js.map +1 -1
- package/dist/projection/card/ShapeKeywords.d.ts +1 -1
- package/dist/projection/card/ShapeKeywords.d.ts.map +1 -1
- package/dist/projection/card/admission.d.ts +0 -14
- package/dist/projection/card/admission.d.ts.map +1 -1
- package/dist/projection/card/admission.js +0 -20
- package/dist/projection/card/admission.js.map +1 -1
- package/dist/validator/FieldDeclarationValidator.d.ts.map +1 -1
- package/dist/validator/FieldDeclarationValidator.js +10 -25
- package/dist/validator/FieldDeclarationValidator.js.map +1 -1
- package/dist/validator/FieldValueValidator.d.ts.map +1 -1
- package/dist/validator/FieldValueValidator.js +9 -29
- package/dist/validator/FieldValueValidator.js.map +1 -1
- package/dist/validator/InputValidator.d.ts +7 -1
- package/dist/validator/InputValidator.d.ts.map +1 -1
- package/dist/validator/InputValidator.js +15 -14
- package/dist/validator/InputValidator.js.map +1 -1
- package/dist/validator/JsonSchemaValidator.d.ts +23 -0
- package/dist/validator/JsonSchemaValidator.d.ts.map +1 -0
- package/dist/validator/JsonSchemaValidator.js +113 -0
- package/dist/validator/JsonSchemaValidator.js.map +1 -0
- package/dist/vocabulary/preset/created.d.ts +2 -2
- package/dist/vocabulary/preset/created.d.ts.map +1 -1
- package/dist/vocabulary/preset/created.js +2 -2
- package/dist/vocabulary/preset/created.js.map +1 -1
- package/dist/vocabulary/preset/updated.d.ts +2 -2
- package/dist/vocabulary/preset/updated.d.ts.map +1 -1
- package/dist/vocabulary/preset/updated.js +2 -2
- package/dist/vocabulary/preset/updated.js.map +1 -1
- package/dist/vocabulary/primitive/bool.d.ts +2 -5
- package/dist/vocabulary/primitive/bool.d.ts.map +1 -1
- package/dist/vocabulary/primitive/bool.js +1 -5
- package/dist/vocabulary/primitive/bool.js.map +1 -1
- package/dist/vocabulary/primitive/date.d.ts +2 -3
- package/dist/vocabulary/primitive/date.d.ts.map +1 -1
- package/dist/vocabulary/primitive/date.js +2 -3
- package/dist/vocabulary/primitive/date.js.map +1 -1
- package/dist/vocabulary/primitive/json.d.ts +3 -3
- package/dist/vocabulary/primitive/json.d.ts.map +1 -1
- package/dist/vocabulary/primitive/json.js +11 -11
- package/dist/vocabulary/primitive/json.js.map +1 -1
- package/dist/vocabulary/primitive/list.d.ts +6 -5
- package/dist/vocabulary/primitive/list.d.ts.map +1 -1
- package/dist/vocabulary/primitive/list.js +13 -7
- package/dist/vocabulary/primitive/list.js.map +1 -1
- package/dist/vocabulary/primitive/many.d.ts +2 -4
- package/dist/vocabulary/primitive/many.d.ts.map +1 -1
- package/dist/vocabulary/primitive/many.js +2 -4
- package/dist/vocabulary/primitive/many.js.map +1 -1
- package/dist/vocabulary/primitive/number.d.ts +2 -4
- package/dist/vocabulary/primitive/number.d.ts.map +1 -1
- package/dist/vocabulary/primitive/number.js +1 -3
- package/dist/vocabulary/primitive/number.js.map +1 -1
- package/dist/vocabulary/primitive/oneOf.d.ts +4 -7
- package/dist/vocabulary/primitive/oneOf.d.ts.map +1 -1
- package/dist/vocabulary/primitive/oneOf.js +19 -11
- package/dist/vocabulary/primitive/oneOf.js.map +1 -1
- package/dist/vocabulary/primitive/primary.d.ts +2 -2
- package/dist/vocabulary/primitive/primary.d.ts.map +1 -1
- package/dist/vocabulary/primitive/primary.js +2 -3
- package/dist/vocabulary/primitive/primary.js.map +1 -1
- package/dist/vocabulary/primitive/ref.d.ts +2 -6
- package/dist/vocabulary/primitive/ref.d.ts.map +1 -1
- package/dist/vocabulary/primitive/ref.js +1 -1
- package/dist/vocabulary/primitive/ref.js.map +1 -1
- package/dist/vocabulary/primitive/text.d.ts +2 -4
- package/dist/vocabulary/primitive/text.d.ts.map +1 -1
- package/dist/vocabulary/primitive/text.js +1 -3
- package/dist/vocabulary/primitive/text.js.map +1 -1
- package/dist/vocabulary/rule/nullable.d.ts +0 -1
- package/dist/vocabulary/rule/nullable.d.ts.map +1 -1
- package/dist/vocabulary/rule/nullable.js +0 -1
- package/dist/vocabulary/rule/nullable.js.map +1 -1
- package/dist/vocabulary/rule/optional.d.ts +0 -1
- package/dist/vocabulary/rule/optional.d.ts.map +1 -1
- package/dist/vocabulary/rule/optional.js +0 -1
- package/dist/vocabulary/rule/optional.js.map +1 -1
- package/dist/vocabulary/rule/readOnly.d.ts +0 -2
- package/dist/vocabulary/rule/readOnly.d.ts.map +1 -1
- package/dist/vocabulary/rule/readOnly.js +0 -2
- package/dist/vocabulary/rule/readOnly.js.map +1 -1
- package/dist/vocabulary/rule/writeOnly.d.ts +0 -2
- package/dist/vocabulary/rule/writeOnly.d.ts.map +1 -1
- package/dist/vocabulary/rule/writeOnly.js +0 -2
- package/dist/vocabulary/rule/writeOnly.js.map +1 -1
- package/dist/vocabulary/vocabulary.d.ts +2 -3
- package/dist/vocabulary/vocabulary.d.ts.map +1 -1
- package/dist/vocabulary/vocabulary.js +18 -20
- package/dist/vocabulary/vocabulary.js.map +1 -1
- package/package.json +1 -1
- package/src/FougereFieldAxes.ts +2 -0
- package/src/Schema.ts +11 -8
- package/src/SchemaConstraints.ts +40 -22
- package/src/SchemaDefinition.ts +7 -5
- package/src/SchemaError.ts +9 -3
- package/src/SchemaView.ts +3 -2
- package/src/axis/Axes.ts +34 -0
- package/src/axis/Axis.ts +15 -19
- package/src/axis/boundary/Boundary.ts +39 -13
- package/src/axis/boundary/Decoder.ts +3 -1
- package/src/axis/lifecycle/Lifecycle.ts +42 -14
- package/src/axis/lifecycle/apply.ts +12 -6
- package/src/axis/role/Role.ts +73 -25
- package/src/axis/shape/Shape.ts +89 -23
- package/src/axis/shape/ShapeFormat.ts +37 -0
- package/src/axis/shape/{Formats.ts → StringFormats.ts} +2 -2
- package/src/entity/EntityDeclarations.ts +3 -2
- package/src/entity/FieldGroups.ts +9 -0
- package/src/field/Field.ts +89 -16
- package/src/field/FieldFormat.ts +18 -0
- package/src/field/FieldSet.ts +27 -19
- package/src/index.ts +7 -3
- package/src/lib/Format.ts +172 -0
- package/src/lib/JsonSchema.ts +1 -0
- package/src/lib/Registry.ts +14 -6
- package/src/lib/UnionToIntersection.ts +10 -0
- package/src/lib/ValidationResult.ts +8 -0
- package/src/lib/utils.ts +5 -1
- package/src/projection/Cases.ts +25 -8
- package/src/projection/Visibility.ts +31 -6
- package/src/projection/card/Bundle.ts +2 -0
- package/src/projection/card/Card.ts +29 -27
- package/src/projection/card/CardForm.ts +8 -0
- package/src/projection/card/CardForms.ts +13 -0
- package/src/projection/card/Change.ts +2 -2
- package/src/projection/card/Diff.ts +6 -2
- package/src/projection/card/FieldExtension.ts +5 -2
- package/src/projection/card/RoleDescriptor.ts +54 -3
- package/src/projection/card/ShapeKeywords.ts +1 -1
- package/src/projection/card/admission.ts +0 -33
- package/src/validator/FieldDeclarationValidator.ts +10 -25
- package/src/validator/FieldValueValidator.ts +13 -36
- package/src/validator/InputValidator.ts +17 -12
- package/src/validator/JsonSchemaValidator.ts +142 -0
- package/src/vocabulary/preset/created.ts +3 -3
- package/src/vocabulary/preset/updated.ts +4 -3
- package/src/vocabulary/primitive/bool.ts +3 -8
- package/src/vocabulary/primitive/date.ts +5 -4
- package/src/vocabulary/primitive/json.ts +27 -12
- package/src/vocabulary/primitive/list.ts +16 -9
- package/src/vocabulary/primitive/many.ts +3 -4
- package/src/vocabulary/primitive/number.ts +3 -8
- package/src/vocabulary/primitive/oneOf.ts +40 -24
- package/src/vocabulary/primitive/primary.ts +9 -5
- package/src/vocabulary/primitive/ref.ts +3 -7
- package/src/vocabulary/primitive/text.ts +3 -8
- package/src/vocabulary/rule/nullable.ts +0 -1
- package/src/vocabulary/rule/optional.ts +0 -1
- package/src/vocabulary/rule/readOnly.ts +0 -2
- package/src/vocabulary/rule/writeOnly.ts +0 -2
- package/src/vocabulary/vocabulary.ts +19 -21
- package/dist/axis/boundary/BoundaryAxis.d.ts +0 -4
- package/dist/axis/boundary/BoundaryAxis.d.ts.map +0 -1
- package/dist/axis/boundary/BoundaryAxis.js +0 -30
- package/dist/axis/boundary/BoundaryAxis.js.map +0 -1
- package/dist/axis/boundary/BoundaryRef.d.ts +0 -3
- package/dist/axis/boundary/BoundaryRef.d.ts.map +0 -1
- package/dist/axis/boundary/BoundaryRef.js +0 -2
- package/dist/axis/boundary/BoundaryRef.js.map +0 -1
- package/dist/axis/boundary/BoundaryRules.d.ts +0 -9
- package/dist/axis/boundary/BoundaryRules.d.ts.map +0 -1
- package/dist/axis/boundary/BoundaryRules.js +0 -2
- package/dist/axis/boundary/BoundaryRules.js.map +0 -1
- package/dist/axis/lifecycle/Clock.d.ts +0 -10
- package/dist/axis/lifecycle/Clock.d.ts.map +0 -1
- package/dist/axis/lifecycle/Clock.js +0 -19
- package/dist/axis/lifecycle/Clock.js.map +0 -1
- package/dist/axis/lifecycle/LifecycleAxis.d.ts +0 -4
- package/dist/axis/lifecycle/LifecycleAxis.d.ts.map +0 -1
- package/dist/axis/lifecycle/LifecycleAxis.js +0 -52
- package/dist/axis/lifecycle/LifecycleAxis.js.map +0 -1
- package/dist/axis/lifecycle/LifecycleRules.d.ts +0 -12
- package/dist/axis/lifecycle/LifecycleRules.d.ts.map +0 -1
- package/dist/axis/lifecycle/LifecycleRules.js +0 -3
- package/dist/axis/lifecycle/LifecycleRules.js.map +0 -1
- package/dist/axis/role/RoleAxis.d.ts +0 -5
- package/dist/axis/role/RoleAxis.d.ts.map +0 -1
- package/dist/axis/role/RoleAxis.js +0 -93
- package/dist/axis/role/RoleAxis.js.map +0 -1
- package/dist/axis/role/RoleRules.d.ts +0 -8
- package/dist/axis/role/RoleRules.d.ts.map +0 -1
- package/dist/axis/role/RoleRules.js +0 -2
- package/dist/axis/role/RoleRules.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/entity/CompositeUnique.d.ts +0 -4
- package/dist/entity/CompositeUnique.d.ts.map +0 -1
- package/dist/entity/CompositeUnique.js +0 -2
- package/dist/entity/CompositeUnique.js.map +0 -1
- package/dist/field/Meta.d.ts +0 -4
- package/dist/field/Meta.d.ts.map +0 -1
- package/dist/field/Meta.js +0 -2
- package/dist/field/Meta.js.map +0 -1
- package/dist/projection/card/RelationDescriptor.d.ts +0 -5
- package/dist/projection/card/RelationDescriptor.d.ts.map +0 -1
- package/dist/projection/card/RelationDescriptor.js +0 -2
- package/dist/projection/card/RelationDescriptor.js.map +0 -1
- package/dist/validator/AdapterFieldValidator.d.ts +0 -14
- package/dist/validator/AdapterFieldValidator.d.ts.map +0 -1
- package/dist/validator/AdapterFieldValidator.js +0 -37
- package/dist/validator/AdapterFieldValidator.js.map +0 -1
- package/src/axis/boundary/BoundaryAxis.ts +0 -32
- package/src/axis/boundary/BoundaryRef.ts +0 -3
- package/src/axis/boundary/BoundaryRules.ts +0 -4
- package/src/axis/lifecycle/Clock.ts +0 -22
- package/src/axis/lifecycle/LifecycleAxis.ts +0 -55
- package/src/axis/lifecycle/LifecycleRules.ts +0 -9
- package/src/axis/role/RoleAxis.ts +0 -104
- package/src/axis/role/RoleRules.ts +0 -8
- package/src/entity/CompositeUnique.ts +0 -6
- package/src/field/Meta.ts +0 -3
- package/src/projection/card/RelationDescriptor.ts +0 -3
- package/src/validator/AdapterFieldValidator.ts +0 -41
package/src/SchemaDefinition.ts
CHANGED
|
@@ -113,7 +113,7 @@ export class SchemaDefinition {
|
|
|
113
113
|
...addressed,
|
|
114
114
|
...Object.keys(declarations.previous ?? {}),
|
|
115
115
|
]);
|
|
116
|
-
const declared = FieldSet.declaring(this.fields, declarations
|
|
116
|
+
const declared = FieldSet.declaring(this.fields, declarations);
|
|
117
117
|
|
|
118
118
|
return this.restated({
|
|
119
119
|
fields: declared.fields,
|
|
@@ -123,9 +123,9 @@ export class SchemaDefinition {
|
|
|
123
123
|
]),
|
|
124
124
|
previous: declarations.previous ?? this.previous,
|
|
125
125
|
constraints:
|
|
126
|
-
declarations.unique === undefined
|
|
126
|
+
declarations.unique === undefined && declarations.index === undefined
|
|
127
127
|
? this.constraints
|
|
128
|
-
: SchemaConstraints.of(declared
|
|
128
|
+
: SchemaConstraints.of(declared),
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
131
|
|
|
@@ -199,11 +199,13 @@ export class SchemaDefinition {
|
|
|
199
199
|
static merged(views: readonly SchemaView[]): SchemaDefinition {
|
|
200
200
|
const fields: Fields = {};
|
|
201
201
|
let opts: ValidateOptions = {};
|
|
202
|
-
const groups: (readonly string[])[]
|
|
202
|
+
const groups: { unique: (readonly string[])[]; index: (readonly string[])[] } =
|
|
203
|
+
{ unique: [], index: [] };
|
|
203
204
|
for (const view of views) {
|
|
204
205
|
Object.assign(fields, view.getFields());
|
|
205
206
|
opts = { ...opts, ...view.getOpts() };
|
|
206
|
-
groups.push(...(view.getUnique() ?? []));
|
|
207
|
+
groups.unique.push(...(view.getUnique() ?? []));
|
|
208
|
+
groups.index.push(...(view.getIndex() ?? []));
|
|
207
209
|
}
|
|
208
210
|
|
|
209
211
|
return SchemaDefinition.derived({
|
package/src/SchemaError.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
export class SchemaError extends Error {
|
|
2
|
-
constructor(message: string) {
|
|
3
|
-
super(
|
|
2
|
+
constructor(message: string, options?: { received: unknown }) {
|
|
3
|
+
super(
|
|
4
|
+
options ? `${message} — got ${SchemaError.inspect(options.received)}` : message,
|
|
5
|
+
);
|
|
4
6
|
|
|
5
|
-
this.name =
|
|
7
|
+
this.name = 'SchemaError';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
static inspect(value: unknown): string {
|
|
11
|
+
return JSON.stringify(value) ?? typeof value;
|
|
6
12
|
}
|
|
7
13
|
}
|
package/src/SchemaView.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Fields } from './field/Fields.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { FieldGroups } from './entity/FieldGroups.js';
|
|
3
3
|
import type { PreviousNames } from './entity/PreviousNames.js';
|
|
4
4
|
import type { EntityAdapters } from './entity/EntityAdapters.js';
|
|
5
5
|
import type { ValidationResult } from './lib/ValidationResult.js';
|
|
@@ -17,7 +17,8 @@ export interface SchemaView<TFields extends Fields = Fields> {
|
|
|
17
17
|
readonly anchored?: boolean;
|
|
18
18
|
getFields(): TFields;
|
|
19
19
|
getAdapters(): EntityAdapters<TFields>;
|
|
20
|
-
getUnique():
|
|
20
|
+
getUnique(): FieldGroups<TFields> | undefined;
|
|
21
|
+
getIndex(): FieldGroups<TFields> | undefined;
|
|
21
22
|
getOpts(): ValidateOptions;
|
|
22
23
|
validate(input: unknown): ValidationResult<Values<TFields>>;
|
|
23
24
|
}
|
package/src/axis/Axes.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Registry } from '../lib/Registry.js';
|
|
2
|
+
import type { JsonSchema } from '../lib/JsonSchema.js';
|
|
3
|
+
import { fieldFormat } from '../field/FieldFormat.js';
|
|
4
|
+
import type { Axis } from './Axis.js';
|
|
5
|
+
import { Boundary } from './boundary/Boundary.js';
|
|
6
|
+
import { Lifecycle } from './lifecycle/Lifecycle.js';
|
|
7
|
+
import { Role } from './role/Role.js';
|
|
8
|
+
|
|
9
|
+
class AxisRegistry extends Registry<Axis> {
|
|
10
|
+
private composed?: JsonSchema;
|
|
11
|
+
|
|
12
|
+
register(name: string, axis: Axis): Axis {
|
|
13
|
+
this.composed = undefined;
|
|
14
|
+
|
|
15
|
+
return super.register(name, axis);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** The document a field declaration is judged against, rebuilt the next time one arrives. */
|
|
19
|
+
get fieldFormat(): JsonSchema {
|
|
20
|
+
this.composed ??= fieldFormat(this.entries);
|
|
21
|
+
|
|
22
|
+
return this.composed;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The axes this process reads, and the door an axis declared elsewhere comes through.
|
|
28
|
+
* `Axes.register('tenancy', Tenancy)` — from a `vocabulary/` file, read before `entities/`
|
|
29
|
+
*/
|
|
30
|
+
export const Axes = new AxisRegistry('axis', 'call Axes.register(name, axis)', [
|
|
31
|
+
['role', Role],
|
|
32
|
+
['lifecycle', Lifecycle],
|
|
33
|
+
['boundary', Boundary],
|
|
34
|
+
]);
|
package/src/axis/Axis.ts
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { boundaryAxis } from './boundary/BoundaryAxis.js';
|
|
1
|
+
import type { Format } from '../lib/Format.js';
|
|
2
|
+
import type { Field } from '../field/Field.js';
|
|
4
3
|
import type { ValidationError } from '../lib/ValidationError.js';
|
|
5
|
-
import type { Resolver } from './Resolver.js';
|
|
6
4
|
|
|
7
|
-
export interface Axis
|
|
8
|
-
readonly
|
|
5
|
+
export interface Axis {
|
|
6
|
+
readonly format: Format;
|
|
9
7
|
|
|
10
|
-
|
|
8
|
+
/**
|
|
9
|
+
* What a format cannot state: `role.relation.to` is a function, and JSON holds none.
|
|
10
|
+
* The whole declaration comes with the name, because a contradiction is a PAIR — a
|
|
11
|
+
* primary key that admits null states one legal `role` beside one legal `shape`.
|
|
12
|
+
*/
|
|
13
|
+
refusals?(value: unknown, declaration: Record<string, unknown>): ValidationError[];
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Whether this axis alone lets the field be absent from what a caller sends. Asked of every
|
|
17
|
+
* REGISTERED axis, so a fourth one weighs on it without the validator naming it.
|
|
18
|
+
*/
|
|
19
|
+
admitsAbsence?(field: Field): boolean;
|
|
15
20
|
}
|
|
16
|
-
|
|
17
|
-
export const EXTENSION_AXES: readonly Axis[] = [
|
|
18
|
-
roleAxis,
|
|
19
|
-
lifecycleAxis,
|
|
20
|
-
boundaryAxis,
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
/** The slots they occupy: the keys of `x-fougere` on a field descriptor. */
|
|
24
|
-
export const EXTENSION_SLOTS = EXTENSION_AXES.map((axis) => axis.slot);
|
|
@@ -4,25 +4,37 @@ import { Boundaries } from './Decoder.js';
|
|
|
4
4
|
import type { Field } from '../../field/Field.js';
|
|
5
5
|
import { type Shape } from '../shape/Shape.js';
|
|
6
6
|
import { Shapes } from '../shape/Shape.js';
|
|
7
|
-
import type { BoundaryRules } from './BoundaryRules.js';
|
|
8
7
|
import { SchemaError } from '../../SchemaError.js';
|
|
8
|
+
import { Format, type Accepted } from '../../lib/Format.js';
|
|
9
|
+
|
|
10
|
+
const closedOr = <Verb extends 'decode' | 'encode'>(verb: Verb) =>
|
|
11
|
+
Format.either(Format.tokens(['closed']), Format.of().key(verb, Format.text).needs(verb).closed());
|
|
12
|
+
|
|
13
|
+
const RULES = Format.of().key('in', closedOr('decode')).key('out', closedOr('encode')).closed();
|
|
14
|
+
|
|
15
|
+
const BOUNDARY = Format.named(
|
|
16
|
+
'axis/boundary',
|
|
17
|
+
Format.either(Format.text.as<'isoDate' | (string & {})>(), RULES),
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export type BoundaryRules = Accepted<typeof RULES>;
|
|
21
|
+
|
|
22
|
+
export type BoundaryRef = Accepted<typeof BOUNDARY>;
|
|
9
23
|
|
|
10
24
|
const identityDecoder: Decoder = (value) => ({ value });
|
|
11
25
|
|
|
12
26
|
const identityEncoder: Encoder = (value) => value;
|
|
13
27
|
|
|
14
28
|
export class Boundary {
|
|
15
|
-
|
|
16
|
-
|
|
29
|
+
static readonly format = BOUNDARY;
|
|
30
|
+
|
|
17
31
|
readonly decode: Decoder;
|
|
18
32
|
readonly encode: Encoder;
|
|
19
33
|
|
|
20
34
|
private constructor(
|
|
21
|
-
rules: BoundaryRules = {},
|
|
35
|
+
private readonly rules: BoundaryRules = {},
|
|
22
36
|
codecs?: { decode: Decoder; encode: Encoder },
|
|
23
37
|
) {
|
|
24
|
-
this.in = rules.in;
|
|
25
|
-
this.out = rules.out;
|
|
26
38
|
this.decode = codecs?.decode ?? identityDecoder;
|
|
27
39
|
this.encode = codecs?.encode ?? identityEncoder;
|
|
28
40
|
}
|
|
@@ -35,16 +47,23 @@ export class Boundary {
|
|
|
35
47
|
|
|
36
48
|
const alias = Boundaries.aliases.find(ref);
|
|
37
49
|
if (!alias) throw new SchemaError(`Unknown boundary alias: '${ref}'`);
|
|
50
|
+
|
|
38
51
|
return new Boundary(alias);
|
|
39
52
|
}
|
|
40
53
|
|
|
54
|
+
/** The server fills it, so a caller never sends it. */
|
|
55
|
+
static admitsAbsence(field: Field): boolean {
|
|
56
|
+
return this.of(field).readOnly();
|
|
57
|
+
}
|
|
58
|
+
|
|
41
59
|
static of(field: Field): Boundary {
|
|
42
60
|
const declared = Boundary.declared(field);
|
|
43
61
|
const derived = Boundary.forShape(field.shape);
|
|
44
62
|
const rules: BoundaryRules = {
|
|
45
|
-
in: declared.in ?? derived.in,
|
|
46
|
-
out: declared.out ?? derived.out,
|
|
63
|
+
in: declared.rules.in ?? derived.rules.in,
|
|
64
|
+
out: declared.rules.out ?? derived.rules.out,
|
|
47
65
|
};
|
|
66
|
+
|
|
48
67
|
return new Boundary(rules, {
|
|
49
68
|
decode:
|
|
50
69
|
typeof rules.in === 'object'
|
|
@@ -60,19 +79,26 @@ export class Boundary {
|
|
|
60
79
|
/** `date-time` means a `Date` on both sides, without a word in the entity. */
|
|
61
80
|
static forShape(shape: Shape | undefined): Boundary {
|
|
62
81
|
if (Shapes.typeOf(shape) === 'date') return new Boundary(Boundaries.aliases.resolve('isoDate'));
|
|
82
|
+
|
|
63
83
|
return new Boundary();
|
|
64
84
|
}
|
|
65
85
|
|
|
66
86
|
/** The dual of `declared`: what `readOnly()` writes back on the field, not a judge. */
|
|
67
87
|
declaring(overrides: BoundaryRules): BoundaryRules {
|
|
68
|
-
return { in: overrides.in ?? this.in, out: overrides.out ?? this.out };
|
|
88
|
+
return { in: overrides.in ?? this.rules.in, out: overrides.out ?? this.rules.out };
|
|
69
89
|
}
|
|
70
90
|
|
|
71
|
-
|
|
72
|
-
return this.in === 'closed';
|
|
91
|
+
readOnly(): boolean {
|
|
92
|
+
return this.rules.in === 'closed';
|
|
73
93
|
}
|
|
74
94
|
|
|
75
|
-
|
|
76
|
-
return this.out === 'closed';
|
|
95
|
+
writeOnly(): boolean {
|
|
96
|
+
return this.rules.out === 'closed';
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
declare module '../../FougereFieldAxes.js' {
|
|
101
|
+
interface FougereFieldAxes {
|
|
102
|
+
readonly boundary?: BoundaryRef;
|
|
77
103
|
}
|
|
78
104
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BoundaryRules } from './
|
|
1
|
+
import type { BoundaryRules } from './Boundary.js';
|
|
2
2
|
import { Registry } from '../../lib/Registry.js';
|
|
3
3
|
import type { Encoder } from './Encoder.js';
|
|
4
4
|
import type { Verdict } from '../../lib/Verdict.js';
|
|
@@ -33,8 +33,10 @@ Boundaries.decoders.register('isoDate', (value) => {
|
|
|
33
33
|
if (value instanceof Date) return { value };
|
|
34
34
|
if (typeof value === 'string') {
|
|
35
35
|
const date = new Date(value);
|
|
36
|
+
|
|
36
37
|
return Number.isNaN(date.getTime()) ? { message: 'Invalid date' } : { value: date };
|
|
37
38
|
}
|
|
39
|
+
|
|
38
40
|
return { message: 'Expected a date' };
|
|
39
41
|
});
|
|
40
42
|
Boundaries.encoders.register('isoDate', (value) =>
|
|
@@ -1,19 +1,45 @@
|
|
|
1
|
+
import { Format, type Accepted } from '../../lib/Format.js';
|
|
1
2
|
import { Generators } from './Generators.js';
|
|
2
|
-
import type {
|
|
3
|
+
import type { GeneratorRef } from './Generators.js';
|
|
3
4
|
|
|
5
|
+
export type LifecycleRules = Accepted<typeof Lifecycle.format>;
|
|
4
6
|
export class Lifecycle {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
static readonly CREATE = ['now', 'optional'] as const;
|
|
8
|
+
static readonly UPDATE = ['now', 'forbidden'] as const;
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
static readonly format = Format.of('axis/lifecycle')
|
|
11
|
+
.key(
|
|
12
|
+
'create',
|
|
13
|
+
Format.either(
|
|
14
|
+
Format.tokens(Lifecycle.CREATE),
|
|
15
|
+
Format.exactlyOne({
|
|
16
|
+
value: Format.anything,
|
|
17
|
+
generate: Format.text.as<GeneratorRef>(),
|
|
18
|
+
}),
|
|
19
|
+
),
|
|
20
|
+
)
|
|
21
|
+
.key('update', Format.tokens(Lifecycle.UPDATE))
|
|
22
|
+
.closed();
|
|
23
|
+
|
|
24
|
+
private constructor(private readonly rules: LifecycleRules = {}) {}
|
|
25
|
+
|
|
26
|
+
/** `optional()`, a default, a generator: the rule says the value need not arrive. */
|
|
27
|
+
static admitsAbsence(field: { lifecycle?: LifecycleRules }): boolean {
|
|
28
|
+
return !this.of(field).requiredAtCreate();
|
|
11
29
|
}
|
|
12
30
|
|
|
13
31
|
static of(field: { lifecycle?: LifecycleRules }): Lifecycle {
|
|
14
32
|
return new Lifecycle(field.lifecycle);
|
|
15
33
|
}
|
|
16
34
|
|
|
35
|
+
private get create() {
|
|
36
|
+
return this.rules.create;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private get update() {
|
|
40
|
+
return this.rules.update;
|
|
41
|
+
}
|
|
42
|
+
|
|
17
43
|
bornWith(instant: number): { value: unknown } | undefined {
|
|
18
44
|
const rule = this.create;
|
|
19
45
|
|
|
@@ -26,23 +52,19 @@ export class Lifecycle {
|
|
|
26
52
|
return { value: Generators.resolve(rule.generate)() };
|
|
27
53
|
}
|
|
28
54
|
|
|
29
|
-
|
|
55
|
+
requiredAtCreate(): boolean {
|
|
30
56
|
return this.create === undefined;
|
|
31
57
|
}
|
|
32
58
|
|
|
33
|
-
|
|
59
|
+
stampedAtCreate(): boolean {
|
|
34
60
|
return this.create === 'now';
|
|
35
61
|
}
|
|
36
62
|
|
|
37
|
-
|
|
38
|
-
return this.stampedAtCreate && !this.stampedOnUpdate;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
get immutable(): boolean {
|
|
63
|
+
immutable(): boolean {
|
|
42
64
|
return this.update === 'forbidden';
|
|
43
65
|
}
|
|
44
66
|
|
|
45
|
-
|
|
67
|
+
stampedOnUpdate(): boolean {
|
|
46
68
|
return this.update === 'now';
|
|
47
69
|
}
|
|
48
70
|
|
|
@@ -54,3 +76,9 @@ export class Lifecycle {
|
|
|
54
76
|
: undefined;
|
|
55
77
|
}
|
|
56
78
|
}
|
|
79
|
+
|
|
80
|
+
declare module '../../FougereFieldAxes.js' {
|
|
81
|
+
interface FougereFieldAxes {
|
|
82
|
+
readonly lifecycle?: LifecycleRules;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Lifecycle } from './Lifecycle.js';
|
|
2
|
-
import { Clock } from './Clock.js';
|
|
3
2
|
import { type Field } from '../../field/Field.js';
|
|
4
3
|
import { type Fields } from '../../field/Fields.js';
|
|
5
4
|
|
|
@@ -8,12 +7,16 @@ import { type Fields } from '../../field/Fields.js';
|
|
|
8
7
|
* FR : remplit ce que la déclaration laisse au storage : aucun handler n'estampe lui-même.
|
|
9
8
|
* `applyCreate({ id: primary(), createdAt: created() }, { title: 'a' })` → `id`, `createdAt`
|
|
10
9
|
*/
|
|
11
|
-
export function applyCreate(
|
|
10
|
+
export function applyCreate(
|
|
11
|
+
fields: Fields,
|
|
12
|
+
input: Record<string, unknown>,
|
|
13
|
+
): Record<string, unknown> {
|
|
12
14
|
const values: Record<string, unknown> = { ...input };
|
|
13
|
-
const instant =
|
|
15
|
+
const instant = Date.now();
|
|
14
16
|
|
|
15
17
|
for (const [name, field] of Object.entries(fields) as [string, Field][]) {
|
|
16
18
|
if (name in values) continue;
|
|
19
|
+
|
|
17
20
|
const born = Lifecycle.of(field).bornWith(instant);
|
|
18
21
|
|
|
19
22
|
if (born) values[name] = born.value;
|
|
@@ -28,12 +31,15 @@ export function applyCreate(fields: Fields, input: Record<string, unknown>): Rec
|
|
|
28
31
|
* sont touchés.
|
|
29
32
|
* `applyUpdate(fields, { title: 'b' })` → `updatedAt` added, nothing else
|
|
30
33
|
*/
|
|
31
|
-
export function applyUpdate(
|
|
34
|
+
export function applyUpdate(
|
|
35
|
+
fields: Fields,
|
|
36
|
+
patch: Record<string, unknown>,
|
|
37
|
+
): Record<string, unknown> {
|
|
32
38
|
const values: Record<string, unknown> = { ...patch };
|
|
33
|
-
const instant =
|
|
39
|
+
const instant = Date.now();
|
|
34
40
|
|
|
35
41
|
for (const [name, field] of Object.entries(fields) as [string, Field][]) {
|
|
36
|
-
if (Lifecycle.of(field).stampedOnUpdate && !(name in values))
|
|
42
|
+
if (Lifecycle.of(field).stampedOnUpdate() && !(name in values))
|
|
37
43
|
values[name] = new Date(instant);
|
|
38
44
|
}
|
|
39
45
|
|
package/src/axis/role/Role.ts
CHANGED
|
@@ -1,56 +1,104 @@
|
|
|
1
|
-
import type { EntityConstructor } from './EntityConstructor.js';
|
|
2
1
|
import type { Relation } from './Relation.js';
|
|
3
|
-
import type {
|
|
2
|
+
import type { EntityConstructor } from './EntityConstructor.js';
|
|
3
|
+
import { isObject } from '../../lib/utils.js';
|
|
4
|
+
import { Shapes, type Shape } from '../shape/Shape.js';
|
|
5
|
+
import type { ValidationError } from '../../lib/ValidationError.js';
|
|
6
|
+
import { Format, type Accepted } from '../../lib/Format.js';
|
|
7
|
+
import { ON_DELETE, RELATION_KINDS } from './Relation.js';
|
|
4
8
|
|
|
5
9
|
export class Role {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
static readonly format = Format.of('axis/role')
|
|
11
|
+
.key('primary', Format.flag)
|
|
12
|
+
.key('index', Format.flag)
|
|
13
|
+
.key('unique', Format.flag)
|
|
14
|
+
.key(
|
|
15
|
+
'relation',
|
|
16
|
+
Format.of()
|
|
17
|
+
.key('to', Format.anything.as<() => EntityConstructor>())
|
|
18
|
+
.key('kind', Format.tokens(RELATION_KINDS))
|
|
19
|
+
.key('onDelete', Format.tokens(ON_DELETE))
|
|
20
|
+
.needs('to', 'kind')
|
|
21
|
+
.closed(),
|
|
22
|
+
)
|
|
23
|
+
.closed();
|
|
24
|
+
|
|
25
|
+
static refusals(value: unknown, declaration: Record<string, unknown> = {}): ValidationError[] {
|
|
26
|
+
const role = Role.of({ role: isObject(value) ? (value as RoleRules) : undefined });
|
|
27
|
+
const errors: ValidationError[] = [];
|
|
28
|
+
const relation = isObject(value) ? value.relation : undefined;
|
|
29
|
+
|
|
30
|
+
if (isObject(relation) && 'to' in relation && typeof relation.to !== 'function')
|
|
31
|
+
errors.push({
|
|
32
|
+
path: ['role', 'relation', 'to'],
|
|
33
|
+
message: 'Expected a function returning the target entity, such as () => Post',
|
|
34
|
+
});
|
|
10
35
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
36
|
+
if (role.isPrimary() && Shapes.isNullable(declaration.shape as Shape))
|
|
37
|
+
errors.push({
|
|
38
|
+
path: ['role', 'primary'],
|
|
39
|
+
message: 'A primary key admits no null — a row is addressed by it',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (role.isCollection() && (role.isUnique() || role.isIndexed()))
|
|
43
|
+
errors.push({
|
|
44
|
+
path: ['role', role.isUnique() ? 'unique' : 'index'],
|
|
45
|
+
message: 'A collection has no column of its own, so there is nothing to index',
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return errors;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private constructor(private readonly rules: RoleRules = {}) {}
|
|
52
|
+
|
|
53
|
+
/** A collection has no column: the far side of the relation carries the key. */
|
|
54
|
+
static admitsAbsence(field: { role?: RoleRules }): boolean {
|
|
55
|
+
return this.of(field).isCollection();
|
|
16
56
|
}
|
|
17
57
|
|
|
18
58
|
static of(field: { role?: RoleRules }): Role {
|
|
19
59
|
return new Role(field.role);
|
|
20
60
|
}
|
|
21
61
|
|
|
22
|
-
|
|
23
|
-
return this.primary === true;
|
|
62
|
+
isPrimary(): boolean {
|
|
63
|
+
return this.rules.primary === true;
|
|
24
64
|
}
|
|
25
65
|
|
|
26
|
-
|
|
27
|
-
return this.index === true;
|
|
66
|
+
isIndexed(): boolean {
|
|
67
|
+
return this.rules.index === true;
|
|
28
68
|
}
|
|
29
69
|
|
|
30
70
|
/** A field unique on its own. A group spanning several belongs to the schema. */
|
|
31
|
-
|
|
32
|
-
return this.unique === true;
|
|
71
|
+
isUnique(): boolean {
|
|
72
|
+
return this.rules.unique === true;
|
|
33
73
|
}
|
|
34
74
|
|
|
35
|
-
|
|
36
|
-
return this.relation?.kind === 'many';
|
|
75
|
+
isCollection(): boolean {
|
|
76
|
+
return this.rules.relation?.kind === 'many';
|
|
37
77
|
}
|
|
38
78
|
|
|
39
|
-
|
|
40
|
-
return this.relation?.kind === 'one';
|
|
79
|
+
isReference(): boolean {
|
|
80
|
+
return this.rules.relation?.kind === 'one';
|
|
41
81
|
}
|
|
42
82
|
|
|
43
83
|
/** Either kind — what a CLI flag and a GraphQL selection both leave out. */
|
|
44
|
-
|
|
45
|
-
return this.relation !== undefined;
|
|
84
|
+
isRelation(): boolean {
|
|
85
|
+
return this.rules.relation !== undefined;
|
|
46
86
|
}
|
|
47
87
|
|
|
48
88
|
/** Calls `() => Post` so no caller has to. */
|
|
49
89
|
get target(): EntityConstructor | undefined {
|
|
50
|
-
return this.relation?.to();
|
|
90
|
+
return this.rules.relation?.to();
|
|
51
91
|
}
|
|
52
92
|
|
|
53
93
|
get onDelete(): Relation['onDelete'] {
|
|
54
|
-
return this.relation?.onDelete;
|
|
94
|
+
return this.rules.relation?.onDelete;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export type RoleRules = Accepted<typeof Role.format>;
|
|
99
|
+
|
|
100
|
+
declare module '../../FougereFieldAxes.js' {
|
|
101
|
+
interface FougereFieldAxes {
|
|
102
|
+
readonly role?: RoleRules;
|
|
55
103
|
}
|
|
56
104
|
}
|