@fougere/schema 0.3.0-alpha.0 → 0.4.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/README.md +1 -1
- package/dist/EntityAdapters.d.ts +26 -0
- package/dist/EntityAdapters.d.ts.map +1 -0
- package/dist/EntityAdapters.js +71 -0
- package/dist/EntityAdapters.js.map +1 -0
- package/dist/EntityDeclarations.d.ts +7 -14
- package/dist/EntityDeclarations.d.ts.map +1 -1
- package/dist/EntityDeclarations.js +1 -18
- package/dist/EntityDeclarations.js.map +1 -1
- package/dist/axis/Axis.d.ts +2 -0
- package/dist/axis/Axis.d.ts.map +1 -1
- package/dist/axis/Axis.js +5 -3
- package/dist/axis/Axis.js.map +1 -1
- package/dist/axis/boundary/Boundary.d.ts +1 -1
- package/dist/axis/boundary/Boundary.d.ts.map +1 -1
- package/dist/axis/boundary/{axis.d.ts → BoundaryAxis.d.ts} +1 -1
- package/dist/axis/boundary/BoundaryAxis.d.ts.map +1 -0
- package/dist/axis/boundary/{axis.js → BoundaryAxis.js} +3 -2
- package/dist/axis/boundary/BoundaryAxis.js.map +1 -0
- package/dist/axis/lifecycle/Clock.d.ts +18 -0
- package/dist/axis/lifecycle/Clock.d.ts.map +1 -0
- package/dist/axis/lifecycle/Clock.js +25 -0
- package/dist/axis/lifecycle/Clock.js.map +1 -0
- package/dist/axis/lifecycle/Generators.d.ts +16 -2
- package/dist/axis/lifecycle/Generators.d.ts.map +1 -1
- package/dist/axis/lifecycle/Generators.js +35 -5
- package/dist/axis/lifecycle/Generators.js.map +1 -1
- package/dist/axis/lifecycle/{axis.d.ts → LifecycleAxis.d.ts} +1 -1
- package/dist/axis/lifecycle/LifecycleAxis.d.ts.map +1 -0
- package/dist/axis/lifecycle/{axis.js → LifecycleAxis.js} +3 -2
- package/dist/axis/lifecycle/LifecycleAxis.js.map +1 -0
- package/dist/axis/lifecycle/apply.d.ts +1 -3
- package/dist/axis/lifecycle/apply.d.ts.map +1 -1
- package/dist/axis/lifecycle/apply.js +5 -43
- package/dist/axis/lifecycle/apply.js.map +1 -1
- package/dist/axis/role/Relation.d.ts +11 -1
- package/dist/axis/role/Relation.d.ts.map +1 -1
- package/dist/axis/role/Relation.js +18 -3
- package/dist/axis/role/Relation.js.map +1 -1
- package/dist/axis/role/Role.d.ts +5 -17
- package/dist/axis/role/Role.d.ts.map +1 -1
- package/dist/axis/role/Role.js +9 -19
- package/dist/axis/role/Role.js.map +1 -1
- package/dist/axis/role/{axis.d.ts → RoleAxis.d.ts} +1 -1
- package/dist/axis/role/RoleAxis.d.ts.map +1 -0
- package/dist/axis/role/{axis.js → RoleAxis.js} +5 -4
- package/dist/axis/role/RoleAxis.js.map +1 -0
- package/dist/card/Bundle.d.ts +15 -0
- package/dist/card/Bundle.d.ts.map +1 -0
- package/dist/card/Bundle.js +67 -0
- package/dist/card/Bundle.js.map +1 -0
- package/dist/card/Card.d.ts +27 -0
- package/dist/card/Card.d.ts.map +1 -0
- package/dist/card/Card.js +230 -0
- package/dist/card/Card.js.map +1 -0
- package/dist/card/EntityTypeSource.d.ts +12 -0
- package/dist/card/EntityTypeSource.d.ts.map +1 -0
- package/dist/card/{typescript.js → EntityTypeSource.js} +20 -35
- package/dist/card/EntityTypeSource.js.map +1 -0
- package/dist/card/FacadeTypeSource.d.ts +19 -0
- package/dist/card/FacadeTypeSource.d.ts.map +1 -0
- package/dist/card/FacadeTypeSource.js +40 -0
- package/dist/card/FacadeTypeSource.js.map +1 -0
- package/dist/{judge/form.d.ts → card/admission.d.ts} +2 -4
- package/dist/card/admission.d.ts.map +1 -0
- package/dist/{judge/form.js → card/admission.js} +1 -3
- package/dist/card/admission.js.map +1 -0
- package/dist/card/diff.d.ts +11 -55
- package/dist/card/diff.d.ts.map +1 -1
- package/dist/card/diff.js +1 -122
- package/dist/card/diff.js.map +1 -1
- package/dist/constraint/FieldGroup.d.ts +2 -2
- package/dist/constraint/FieldGroup.d.ts.map +1 -1
- package/dist/constraint/FieldGroup.js.map +1 -1
- package/dist/entity.d.ts +3 -3
- package/dist/entity.d.ts.map +1 -1
- package/dist/entity.js +8 -13
- package/dist/entity.js.map +1 -1
- package/dist/fields/Field.d.ts +24 -0
- package/dist/fields/Field.d.ts.map +1 -0
- package/dist/{Field.js → fields/Field.js} +17 -15
- package/dist/fields/Field.js.map +1 -0
- package/dist/fields/FieldSet.d.ts +28 -0
- package/dist/fields/FieldSet.d.ts.map +1 -0
- package/dist/fields/FieldSet.js +55 -0
- package/dist/fields/FieldSet.js.map +1 -0
- package/dist/index.d.ts +23 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -17
- package/dist/index.js.map +1 -1
- package/dist/judge/{cases.d.ts → Cases.d.ts} +22 -22
- package/dist/judge/Cases.d.ts.map +1 -0
- package/dist/judge/{cases.js → Cases.js} +35 -27
- package/dist/judge/Cases.js.map +1 -0
- package/dist/judge/FieldJudge.d.ts +9 -0
- package/dist/judge/FieldJudge.d.ts.map +1 -0
- package/dist/judge/FieldJudge.js +54 -0
- package/dist/judge/FieldJudge.js.map +1 -0
- package/dist/judge/RowJudge.d.ts +12 -0
- package/dist/judge/RowJudge.d.ts.map +1 -0
- package/dist/judge/RowJudge.js +81 -0
- package/dist/judge/RowJudge.js.map +1 -0
- package/dist/judge/RowRefusal.d.ts +17 -0
- package/dist/judge/RowRefusal.d.ts.map +1 -0
- package/dist/judge/RowRefusal.js +16 -0
- package/dist/judge/RowRefusal.js.map +1 -0
- package/dist/judge/ValueForm.d.ts +3 -0
- package/dist/judge/ValueForm.d.ts.map +1 -0
- package/dist/judge/ValueForm.js +3 -0
- package/dist/judge/ValueForm.js.map +1 -0
- package/dist/judge/ValueJudge.d.ts +12 -0
- package/dist/judge/ValueJudge.d.ts.map +1 -0
- package/dist/judge/ValueJudge.js +60 -0
- package/dist/judge/ValueJudge.js.map +1 -0
- package/dist/projection/SchemaOrCard.d.ts +7 -0
- package/dist/projection/SchemaOrCard.d.ts.map +1 -0
- package/dist/projection/{source.js → SchemaOrCard.js} +3 -3
- package/dist/projection/SchemaOrCard.js.map +1 -0
- package/dist/projection/Visibility.d.ts +10 -0
- package/dist/projection/Visibility.d.ts.map +1 -0
- package/dist/projection/Visibility.js +55 -0
- package/dist/projection/Visibility.js.map +1 -0
- package/dist/projection/standard.d.ts +2 -2
- package/dist/projection/standard.d.ts.map +1 -1
- package/dist/{Schema.d.ts → schema/Schema.d.ts} +30 -34
- package/dist/schema/Schema.d.ts.map +1 -0
- package/dist/{Schema.js → schema/Schema.js} +25 -48
- package/dist/schema/Schema.js.map +1 -0
- package/dist/schema/SchemaDefinition.d.ts +46 -0
- package/dist/schema/SchemaDefinition.d.ts.map +1 -0
- package/dist/schema/SchemaDefinition.js +64 -0
- package/dist/schema/SchemaDefinition.js.map +1 -0
- package/dist/schema/SchemaDerivation.d.ts +28 -0
- package/dist/schema/SchemaDerivation.d.ts.map +1 -0
- package/dist/schema/SchemaDerivation.js +37 -0
- package/dist/schema/SchemaDerivation.js.map +1 -0
- package/dist/schema/SchemaView.d.ts +23 -0
- package/dist/schema/SchemaView.d.ts.map +1 -0
- package/dist/{SchemaView.js.map → schema/SchemaView.js.map} +1 -1
- package/dist/utils.d.ts +4 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +13 -0
- package/dist/utils.js.map +1 -0
- package/dist/vocabulary/bool.d.ts +1 -1
- package/dist/vocabulary/bool.d.ts.map +1 -1
- package/dist/vocabulary/bool.js +1 -1
- package/dist/vocabulary/bool.js.map +1 -1
- package/dist/vocabulary/created.d.ts +1 -1
- package/dist/vocabulary/created.d.ts.map +1 -1
- package/dist/vocabulary/date.d.ts +1 -1
- package/dist/vocabulary/date.d.ts.map +1 -1
- package/dist/vocabulary/date.js +1 -1
- package/dist/vocabulary/date.js.map +1 -1
- package/dist/vocabulary/email.d.ts +1 -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/indexed.d.ts +1 -1
- package/dist/vocabulary/indexed.d.ts.map +1 -1
- package/dist/vocabulary/json.d.ts +2 -2
- package/dist/vocabulary/json.d.ts.map +1 -1
- package/dist/vocabulary/json.js +6 -4
- 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 +1 -1
- package/dist/vocabulary/many.d.ts.map +1 -1
- package/dist/vocabulary/many.js +3 -3
- 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/number.d.ts +1 -1
- package/dist/vocabulary/number.d.ts.map +1 -1
- package/dist/vocabulary/number.js +1 -1
- package/dist/vocabulary/number.js.map +1 -1
- package/dist/vocabulary/oneOf.d.ts +1 -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/primary.d.ts +1 -1
- package/dist/vocabulary/primary.d.ts.map +1 -1
- package/dist/vocabulary/primary.js +4 -5
- 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/ref.d.ts +1 -1
- package/dist/vocabulary/ref.d.ts.map +1 -1
- package/dist/vocabulary/ref.js +3 -9
- package/dist/vocabulary/ref.js.map +1 -1
- package/dist/vocabulary/text.d.ts +1 -1
- package/dist/vocabulary/text.d.ts.map +1 -1
- package/dist/vocabulary/text.js +1 -1
- package/dist/vocabulary/text.js.map +1 -1
- package/dist/vocabulary/unique.d.ts +1 -1
- package/dist/vocabulary/unique.d.ts.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 +2 -3
- package/dist/vocabulary/vocabulary.d.ts.map +1 -1
- package/dist/vocabulary/vocabulary.js +4 -4
- 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/package.json +8 -4
- package/src/EntityAdapters.ts +95 -0
- package/src/EntityDeclarations.ts +19 -0
- package/src/axis/Axis.ts +25 -0
- package/src/axis/Meta.ts +3 -0
- package/src/axis/boundary/Boundaries.ts +44 -0
- package/src/axis/boundary/Boundary.ts +69 -0
- package/src/axis/boundary/BoundaryAxis.ts +32 -0
- package/src/axis/lifecycle/Clock.ts +26 -0
- package/src/axis/lifecycle/Generators.ts +46 -0
- package/src/axis/lifecycle/Lifecycle.ts +53 -0
- package/src/axis/lifecycle/LifecycleAxis.ts +49 -0
- package/src/axis/lifecycle/apply.ts +38 -0
- package/src/axis/role/Relation.ts +31 -0
- package/src/axis/role/Role.ts +56 -0
- package/src/axis/role/RoleAxis.ts +115 -0
- package/src/axis/shape/Formats.ts +22 -0
- package/src/axis/shape/Shape.ts +91 -0
- package/src/card/Bundle.ts +80 -0
- package/src/card/Card.ts +256 -0
- package/src/card/Descriptor.ts +68 -0
- package/src/card/EntityTypeSource.ts +90 -0
- package/src/card/FacadeTypeSource.ts +55 -0
- package/src/card/admission.ts +25 -0
- package/src/card/diff.ts +56 -0
- package/src/constraint/FieldGroup.ts +91 -0
- package/src/constraint/Unique.ts +3 -0
- package/src/entity.ts +15 -0
- package/src/fields/Field.ts +80 -0
- package/src/fields/FieldSet.ts +62 -0
- package/src/index.ts +64 -0
- package/src/judge/Cases.ts +139 -0
- package/src/judge/FieldJudge.ts +61 -0
- package/src/judge/RowJudge.ts +84 -0
- package/src/judge/RowRefusal.ts +17 -0
- package/src/judge/ValueForm.ts +7 -0
- package/src/judge/ValueJudge.ts +72 -0
- package/src/judge/options.ts +3 -0
- package/src/judge/result.ts +10 -0
- package/src/projection/SchemaOrCard.ts +18 -0
- package/src/projection/Visibility.ts +47 -0
- package/src/projection/standard.ts +47 -0
- package/src/schema/Schema.ts +167 -0
- package/src/schema/SchemaDefinition.ts +87 -0
- package/src/schema/SchemaDerivation.ts +46 -0
- package/src/schema/SchemaView.ts +25 -0
- package/src/utils.ts +13 -0
- package/src/vocabulary/bool.ts +9 -0
- package/src/vocabulary/created.ts +8 -0
- package/src/vocabulary/date.ts +5 -0
- package/src/vocabulary/email.ts +6 -0
- package/src/vocabulary/immutable.ts +6 -0
- package/src/vocabulary/indexed.ts +4 -0
- package/src/vocabulary/json.ts +22 -0
- package/src/vocabulary/list.ts +13 -0
- package/src/vocabulary/many.ts +9 -0
- package/src/vocabulary/nullable.ts +7 -0
- package/src/vocabulary/number.ts +17 -0
- package/src/vocabulary/oneOf.ts +24 -0
- package/src/vocabulary/optional.ts +8 -0
- package/src/vocabulary/primary.ts +33 -0
- package/src/vocabulary/readOnly.ts +7 -0
- package/src/vocabulary/ref.ts +13 -0
- package/src/vocabulary/text.ts +19 -0
- package/src/vocabulary/unique.ts +10 -0
- package/src/vocabulary/updated.ts +7 -0
- package/src/vocabulary/url.ts +6 -0
- package/src/vocabulary/vocabulary.ts +40 -0
- package/src/vocabulary/writeOnly.ts +7 -0
- package/dist/Field.d.ts +0 -21
- package/dist/Field.d.ts.map +0 -1
- package/dist/Field.js.map +0 -1
- package/dist/Schema.d.ts.map +0 -1
- package/dist/Schema.js.map +0 -1
- package/dist/SchemaView.d.ts +0 -18
- package/dist/SchemaView.d.ts.map +0 -1
- package/dist/axis/boundary/axis.d.ts.map +0 -1
- package/dist/axis/boundary/axis.js.map +0 -1
- package/dist/axis/lifecycle/axis.d.ts.map +0 -1
- package/dist/axis/lifecycle/axis.js.map +0 -1
- package/dist/axis/role/axis.d.ts.map +0 -1
- package/dist/axis/role/axis.js.map +0 -1
- package/dist/card/describe.d.ts +0 -12
- package/dist/card/describe.d.ts.map +0 -1
- package/dist/card/describe.js +0 -83
- package/dist/card/describe.js.map +0 -1
- package/dist/card/reconstruct.d.ts +0 -11
- package/dist/card/reconstruct.d.ts.map +0 -1
- package/dist/card/reconstruct.js +0 -83
- package/dist/card/reconstruct.js.map +0 -1
- package/dist/card/typescript.d.ts +0 -17
- package/dist/card/typescript.d.ts.map +0 -1
- package/dist/card/typescript.js.map +0 -1
- package/dist/clean.d.ts +0 -2
- package/dist/clean.d.ts.map +0 -1
- package/dist/clean.js +0 -7
- package/dist/clean.js.map +0 -1
- package/dist/judge/Judge.d.ts +0 -14
- package/dist/judge/Judge.d.ts.map +0 -1
- package/dist/judge/Judge.js +0 -161
- package/dist/judge/Judge.js.map +0 -1
- package/dist/judge/cases.d.ts.map +0 -1
- package/dist/judge/cases.js.map +0 -1
- package/dist/judge/form.d.ts.map +0 -1
- package/dist/judge/form.js.map +0 -1
- package/dist/name.d.ts +0 -3
- package/dist/name.d.ts.map +0 -1
- package/dist/name.js +0 -7
- package/dist/name.js.map +0 -1
- package/dist/projection/encode.d.ts +0 -3
- package/dist/projection/encode.d.ts.map +0 -1
- package/dist/projection/encode.js +0 -19
- package/dist/projection/encode.js.map +0 -1
- package/dist/projection/io.d.ts +0 -4
- package/dist/projection/io.d.ts.map +0 -1
- package/dist/projection/io.js +0 -29
- package/dist/projection/io.js.map +0 -1
- package/dist/projection/source.d.ts +0 -7
- package/dist/projection/source.d.ts.map +0 -1
- package/dist/projection/source.js.map +0 -1
- package/dist/same.d.ts +0 -6
- package/dist/same.d.ts.map +0 -1
- package/dist/same.js +0 -35
- package/dist/same.js.map +0 -1
- /package/dist/{SchemaView.js → schema/SchemaView.js} +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { upperFirst } from '../utils.js';
|
|
2
|
+
import type { FieldDescriptor, SchemaDescriptor } from './Descriptor.js';
|
|
3
|
+
|
|
4
|
+
function typeOf(field: FieldDescriptor): string {
|
|
5
|
+
const types = Array.isArray(field.type) ? field.type : field.type ? [field.type] : [];
|
|
6
|
+
const nullable = types.includes('null');
|
|
7
|
+
const base = types.find((t) => t !== 'null');
|
|
8
|
+
const inner = baseTypeOf(base, field);
|
|
9
|
+
return nullable ? `${inner} | null` : inner;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function baseTypeOf(base: string | undefined, field: FieldDescriptor): string {
|
|
13
|
+
if (field.enum?.length) {
|
|
14
|
+
return field.enum.map((v) => (v === null ? 'null' : JSON.stringify(v))).join(' | ');
|
|
15
|
+
}
|
|
16
|
+
switch (base) {
|
|
17
|
+
case 'string':
|
|
18
|
+
return field.format === 'date-time' ? 'Date' : 'string';
|
|
19
|
+
case 'number':
|
|
20
|
+
case 'integer':
|
|
21
|
+
return 'number';
|
|
22
|
+
case 'boolean':
|
|
23
|
+
return 'boolean';
|
|
24
|
+
case 'array':
|
|
25
|
+
return field.items ? `${typeOf(field.items)}[]` : 'string[]';
|
|
26
|
+
case 'object':
|
|
27
|
+
return field.properties ? objectTypeOf(field.properties, field.required ?? []) : 'Record<string, unknown>';
|
|
28
|
+
default:
|
|
29
|
+
return 'unknown';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function objectTypeOf(properties: Record<string, FieldDescriptor>, required: readonly string[]): string {
|
|
34
|
+
const members = Object.entries(properties).map(([name, field]) => {
|
|
35
|
+
const optional = required.includes(name) ? '' : '?';
|
|
36
|
+
return `${propertyKey(name)}${optional}: ${typeOf(field)}`;
|
|
37
|
+
});
|
|
38
|
+
return `{ ${members.join('; ')} }`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function propertyKey(name: string): string {
|
|
42
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function docCommentOf(text: string | undefined, indent: string): string {
|
|
46
|
+
if (!text) return '';
|
|
47
|
+
return `${indent}/** ${text.replace(/\*\//g, '*\\/')} */\n`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface EntityTypeSourceOptions {
|
|
51
|
+
name?: string;
|
|
52
|
+
exported?: boolean;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function shapeTypeOf(descriptor: SchemaDescriptor, indent = ''): string {
|
|
56
|
+
const entries = Object.entries(descriptor.properties ?? {});
|
|
57
|
+
if (entries.length === 0) return '{}';
|
|
58
|
+
|
|
59
|
+
const lines = entries.map(([key, field]) => {
|
|
60
|
+
const doc = docCommentOf(field.description, `${indent} `);
|
|
61
|
+
return `${doc}${indent} ${propertyKey(key)}: ${typeOf(field)};`;
|
|
62
|
+
});
|
|
63
|
+
return `{\n${lines.join('\n')}\n${indent}}`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export class EntityTypeSource {
|
|
67
|
+
private constructor(private readonly descriptor: SchemaDescriptor) {}
|
|
68
|
+
|
|
69
|
+
static of(descriptor: SchemaDescriptor): EntityTypeSource {
|
|
70
|
+
return new EntityTypeSource(descriptor);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
render(options: EntityTypeSourceOptions = {}): string {
|
|
74
|
+
const name = identifierOf(options.name ?? upperFirst(this.descriptor.title ?? 'Schema'));
|
|
75
|
+
const exported = options.exported === false ? '' : 'export ';
|
|
76
|
+
const card = JSON.stringify(this.descriptor, null, 2)
|
|
77
|
+
.split('\n')
|
|
78
|
+
.map((line, i) => (i === 0 ? line : ` ${line}`))
|
|
79
|
+
.join('\n');
|
|
80
|
+
|
|
81
|
+
return `${exported}class ${name} extends Card.fromDescriptor<${shapeTypeOf(this.descriptor)}>(${card}).toSchema() {}`;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function identifierOf(name: string): string {
|
|
86
|
+
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name)) {
|
|
87
|
+
throw new Error(`'${name}' is not a TypeScript identifier — it cannot name a generated declaration`);
|
|
88
|
+
}
|
|
89
|
+
return name;
|
|
90
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { SchemaDescriptor } from './Descriptor.js';
|
|
2
|
+
|
|
3
|
+
export interface FacadeTypeSourceOptions {
|
|
4
|
+
name?: string;
|
|
5
|
+
exported?: boolean;
|
|
6
|
+
rowType?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface OpDescriptor {
|
|
10
|
+
name: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
output?: SchemaDescriptor;
|
|
13
|
+
cardinality?: 'one' | 'maybe' | 'many' | 'page' | 'none';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function propertyKey(name: string): string {
|
|
17
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function docCommentOf(text: string | undefined, indent: string): string {
|
|
21
|
+
if (!text) return '';
|
|
22
|
+
return `${indent}/** ${text.replace(/\*\//g, '*\\/')} */\n`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function returnTypeOf(op: OpDescriptor, rowType: string): string {
|
|
26
|
+
switch (op.cardinality) {
|
|
27
|
+
case 'many': return `${rowType}[]`;
|
|
28
|
+
case 'page': return `${rowType}[] & { total?: number; endCursor?: string; hasMore?: boolean }`;
|
|
29
|
+
case 'maybe': return `${rowType} | undefined`;
|
|
30
|
+
case 'one': return rowType;
|
|
31
|
+
case 'none': return 'unknown';
|
|
32
|
+
default: return 'unknown';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class FacadeTypeSource {
|
|
37
|
+
private constructor(private readonly operations: readonly OpDescriptor[]) {}
|
|
38
|
+
|
|
39
|
+
static of(operations: readonly OpDescriptor[]): FacadeTypeSource {
|
|
40
|
+
return new FacadeTypeSource(operations);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
render(options: FacadeTypeSourceOptions = {}): string {
|
|
44
|
+
const name = options.name ?? 'Facade';
|
|
45
|
+
const exported = options.exported === false ? '' : 'export ';
|
|
46
|
+
const rowType = options.rowType ?? 'unknown';
|
|
47
|
+
const members = this.operations.map((operation) => {
|
|
48
|
+
const doc = docCommentOf(operation.description, ' ');
|
|
49
|
+
return `${doc} ${propertyKey(operation.name)}(invocation?: Invocation): Promise<${returnTypeOf(operation, rowType)}>;`;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
if (members.length === 0) return `${exported}interface ${name} {}`;
|
|
53
|
+
return `${exported}interface ${name} {\n${members.join('\n')}\n}`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ValidationError } from '../judge/result.js';
|
|
2
|
+
|
|
3
|
+
/** A card is refused by naming what is wrong AND the remedy — never by a bare throw. */
|
|
4
|
+
export function refuse(what: string, fix: string): never {
|
|
5
|
+
throw new Error(`This card cannot be read: ${what}.\n ${fix}`);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A wire value admitted by the axis's OWN judge — legal only where its declared and wire
|
|
10
|
+
* forms are the same value, which `describe: v => v` states.
|
|
11
|
+
*/
|
|
12
|
+
export function admitWire(
|
|
13
|
+
judge: (value: unknown, errors: ValidationError[]) => void,
|
|
14
|
+
value: unknown,
|
|
15
|
+
slot: string,
|
|
16
|
+
): void {
|
|
17
|
+
const errors: ValidationError[] = [];
|
|
18
|
+
judge(value, errors);
|
|
19
|
+
if (errors.length) {
|
|
20
|
+
refuse(
|
|
21
|
+
`${slot} is malformed — ${errors.map((e) => `${e.path}: ${e.message}`).join('; ')}`,
|
|
22
|
+
'A card states an axis the way a declaration does.',
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
}
|
package/src/card/diff.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { BoundaryRef } from '../axis/boundary/Boundary.js';
|
|
2
|
+
import type { LifecycleRules } from '../axis/lifecycle/Lifecycle.js';
|
|
3
|
+
import type { FieldDescriptor, RoleDescriptor } from './Descriptor.js';
|
|
4
|
+
|
|
5
|
+
/** One named difference, at one place. Each kind exists because a reader asks for it. */
|
|
6
|
+
export type Change =
|
|
7
|
+
/** DDL: add the column. Codec: the old caller never sends it. Boot: refuse when required. */
|
|
8
|
+
| { kind: 'added'; field: string; to: FieldDescriptor; required: boolean }
|
|
9
|
+
/** DDL: drop the column. Codec: the old caller still sends it, and it goes nowhere. */
|
|
10
|
+
| { kind: 'removed'; field: string; from: FieldDescriptor; required: boolean }
|
|
11
|
+
/** DDL: rename the column. Codec and ORM: one more entry in the field-to-column map. */
|
|
12
|
+
| { kind: 'renamed'; from: string; to: string; field: FieldDescriptor }
|
|
13
|
+
/** DDL: alter the type. Codec: convert the value, when it can. */
|
|
14
|
+
| { kind: 'retyped'; field: string; from: TypeSet; to: TypeSet }
|
|
15
|
+
/** Same type, different bounds: a CHECK moves, and a value legal yesterday may not be. */
|
|
16
|
+
| { kind: 'reshaped'; field: string; from: FieldDescriptor; to: FieldDescriptor }
|
|
17
|
+
/** NOT NULL in either direction. Boot: an old writer cannot fill what it never knew. */
|
|
18
|
+
| { kind: 'required'; field: string; from: boolean; to: boolean }
|
|
19
|
+
/** An axis other than shape was restated. */
|
|
20
|
+
| { kind: 'restated'; field: string; axis: 'role'; from?: RoleDescriptor; to?: RoleDescriptor }
|
|
21
|
+
| { kind: 'restated'; field: string; axis: 'lifecycle'; from?: LifecycleRules; to?: LifecycleRules }
|
|
22
|
+
| { kind: 'restated'; field: string; axis: 'boundary'; from?: BoundaryRef; to?: BoundaryRef };
|
|
23
|
+
|
|
24
|
+
/** A field's declared types, always represented as a set. */
|
|
25
|
+
export type TypeSet = string[];
|
|
26
|
+
|
|
27
|
+
/** A removal and an addition that could be one rename: same shape, different name. */
|
|
28
|
+
export interface RenameCandidate {
|
|
29
|
+
removed: string;
|
|
30
|
+
added: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface Diff {
|
|
34
|
+
changes: Change[];
|
|
35
|
+
/** Questions the comparison refuses to decide without an explicit rename declaration. */
|
|
36
|
+
ambiguous: RenameCandidate[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface DiffOptions {
|
|
40
|
+
/** Renames as declared at the time: old name to new name. */
|
|
41
|
+
renamed?: Record<string, string>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface SetDiff {
|
|
45
|
+
/** Entities the target bundle has and the source bundle had not. */
|
|
46
|
+
entitiesAdded: string[];
|
|
47
|
+
/** Entities the source bundle had and the target bundle has not. */
|
|
48
|
+
entitiesRemoved: string[];
|
|
49
|
+
/** Differences for entities present in both bundles; unchanged entities are absent. */
|
|
50
|
+
entities: Record<string, Diff>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface SetDiffOptions {
|
|
54
|
+
/** Declared renames, per entity: `{ post: { body: 'content' } }`. */
|
|
55
|
+
renamed?: Record<string, Record<string, string>>;
|
|
56
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { Field, Fields } from "../fields/Field.js";
|
|
2
|
+
|
|
3
|
+
export abstract class FieldGroup {
|
|
4
|
+
constructor(readonly members: readonly string[]) {}
|
|
5
|
+
|
|
6
|
+
protected withMembers(members: readonly string[]): this {
|
|
7
|
+
return new (this.constructor as new (members: readonly string[]) => this)(
|
|
8
|
+
members,
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
get isSelf(): boolean {
|
|
13
|
+
return this.members.length === 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
resolvedOn(ownKey: string): this {
|
|
17
|
+
return this.isSelf ? this.withMembers([ownKey]) : this;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
covers(key: string): boolean {
|
|
21
|
+
return this.members.includes(key);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
equals(other: FieldGroup): boolean {
|
|
25
|
+
return (
|
|
26
|
+
this.constructor === other.constructor &&
|
|
27
|
+
this.members.length === other.members.length &&
|
|
28
|
+
this.members.every((member, i) => member === other.members[i])
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
onto(fields: Fields): Fields {
|
|
33
|
+
const missing = this.members.filter((key) => !(key in fields));
|
|
34
|
+
if (missing.length)
|
|
35
|
+
throw new Error(
|
|
36
|
+
`${this.constructor.name.toLowerCase()}: [${this.members.join(", ")}] names ` +
|
|
37
|
+
`${missing.map((m) => `'${m}'`).join(", ")}, which the entity does not declare.`,
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const out: Fields = { ...fields };
|
|
41
|
+
for (const key of this.members) {
|
|
42
|
+
const field = out[key]!;
|
|
43
|
+
out[key] = field.with({
|
|
44
|
+
role: { ...field.role, rules: [...(field.role?.rules ?? []), this] },
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
rename(map: (key: string) => string | undefined): this | null {
|
|
51
|
+
if (this.isSelf) return this;
|
|
52
|
+
const carried = this.members.map(map);
|
|
53
|
+
return carried.every((key): key is string => key !== undefined)
|
|
54
|
+
? this.withMembers(carried)
|
|
55
|
+
: null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
toJSON(): string[] {
|
|
59
|
+
return [...this.members];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static normalize<R extends FieldGroup>(
|
|
63
|
+
groups: readonly (R | readonly string[])[] | undefined,
|
|
64
|
+
make: (members: readonly string[]) => R,
|
|
65
|
+
): readonly R[] | undefined {
|
|
66
|
+
if (!groups) return undefined;
|
|
67
|
+
return groups.map((group) =>
|
|
68
|
+
group instanceof FieldGroup ? (group as R) : make(group),
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static on<R extends FieldGroup>(
|
|
73
|
+
field: Field,
|
|
74
|
+
kind: Function & { prototype: R },
|
|
75
|
+
): R[] {
|
|
76
|
+
return (field.role?.rules ?? []).filter(
|
|
77
|
+
(rule): rule is R => rule instanceof kind,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
static groupsOf<R extends FieldGroup>(
|
|
82
|
+
fields: Fields,
|
|
83
|
+
kind: Function & { prototype: R },
|
|
84
|
+
): R[] {
|
|
85
|
+
const seen = new Map<string, R>();
|
|
86
|
+
for (const field of Object.values(fields))
|
|
87
|
+
for (const rule of FieldGroup.on(field, kind))
|
|
88
|
+
if (rule.members.length > 1) seen.set(rule.members.join(" "), rule);
|
|
89
|
+
return [...seen.values()];
|
|
90
|
+
}
|
|
91
|
+
}
|
package/src/entity.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Fields } from './fields/Field.js';
|
|
2
|
+
import { FieldSet } from './fields/FieldSet.js';
|
|
3
|
+
import { type EntityDeclarations } from './EntityDeclarations.js';
|
|
4
|
+
import { Schema, type SchemaConstructor } from './schema/Schema.js';
|
|
5
|
+
|
|
6
|
+
export function entity<TFields extends Fields>(
|
|
7
|
+
originalFields: TFields,
|
|
8
|
+
{ unique, adapters, previous }: EntityDeclarations<TFields> = {},
|
|
9
|
+
): SchemaConstructor<TFields> {
|
|
10
|
+
return Schema.of({
|
|
11
|
+
fields: FieldSet.declared(originalFields, unique),
|
|
12
|
+
adapters,
|
|
13
|
+
previous,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
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
|
+
|
|
10
|
+
export type Fields = Record<string, Field>;
|
|
11
|
+
|
|
12
|
+
/** A key of a field set — the name a declaration addresses a field by. */
|
|
13
|
+
export type FieldName<TFields extends Fields> = Extract<keyof TFields, string>;
|
|
14
|
+
|
|
15
|
+
/** The carrier, the three extension axes, the annotation — the five the judge reads. */
|
|
16
|
+
export type FieldDeclaration = Pick<Field, "shape" | Axis["slot"] | "meta">;
|
|
17
|
+
|
|
18
|
+
export class Field<T = unknown> {
|
|
19
|
+
readonly shape: Shape;
|
|
20
|
+
readonly role?: RoleRules;
|
|
21
|
+
readonly lifecycle?: LifecycleRules;
|
|
22
|
+
readonly boundary?: BoundaryRef;
|
|
23
|
+
readonly meta?: Meta;
|
|
24
|
+
|
|
25
|
+
declare readonly _type?: T;
|
|
26
|
+
|
|
27
|
+
constructor(init: FieldDeclaration, key?: string) {
|
|
28
|
+
const verdict = FieldJudge.of(init).verdict;
|
|
29
|
+
|
|
30
|
+
if (!verdict.success) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`${key ? `Field '${key}': ` : ""}` +
|
|
33
|
+
verdict.errors.map((e) => `${e.path}: ${e.message}`).join("; "),
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this.shape = init.shape;
|
|
38
|
+
this.role = Role.resolvedOn(init.role, key);
|
|
39
|
+
this.lifecycle = init.lifecycle;
|
|
40
|
+
this.boundary = init.boundary;
|
|
41
|
+
this.meta = init.meta;
|
|
42
|
+
|
|
43
|
+
const create = this.lifecycle?.create;
|
|
44
|
+
if (typeof create === "object" && create !== null && "value" in create) {
|
|
45
|
+
const checked = ValueJudge.of(this).check(create.value);
|
|
46
|
+
if ("error" in checked)
|
|
47
|
+
throw new Error(
|
|
48
|
+
`${key ? `Field '${key}': ` : ""}the declared default ${JSON.stringify(create.value)} ` +
|
|
49
|
+
`is not a legal value for it — ${checked.error}.`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static is(value: unknown): value is Field {
|
|
55
|
+
return FieldJudge.of(value).verdict.success;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
with<U = T>(overrides: Partial<FieldDeclaration>): Field<U> {
|
|
59
|
+
return new Field<U>({ ...this, ...overrides });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
rename(map: (key: string) => string | undefined): Field<T> {
|
|
63
|
+
const rules = this.role?.rules;
|
|
64
|
+
if (!rules?.length) return this;
|
|
65
|
+
|
|
66
|
+
const carried = rules
|
|
67
|
+
.map((group) => group.rename(map))
|
|
68
|
+
.filter((group) => group !== null);
|
|
69
|
+
const unchanged =
|
|
70
|
+
carried.length === rules.length &&
|
|
71
|
+
carried.every((group, i) => group.equals(rules[i]!));
|
|
72
|
+
if (unchanged) return this;
|
|
73
|
+
|
|
74
|
+
const { rules: _dropped, ...rest } = this.role!;
|
|
75
|
+
return this.with({
|
|
76
|
+
role: carried.length ? { ...rest, rules: carried } : rest,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Role } from '../axis/role/Role.js';
|
|
2
|
+
import { FieldGroup } from '../constraint/FieldGroup.js';
|
|
3
|
+
import { Unique } from '../constraint/Unique.js';
|
|
4
|
+
import type { CompositeUnique } from '../EntityDeclarations.js';
|
|
5
|
+
import { Field, type FieldName, type Fields } from './Field.js';
|
|
6
|
+
|
|
7
|
+
export class FieldSet<TFields extends Fields = Fields> {
|
|
8
|
+
private constructor(private readonly fields: TFields) {}
|
|
9
|
+
|
|
10
|
+
static of<TFields extends Fields>(fields: TFields): FieldSet<TFields> {
|
|
11
|
+
return new FieldSet(fields);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Every entry through the field door, then the groups declared over several of them.
|
|
16
|
+
* A group written here names its members; one written on a field named itself, and the
|
|
17
|
+
* key it sat under resolved it.
|
|
18
|
+
*/
|
|
19
|
+
static declared<TFields extends Fields>(
|
|
20
|
+
declared: TFields,
|
|
21
|
+
unique?: CompositeUnique<TFields>,
|
|
22
|
+
): TFields {
|
|
23
|
+
let fields: Fields = {};
|
|
24
|
+
for (const [key, field] of Object.entries(declared)) fields[key] = new Field(field, key);
|
|
25
|
+
for (const group of unique ?? []) fields = new Unique(group).onto(fields);
|
|
26
|
+
return fields as TFields;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The name of the field that carries `primary`, or `undefined` when none does.
|
|
31
|
+
*
|
|
32
|
+
* `Role.of(field).isPrimary` answers about ONE field; this answers about a shape, which
|
|
33
|
+
* is the question every reader actually had. It was the same three lines spelled five
|
|
34
|
+
* times — a mirror's key, a form's row identity, GraphQL's node id, the DDL's primary
|
|
35
|
+
* key and the ORM's `findById` column — so a shape with two primaries meant whichever
|
|
36
|
+
* one that loop happened to see first, five times over.
|
|
37
|
+
*
|
|
38
|
+
* The absence is answered and not defaulted: `'id'` is a fine fallback for a form and a
|
|
39
|
+
* lie for a DDL, so the caller decides.
|
|
40
|
+
*/
|
|
41
|
+
get primary(): FieldName<TFields> | undefined {
|
|
42
|
+
const primaries = Object.entries(this.fields)
|
|
43
|
+
.filter(([, field]) => Role.of(field).isPrimary)
|
|
44
|
+
.map(([name]) => name);
|
|
45
|
+
|
|
46
|
+
if (primaries.length > 1) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`FieldSet.primary: ${primaries.map((name) => JSON.stringify(name)).join(', ')} all declare ` +
|
|
49
|
+
'`primary`; a field set can have only one primary field.',
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return primaries[0] as FieldName<TFields> | undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get uniqueGroups(): CompositeUnique<TFields> | undefined {
|
|
57
|
+
const groups = FieldGroup.groupsOf(this.fields, Unique);
|
|
58
|
+
return groups.length
|
|
59
|
+
? groups.map((group) => [...group.members]) as unknown as CompositeUnique<TFields>
|
|
60
|
+
: undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
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 { type StringFormat, type FormatPredicate, Formats } from './axis/shape/Formats.js';
|
|
5
|
+
export { Role, type RoleRules } from './axis/role/Role.js';
|
|
6
|
+
export { type Relation, type EntityConstructor } from './axis/role/Relation.js';
|
|
7
|
+
export { Lifecycle, type LifecycleRules } from './axis/lifecycle/Lifecycle.js';
|
|
8
|
+
export { type GeneratorRef, Generators } from './axis/lifecycle/Generators.js';
|
|
9
|
+
export { Clock } from './axis/lifecycle/Clock.js';
|
|
10
|
+
export { Boundary, type BoundaryRules, type BoundaryRef } from './axis/boundary/Boundary.js';
|
|
11
|
+
export { type Decoder, type Encoder, Boundaries } from './axis/boundary/Boundaries.js';
|
|
12
|
+
export { type Meta } from './axis/Meta.js';
|
|
13
|
+
export { FieldGroup } from './constraint/FieldGroup.js';
|
|
14
|
+
export { Unique } from './constraint/Unique.js';
|
|
15
|
+
|
|
16
|
+
export { Schema, ANONYMOUS_SCHEMA_NAME, type SchemaConstructor } from './schema/Schema.js';
|
|
17
|
+
export { SchemaDerivation } from './schema/SchemaDerivation.js';
|
|
18
|
+
export { isObject } from './judge/ValueForm.js';
|
|
19
|
+
export { Cases, type Case } from './judge/Cases.js';
|
|
20
|
+
export { RowRefusal } from './judge/RowRefusal.js';
|
|
21
|
+
export { type SchemaView, type Row, type PartialRow } from './schema/SchemaView.js';
|
|
22
|
+
export { type FougereEntityAdapters, type EntityAdapters } from './EntityAdapters.js';
|
|
23
|
+
export { lowerFirst, upperFirst } from './utils.js';
|
|
24
|
+
|
|
25
|
+
export { primary } from './vocabulary/primary.js';
|
|
26
|
+
export { text } from './vocabulary/text.js';
|
|
27
|
+
export { email } from './vocabulary/email.js';
|
|
28
|
+
export { url } from './vocabulary/url.js';
|
|
29
|
+
export { list } from './vocabulary/list.js';
|
|
30
|
+
export { number } from './vocabulary/number.js';
|
|
31
|
+
export { bool } from './vocabulary/bool.js';
|
|
32
|
+
export { date } from './vocabulary/date.js';
|
|
33
|
+
export { created } from './vocabulary/created.js';
|
|
34
|
+
export { updated } from './vocabulary/updated.js';
|
|
35
|
+
export { oneOf } from './vocabulary/oneOf.js';
|
|
36
|
+
export { ref } from './vocabulary/ref.js';
|
|
37
|
+
export { many } from './vocabulary/many.js';
|
|
38
|
+
export { optional } from './vocabulary/optional.js';
|
|
39
|
+
export { nullable } from './vocabulary/nullable.js';
|
|
40
|
+
export { immutable } from './vocabulary/immutable.js';
|
|
41
|
+
export { unique } from './vocabulary/unique.js';
|
|
42
|
+
export { indexed } from './vocabulary/indexed.js';
|
|
43
|
+
export { readOnly } from './vocabulary/readOnly.js';
|
|
44
|
+
export { writeOnly } from './vocabulary/writeOnly.js';
|
|
45
|
+
export { json } from './vocabulary/json.js';
|
|
46
|
+
|
|
47
|
+
export { applyCreate, applyUpdate } from './axis/lifecycle/apply.js';
|
|
48
|
+
export { Visibility } from './projection/Visibility.js';
|
|
49
|
+
export { Card } from './card/Card.js';
|
|
50
|
+
export { Bundle } from './card/Bundle.js';
|
|
51
|
+
export type { Change, Diff, DiffOptions, SetDiff, SetDiffOptions, RenameCandidate, TypeSet } from './card/diff.js';
|
|
52
|
+
export { EntityTypeSource, type EntityTypeSourceOptions } from './card/EntityTypeSource.js';
|
|
53
|
+
export { FacadeTypeSource, type FacadeTypeSourceOptions, type OpDescriptor } from './card/FacadeTypeSource.js';
|
|
54
|
+
export { type SchemaBundle, type SchemaDescriptor, type FieldDescriptor, type FieldExtension, type RoleDescriptor, type RelationDescriptor } from './card/Descriptor.js';
|
|
55
|
+
export { type SchemaOrCard, schemaOf, fieldsOf } from './projection/SchemaOrCard.js';
|
|
56
|
+
export type { StandardSchemaV1 } from './projection/standard.js';
|
|
57
|
+
|
|
58
|
+
export { entity } from './entity.js';
|
|
59
|
+
|
|
60
|
+
export { FieldJudge } from './judge/FieldJudge.js';
|
|
61
|
+
export { ValueJudge } from './judge/ValueJudge.js';
|
|
62
|
+
export { RowJudge } from './judge/RowJudge.js';
|
|
63
|
+
export { type ValidateOptions } from './judge/options.js';
|
|
64
|
+
export { type ValidationError, type ValidationResult, type Checked } from './judge/result.js';
|