@metaobjectsdev/metadata 0.9.0 → 0.10.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/attr-schema-validate.d.ts +1 -1
- package/dist/attr-schema-validate.d.ts.map +1 -1
- package/dist/attr-schema-validate.js +84 -7
- package/dist/attr-schema-validate.js.map +1 -1
- package/dist/constants.d.ts +208 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +419 -0
- package/dist/constants.js.map +1 -0
- package/dist/constraint-merge.d.ts +18 -0
- package/dist/constraint-merge.d.ts.map +1 -0
- package/dist/constraint-merge.js +0 -0
- package/dist/constraint-merge.js.map +1 -0
- package/dist/constraint-validate.d.ts +6 -0
- package/dist/constraint-validate.d.ts.map +1 -0
- package/dist/constraint-validate.js +274 -0
- package/dist/constraint-validate.js.map +1 -0
- package/dist/core/attr/attr-constants.d.ts +13 -3
- package/dist/core/attr/attr-constants.d.ts.map +1 -1
- package/dist/core/attr/attr-constants.js +11 -2
- package/dist/core/attr/attr-constants.js.map +1 -1
- package/dist/core/attr/attr-definition.embedded.d.ts +3 -0
- package/dist/core/attr/attr-definition.embedded.d.ts.map +1 -0
- package/dist/core/attr/attr-definition.embedded.js +60 -0
- package/dist/core/attr/attr-definition.embedded.js.map +1 -0
- package/dist/core/documentation/doc-constants.d.ts +3 -2
- package/dist/core/documentation/doc-constants.d.ts.map +1 -1
- package/dist/core/documentation/doc-constants.js +3 -1
- package/dist/core/documentation/doc-constants.js.map +1 -1
- package/dist/core/documentation/doc-provider.d.ts.map +1 -1
- package/dist/core/documentation/doc-provider.js +6 -2
- package/dist/core/documentation/doc-provider.js.map +1 -1
- package/dist/core/documentation/doc-schema.d.ts +1 -1
- package/dist/core/documentation/doc-schema.d.ts.map +1 -1
- package/dist/core/documentation/doc-schema.js +13 -5
- package/dist/core/documentation/doc-schema.js.map +1 -1
- package/dist/core/documentation/documentation-definition.embedded.d.ts +3 -0
- package/dist/core/documentation/documentation-definition.embedded.d.ts.map +1 -0
- package/dist/core/documentation/documentation-definition.embedded.js +79 -0
- package/dist/core/documentation/documentation-definition.embedded.js.map +1 -0
- package/dist/core/field/field-constants.d.ts +7 -4
- package/dist/core/field/field-constants.d.ts.map +1 -1
- package/dist/core/field/field-constants.js +7 -7
- package/dist/core/field/field-constants.js.map +1 -1
- package/dist/core/field/field-definition.embedded.d.ts +3 -0
- package/dist/core/field/field-definition.embedded.d.ts.map +1 -0
- package/dist/core/field/field-definition.embedded.js +236 -0
- package/dist/core/field/field-definition.embedded.js.map +1 -0
- package/dist/core/field/field-schema.d.ts +0 -16
- package/dist/core/field/field-schema.d.ts.map +1 -1
- package/dist/core/field/field-schema.js +10 -158
- package/dist/core/field/field-schema.js.map +1 -1
- package/dist/core/field/meta-field.d.ts.map +1 -1
- package/dist/core/field/meta-field.js +7 -5
- package/dist/core/field/meta-field.js.map +1 -1
- package/dist/core/file-meta-data-loader.d.ts +18 -0
- package/dist/core/file-meta-data-loader.d.ts.map +1 -0
- package/dist/core/file-meta-data-loader.js +81 -0
- package/dist/core/file-meta-data-loader.js.map +1 -0
- package/dist/core/file-source.d.ts +12 -0
- package/dist/core/file-source.d.ts.map +1 -0
- package/dist/core/file-source.js +46 -0
- package/dist/core/file-source.js.map +1 -0
- package/dist/core/identity/identity-definition.embedded.d.ts +3 -0
- package/dist/core/identity/identity-definition.embedded.d.ts.map +1 -0
- package/dist/core/identity/identity-definition.embedded.js +91 -0
- package/dist/core/identity/identity-definition.embedded.js.map +1 -0
- package/dist/core/identity/identity-schema.d.ts.map +1 -1
- package/dist/core/identity/identity-schema.js +3 -2
- package/dist/core/identity/identity-schema.js.map +1 -1
- package/dist/core/identity/validate-identity-passthrough.d.ts +42 -0
- package/dist/core/identity/validate-identity-passthrough.d.ts.map +1 -0
- package/dist/core/identity/validate-identity-passthrough.js +158 -0
- package/dist/core/identity/validate-identity-passthrough.js.map +1 -0
- package/dist/core/object/object-constants.d.ts +2 -1
- package/dist/core/object/object-constants.d.ts.map +1 -1
- package/dist/core/object/object-constants.js +3 -0
- package/dist/core/object/object-constants.js.map +1 -1
- package/dist/core/object/object-definition.embedded.d.ts +3 -0
- package/dist/core/object/object-definition.embedded.d.ts.map +1 -0
- package/dist/core/object/object-definition.embedded.js +110 -0
- package/dist/core/object/object-definition.embedded.js.map +1 -0
- package/dist/core/object/validate-discriminator.d.ts.map +1 -1
- package/dist/core/object/validate-discriminator.js +1 -3
- package/dist/core/object/validate-discriminator.js.map +1 -1
- package/dist/core/query/query-constants.d.ts.map +1 -1
- package/dist/core/query/query-constants.js +5 -3
- package/dist/core/query/query-constants.js.map +1 -1
- package/dist/core/relationship/derive-m2m-fields.d.ts +26 -0
- package/dist/core/relationship/derive-m2m-fields.d.ts.map +1 -0
- package/dist/core/relationship/derive-m2m-fields.js +102 -0
- package/dist/core/relationship/derive-m2m-fields.js.map +1 -0
- package/dist/core/relationship/meta-relationship.d.ts +6 -4
- package/dist/core/relationship/meta-relationship.d.ts.map +1 -1
- package/dist/core/relationship/meta-relationship.js +12 -8
- package/dist/core/relationship/meta-relationship.js.map +1 -1
- package/dist/core/relationship/relationship-constants.d.ts +6 -2
- package/dist/core/relationship/relationship-constants.d.ts.map +1 -1
- package/dist/core/relationship/relationship-constants.js +6 -2
- package/dist/core/relationship/relationship-constants.js.map +1 -1
- package/dist/core/relationship/relationship-definition.embedded.d.ts +3 -0
- package/dist/core/relationship/relationship-definition.embedded.d.ts.map +1 -0
- package/dist/core/relationship/relationship-definition.embedded.js +310 -0
- package/dist/core/relationship/relationship-definition.embedded.js.map +1 -0
- package/dist/core/relationship/relationship-schema.d.ts.map +1 -1
- package/dist/core/relationship/relationship-schema.js +13 -7
- package/dist/core/relationship/relationship-schema.js.map +1 -1
- package/dist/core/validator/validator-definition.embedded.d.ts +3 -0
- package/dist/core/validator/validator-definition.embedded.d.ts.map +1 -0
- package/dist/core/validator/validator-definition.embedded.js +134 -0
- package/dist/core/validator/validator-definition.embedded.js.map +1 -0
- package/dist/core/yaml-desugar.d.ts.map +1 -1
- package/dist/core/yaml-desugar.js +88 -10
- package/dist/core/yaml-desugar.js.map +1 -1
- package/dist/core-attr-schemas.d.ts +22 -0
- package/dist/core-attr-schemas.d.ts.map +1 -0
- package/dist/core-attr-schemas.js +324 -0
- package/dist/core-attr-schemas.js.map +1 -0
- package/dist/core-types.d.ts +5 -2
- package/dist/core-types.d.ts.map +1 -1
- package/dist/core-types.js +261 -115
- package/dist/core-types.js.map +1 -1
- package/dist/db/db-attr-schemas.d.ts +8 -0
- package/dist/db/db-attr-schemas.d.ts.map +1 -0
- package/dist/db/db-attr-schemas.js +26 -0
- package/dist/db/db-attr-schemas.js.map +1 -0
- package/dist/db/db-provider.d.ts +3 -0
- package/dist/db/db-provider.d.ts.map +1 -0
- package/dist/db/db-provider.js +28 -0
- package/dist/db/db-provider.js.map +1 -0
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +78 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +17 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -1
- package/dist/index.js.map +1 -1
- package/dist/library/embedded-library.generated.d.ts +2 -0
- package/dist/library/embedded-library.generated.d.ts.map +1 -0
- package/dist/library/embedded-library.generated.js +11 -0
- package/dist/library/embedded-library.generated.js.map +1 -0
- package/dist/library/library-sources.d.ts +12 -0
- package/dist/library/library-sources.d.ts.map +1 -0
- package/dist/library/library-sources.js +88 -0
- package/dist/library/library-sources.js.map +1 -0
- package/dist/loader/meta-data-loader.d.ts +10 -2
- package/dist/loader/meta-data-loader.d.ts.map +1 -1
- package/dist/loader/meta-data-loader.js +47 -6
- package/dist/loader/meta-data-loader.js.map +1 -1
- package/dist/loader/shortcuts.d.ts +2 -5
- package/dist/loader/shortcuts.d.ts.map +1 -1
- package/dist/loader/shortcuts.js.map +1 -1
- package/dist/loader/validation-passes.d.ts +3 -0
- package/dist/loader/validation-passes.d.ts.map +1 -1
- package/dist/loader/validation-passes.js +513 -33
- package/dist/loader/validation-passes.js.map +1 -1
- package/dist/meta/find-reference.d.ts +22 -0
- package/dist/meta/find-reference.d.ts.map +1 -0
- package/dist/meta/find-reference.js +29 -0
- package/dist/meta/find-reference.js.map +1 -0
- package/dist/meta/meta-attr.d.ts +8 -0
- package/dist/meta/meta-attr.d.ts.map +1 -0
- package/dist/meta/meta-attr.js +17 -0
- package/dist/meta/meta-attr.js.map +1 -0
- package/dist/meta/meta-data.d.ts +107 -0
- package/dist/meta/meta-data.d.ts.map +1 -0
- package/dist/meta/meta-data.js +302 -0
- package/dist/meta/meta-data.js.map +1 -0
- package/dist/meta/meta-field.d.ts +48 -0
- package/dist/meta/meta-field.d.ts.map +1 -0
- package/dist/meta/meta-field.js +94 -0
- package/dist/meta/meta-field.js.map +1 -0
- package/dist/meta/meta-identity.d.ts +71 -0
- package/dist/meta/meta-identity.d.ts.map +1 -0
- package/dist/meta/meta-identity.js +129 -0
- package/dist/meta/meta-identity.js.map +1 -0
- package/dist/meta/meta-layout.d.ts +23 -0
- package/dist/meta/meta-layout.d.ts.map +1 -0
- package/dist/meta/meta-layout.js +45 -0
- package/dist/meta/meta-layout.js.map +1 -0
- package/dist/meta/meta-object.d.ts +40 -0
- package/dist/meta/meta-object.d.ts.map +1 -0
- package/dist/meta/meta-object.js +81 -0
- package/dist/meta/meta-object.js.map +1 -0
- package/dist/meta/meta-origin.d.ts +32 -0
- package/dist/meta/meta-origin.d.ts.map +1 -0
- package/dist/meta/meta-origin.js +55 -0
- package/dist/meta/meta-origin.js.map +1 -0
- package/dist/meta/meta-relationship.d.ts +11 -0
- package/dist/meta/meta-relationship.d.ts.map +1 -0
- package/dist/meta/meta-relationship.js +27 -0
- package/dist/meta/meta-relationship.js.map +1 -0
- package/dist/meta/meta-root.d.ts +12 -0
- package/dist/meta/meta-root.d.ts.map +1 -0
- package/dist/meta/meta-root.js +24 -0
- package/dist/meta/meta-root.js.map +1 -0
- package/dist/meta/meta-source.d.ts +18 -0
- package/dist/meta/meta-source.d.ts.map +1 -0
- package/dist/meta/meta-source.js +31 -0
- package/dist/meta/meta-source.js.map +1 -0
- package/dist/meta/meta-validator.d.ts +29 -0
- package/dist/meta/meta-validator.d.ts.map +1 -0
- package/dist/meta/meta-validator.js +49 -0
- package/dist/meta/meta-validator.js.map +1 -0
- package/dist/meta/meta-view.d.ts +4 -0
- package/dist/meta/meta-view.d.ts.map +1 -0
- package/dist/meta/meta-view.js +8 -0
- package/dist/meta/meta-view.js.map +1 -0
- package/dist/metamodel-docs/index.d.ts +19 -0
- package/dist/metamodel-docs/index.d.ts.map +1 -0
- package/dist/metamodel-docs/index.js +37 -0
- package/dist/metamodel-docs/index.js.map +1 -0
- package/dist/metamodel-docs/provenance.d.ts +42 -0
- package/dist/metamodel-docs/provenance.d.ts.map +1 -0
- package/dist/metamodel-docs/provenance.js +148 -0
- package/dist/metamodel-docs/provenance.js.map +1 -0
- package/dist/metamodel-docs/provider-definitions.d.ts +8 -0
- package/dist/metamodel-docs/provider-definitions.d.ts.map +1 -0
- package/dist/metamodel-docs/provider-definitions.js +48 -0
- package/dist/metamodel-docs/provider-definitions.js.map +1 -0
- package/dist/metamodel-docs/render.d.ts +12 -0
- package/dist/metamodel-docs/render.d.ts.map +1 -0
- package/dist/metamodel-docs/render.js +252 -0
- package/dist/metamodel-docs/render.js.map +1 -0
- package/dist/naming-refs.d.ts +41 -0
- package/dist/naming-refs.d.ts.map +1 -0
- package/dist/naming-refs.js +144 -0
- package/dist/naming-refs.js.map +1 -0
- package/dist/naming.d.ts.map +1 -1
- package/dist/naming.js +10 -2
- package/dist/naming.js.map +1 -1
- package/dist/parser-core.d.ts.map +1 -1
- package/dist/parser-core.js +74 -8
- package/dist/parser-core.js.map +1 -1
- package/dist/persistence/db/db-attr-schemas.d.ts +8 -0
- package/dist/persistence/db/db-attr-schemas.d.ts.map +1 -0
- package/dist/persistence/db/db-attr-schemas.js +28 -0
- package/dist/persistence/db/db-attr-schemas.js.map +1 -0
- package/dist/persistence/db/db-definition.embedded.d.ts +3 -0
- package/dist/persistence/db/db-definition.embedded.d.ts.map +1 -0
- package/dist/persistence/db/db-definition.embedded.js +170 -0
- package/dist/persistence/db/db-definition.embedded.js.map +1 -0
- package/dist/persistence/db/db-provider.d.ts.map +1 -1
- package/dist/persistence/db/db-provider.js +13 -18
- package/dist/persistence/db/db-provider.js.map +1 -1
- package/dist/persistence/db/db-schema.d.ts +14 -0
- package/dist/persistence/db/db-schema.d.ts.map +1 -1
- package/dist/persistence/db/db-schema.js +27 -0
- package/dist/persistence/db/db-schema.js.map +1 -1
- package/dist/persistence/origin/origin-definition.embedded.d.ts +3 -0
- package/dist/persistence/origin/origin-definition.embedded.d.ts.map +1 -0
- package/dist/persistence/origin/origin-definition.embedded.js +88 -0
- package/dist/persistence/origin/origin-definition.embedded.js.map +1 -0
- package/dist/persistence/origin/origin-schema.d.ts.map +1 -1
- package/dist/persistence/origin/origin-schema.js +7 -3
- package/dist/persistence/origin/origin-schema.js.map +1 -1
- package/dist/persistence/source/source-definition.embedded.d.ts +3 -0
- package/dist/persistence/source/source-definition.embedded.d.ts.map +1 -0
- package/dist/persistence/source/source-definition.embedded.js +17 -0
- package/dist/persistence/source/source-definition.embedded.js.map +1 -0
- package/dist/persistence/source/validate-source-parameter-ref.d.ts.map +1 -1
- package/dist/persistence/source/validate-source-parameter-ref.js +7 -1
- package/dist/persistence/source/validate-source-parameter-ref.js.map +1 -1
- package/dist/persistence/source/validate-source-roles.d.ts.map +1 -1
- package/dist/persistence/source/validate-source-roles.js +16 -1
- package/dist/persistence/source/validate-source-roles.js.map +1 -1
- package/dist/presentation/layout/layout-definition.embedded.d.ts +3 -0
- package/dist/presentation/layout/layout-definition.embedded.d.ts.map +1 -0
- package/dist/presentation/layout/layout-definition.embedded.js +16 -0
- package/dist/presentation/layout/layout-definition.embedded.js.map +1 -0
- package/dist/presentation/layout/layout-schema.d.ts.map +1 -1
- package/dist/presentation/layout/layout-schema.js +3 -2
- package/dist/presentation/layout/layout-schema.js.map +1 -1
- package/dist/presentation/ui/ui-definition.embedded.d.ts +3 -0
- package/dist/presentation/ui/ui-definition.embedded.d.ts.map +1 -0
- package/dist/presentation/ui/ui-definition.embedded.js +114 -0
- package/dist/presentation/ui/ui-definition.embedded.js.map +1 -0
- package/dist/presentation/ui/ui-provider.d.ts +3 -0
- package/dist/presentation/ui/ui-provider.d.ts.map +1 -0
- package/dist/presentation/ui/ui-provider.js +21 -0
- package/dist/presentation/ui/ui-provider.js.map +1 -0
- package/dist/presentation/ui/ui-schema.d.ts +10 -0
- package/dist/presentation/ui/ui-schema.d.ts.map +1 -0
- package/dist/presentation/ui/ui-schema.js +41 -0
- package/dist/presentation/ui/ui-schema.js.map +1 -0
- package/dist/presentation/view/view-definition.embedded.d.ts +3 -0
- package/dist/presentation/view/view-definition.embedded.d.ts.map +1 -0
- package/dist/presentation/view/view-definition.embedded.js +76 -0
- package/dist/presentation/view/view-definition.embedded.js.map +1 -0
- package/dist/provider-data.d.ts +169 -0
- package/dist/provider-data.d.ts.map +1 -0
- package/dist/provider-data.js +269 -0
- package/dist/provider-data.js.map +1 -0
- package/dist/provider.d.ts +3 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +15 -1
- package/dist/provider.js.map +1 -1
- package/dist/registry-coverage.d.ts +99 -0
- package/dist/registry-coverage.d.ts.map +1 -0
- package/dist/registry-coverage.js +294 -0
- package/dist/registry-coverage.js.map +1 -0
- package/dist/registry-manifest-exclusions.d.ts +62 -0
- package/dist/registry-manifest-exclusions.d.ts.map +1 -0
- package/dist/registry-manifest-exclusions.js +163 -0
- package/dist/registry-manifest-exclusions.js.map +1 -0
- package/dist/registry-manifest.d.ts +117 -0
- package/dist/registry-manifest.d.ts.map +1 -0
- package/dist/registry-manifest.js +242 -0
- package/dist/registry-manifest.js.map +1 -0
- package/dist/registry.d.ts +60 -2
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +37 -1
- package/dist/registry.js.map +1 -1
- package/dist/shared/structural.d.ts +7 -0
- package/dist/shared/structural.d.ts.map +1 -1
- package/dist/shared/structural.js +7 -0
- package/dist/shared/structural.js.map +1 -1
- package/dist/subtype-rules.d.ts.map +1 -1
- package/dist/subtype-rules.js +97 -13
- package/dist/subtype-rules.js.map +1 -1
- package/dist/super-resolve.d.ts +49 -2
- package/dist/super-resolve.d.ts.map +1 -1
- package/dist/super-resolve.js +128 -43
- package/dist/super-resolve.js.map +1 -1
- package/dist/template/meta-template.d.ts +3 -2
- package/dist/template/meta-template.d.ts.map +1 -1
- package/dist/template/meta-template.js +3 -2
- package/dist/template/meta-template.js.map +1 -1
- package/dist/template/prompt-definition.embedded.d.ts +3 -0
- package/dist/template/prompt-definition.embedded.d.ts.map +1 -0
- package/dist/template/prompt-definition.embedded.js +368 -0
- package/dist/template/prompt-definition.embedded.js.map +1 -0
- package/dist/template/prompt-provider.d.ts +3 -0
- package/dist/template/prompt-provider.d.ts.map +1 -0
- package/dist/template/prompt-provider.js +25 -0
- package/dist/template/prompt-provider.js.map +1 -0
- package/dist/template/prompt-schema.d.ts +20 -0
- package/dist/template/prompt-schema.d.ts.map +1 -0
- package/dist/template/prompt-schema.js +70 -0
- package/dist/template/prompt-schema.js.map +1 -0
- package/dist/template/template-constants.d.ts +2 -0
- package/dist/template/template-constants.d.ts.map +1 -1
- package/dist/template/template-constants.js +7 -0
- package/dist/template/template-constants.js.map +1 -1
- package/dist/template/template-definition.embedded.d.ts +3 -0
- package/dist/template/template-definition.embedded.d.ts.map +1 -0
- package/dist/template/template-definition.embedded.js +30 -0
- package/dist/template/template-definition.embedded.js.map +1 -0
- package/dist/template/template-schema.d.ts.map +1 -1
- package/dist/template/template-schema.js +12 -4
- package/dist/template/template-schema.js.map +1 -1
- package/package.json +33 -22
- package/src/attr-schema-validate.ts +96 -4
- package/src/constraint-merge.ts +0 -0
- package/src/constraint-validate.ts +363 -0
- package/src/core/attr/attr-constants.ts +15 -3
- package/src/core/attr/attr-definition.embedded.ts +67 -0
- package/src/core/documentation/doc-constants.ts +3 -1
- package/src/core/documentation/doc-provider.ts +6 -2
- package/src/core/documentation/documentation-definition.embedded.ts +86 -0
- package/src/core/field/field-constants.ts +8 -7
- package/src/core/field/field-definition.embedded.ts +243 -0
- package/src/core/field/meta-field.ts +6 -7
- package/src/core/identity/identity-definition.embedded.ts +98 -0
- package/src/core/identity/validate-identity-passthrough.ts +194 -0
- package/src/core/object/object-constants.ts +3 -0
- package/src/core/object/object-definition.embedded.ts +117 -0
- package/src/core/object/validate-discriminator.ts +0 -4
- package/src/core/query/query-constants.ts +5 -3
- package/src/core/relationship/derive-m2m-fields.ts +145 -0
- package/src/core/relationship/meta-relationship.ts +15 -9
- package/src/core/relationship/relationship-constants.ts +6 -2
- package/src/core/relationship/relationship-definition.embedded.ts +317 -0
- package/src/core/validator/validator-definition.embedded.ts +141 -0
- package/src/core/yaml-desugar.ts +96 -7
- package/src/core-types.ts +289 -150
- package/src/errors.ts +78 -0
- package/src/index.ts +47 -2
- package/src/library/embedded-library.generated.ts +10 -0
- package/src/library/library-sources.ts +97 -0
- package/src/loader/meta-data-loader.ts +66 -7
- package/src/loader/shortcuts.ts +2 -2
- package/src/loader/validation-passes.ts +679 -33
- package/src/metamodel-docs/index.ts +41 -0
- package/src/metamodel-docs/provenance.ts +187 -0
- package/src/metamodel-docs/provider-definitions.ts +50 -0
- package/src/metamodel-docs/render.ts +309 -0
- package/src/naming-refs.ts +162 -0
- package/src/naming.ts +10 -2
- package/src/parser-core.ts +86 -8
- package/src/persistence/db/db-definition.embedded.ts +177 -0
- package/src/persistence/db/db-provider.ts +13 -18
- package/src/persistence/origin/origin-definition.embedded.ts +95 -0
- package/src/persistence/source/source-definition.embedded.ts +24 -0
- package/src/persistence/source/validate-source-parameter-ref.ts +7 -1
- package/src/persistence/source/validate-source-roles.ts +22 -1
- package/src/presentation/layout/layout-definition.embedded.ts +23 -0
- package/src/presentation/ui/ui-definition.embedded.ts +121 -0
- package/src/presentation/ui/ui-provider.ts +25 -0
- package/src/presentation/view/view-definition.embedded.ts +83 -0
- package/src/provider-data.ts +446 -0
- package/src/provider.ts +18 -0
- package/src/registry-coverage.ts +430 -0
- package/src/registry-manifest-exclusions.ts +176 -0
- package/src/registry-manifest.ts +334 -0
- package/src/registry.ts +90 -3
- package/src/shared/structural.ts +8 -0
- package/src/subtype-rules.ts +135 -18
- package/src/super-resolve.ts +153 -43
- package/src/template/meta-template.ts +3 -2
- package/src/template/prompt-definition.embedded.ts +375 -0
- package/src/template/prompt-provider.ts +29 -0
- package/src/template/template-constants.ts +8 -0
- package/src/template/template-definition.embedded.ts +37 -0
- package/src/core/documentation/doc-schema.ts +0 -64
- package/src/core/field/field-schema.ts +0 -228
- package/src/core/identity/identity-schema.ts +0 -80
- package/src/core/object/object-schema.ts +0 -35
- package/src/core/relationship/relationship-schema.ts +0 -67
- package/src/core/validator/validator-schema.ts +0 -50
- package/src/persistence/db/db-schema.ts +0 -50
- package/src/persistence/origin/origin-schema.ts +0 -80
- package/src/persistence/source/source-schema.ts +0 -129
- package/src/presentation/layout/layout-schema.ts +0 -62
- package/src/presentation/view/view-schema.ts +0 -21
- package/src/template/template-schema.ts +0 -211
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
// Validation pass: FR-024 projection identity pass-through + key correspondence.
|
|
2
|
+
//
|
|
3
|
+
// A projection's identity is a PASS-THROUGH of an entity identity:
|
|
4
|
+
//
|
|
5
|
+
// - every identity child of an object.projection MUST extend an entity
|
|
6
|
+
// identity (the dotted by-name form, e.g. `extends: "Customer.id"`);
|
|
7
|
+
// a projection identity without `extends` → ERR_PROJECTION_IDENTITY_NOT_EXTENDED.
|
|
8
|
+
// - key correspondence: every field named by the extended identity's
|
|
9
|
+
// @fields must have a local projection field extending it; a missing
|
|
10
|
+
// pass-through → ERR_IDENTITY_KEY_MISMATCH.
|
|
11
|
+
// - the identity's local key is COMPUTED from those local fields (in the
|
|
12
|
+
// extended identity's order) — derived on read, NEVER written back into
|
|
13
|
+
// the tree (metadata is the authored spine; the loader never mutates it).
|
|
14
|
+
// An explicit @fields that disagrees with the computed set →
|
|
15
|
+
// ERR_IDENTITY_KEY_MISMATCH.
|
|
16
|
+
//
|
|
17
|
+
// Unresolved / type-mismatched `extends` refs are NOT re-reported here — the
|
|
18
|
+
// deferred-super pass already emitted ERR_UNRESOLVED_SUPER /
|
|
19
|
+
// ERR_EXTENDS_TARGET_MISMATCH for those.
|
|
20
|
+
|
|
21
|
+
import type { MetaData } from "../../shared/meta-data.js";
|
|
22
|
+
import { ParseError } from "../../errors.js";
|
|
23
|
+
import { TYPE_OBJECT, TYPE_IDENTITY, TYPE_FIELD } from "../../shared/base-types.js";
|
|
24
|
+
import { OBJECT_SUBTYPE_PROJECTION } from "../object/object-constants.js";
|
|
25
|
+
import { IDENTITY_ATTR_FIELDS } from "./identity-constants.js";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Normalize an identity's OWN @fields attr to a string[]. Accepts both the
|
|
29
|
+
* array form (["id"]) and the comma-string form ("id" / "a,b"); returns
|
|
30
|
+
* undefined when the identity declares no own @fields (the pass-through case).
|
|
31
|
+
*/
|
|
32
|
+
export function identityOwnFields(identity: MetaData): string[] | undefined {
|
|
33
|
+
return normalizeFields(identity.ownAttr(IDENTITY_ATTR_FIELDS));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Normalize an identity's EFFECTIVE @fields attr (inherits through extends). */
|
|
37
|
+
export function identityEffectiveFields(identity: MetaData): string[] | undefined {
|
|
38
|
+
return normalizeFields(identity.attr(IDENTITY_ATTR_FIELDS));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function normalizeFields(raw: unknown): string[] | undefined {
|
|
42
|
+
if (raw === undefined || raw === null) return undefined;
|
|
43
|
+
if (Array.isArray(raw)) return raw.map((v) => String(v).trim());
|
|
44
|
+
if (typeof raw === "string") {
|
|
45
|
+
return raw
|
|
46
|
+
.split(",")
|
|
47
|
+
.map((s) => s.trim())
|
|
48
|
+
.filter((s) => s.length > 0);
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** The result of deriving a projection identity's pass-through key. */
|
|
54
|
+
export interface IdentityPassthroughResolution {
|
|
55
|
+
/** The owning entity of the extended identity. */
|
|
56
|
+
readonly entity: MetaData;
|
|
57
|
+
/** Local pass-through field names, in the extended identity's @fields order. */
|
|
58
|
+
readonly computedFields: string[];
|
|
59
|
+
/** Extended-identity field names with NO local pass-through field. */
|
|
60
|
+
readonly missing: string[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Derive a projection identity's pass-through key — a PURE read of the
|
|
65
|
+
* resolved tree (no mutation): for each field name in the extended identity's
|
|
66
|
+
* effective @fields, find the local field whose extends-chain reaches the
|
|
67
|
+
* entity's field of that name; the computed key is those local field names in
|
|
68
|
+
* the extended identity's order.
|
|
69
|
+
*
|
|
70
|
+
* Returns undefined when the identity has no resolved identity super (the
|
|
71
|
+
* not-extended / unresolved / mismatched cases — reported elsewhere).
|
|
72
|
+
*/
|
|
73
|
+
export function resolveIdentityPassthrough(
|
|
74
|
+
identity: MetaData,
|
|
75
|
+
): IdentityPassthroughResolution | undefined {
|
|
76
|
+
const extended = identity.superResolved;
|
|
77
|
+
if (extended === undefined || extended.type !== TYPE_IDENTITY) return undefined;
|
|
78
|
+
const entity = extended.parent;
|
|
79
|
+
if (entity === undefined || entity.type !== TYPE_OBJECT) return undefined;
|
|
80
|
+
const owner = identity.parent;
|
|
81
|
+
if (owner === undefined) return undefined;
|
|
82
|
+
|
|
83
|
+
const extendedFields = identityEffectiveFields(extended) ?? [];
|
|
84
|
+
const computedFields: string[] = [];
|
|
85
|
+
const missing: string[] = [];
|
|
86
|
+
for (const fieldName of extendedFields) {
|
|
87
|
+
const entityField = entity
|
|
88
|
+
.children()
|
|
89
|
+
.find((c) => c.type === TYPE_FIELD && c.name === fieldName);
|
|
90
|
+
if (entityField === undefined) {
|
|
91
|
+
missing.push(fieldName);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const local = owner
|
|
95
|
+
.ownChildren()
|
|
96
|
+
.find((c) => c.type === TYPE_FIELD && extendsChainReaches(c, entityField));
|
|
97
|
+
if (local === undefined) {
|
|
98
|
+
missing.push(fieldName);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
computedFields.push(local.name);
|
|
102
|
+
}
|
|
103
|
+
return { entity, computedFields, missing };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The computed pass-through key of a projection identity, or undefined when
|
|
108
|
+
* the identity is not a fully-corresponding pass-through. Codegen-facing
|
|
109
|
+
* convenience over resolveIdentityPassthrough.
|
|
110
|
+
*/
|
|
111
|
+
export function computedIdentityFields(identity: MetaData): string[] | undefined {
|
|
112
|
+
const res = resolveIdentityPassthrough(identity);
|
|
113
|
+
if (res === undefined || res.missing.length > 0) return undefined;
|
|
114
|
+
return res.computedFields;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function extendsChainReaches(node: MetaData, target: MetaData): boolean {
|
|
118
|
+
let cur = node.superResolved;
|
|
119
|
+
while (cur !== undefined) {
|
|
120
|
+
if (cur === target) return true;
|
|
121
|
+
cur = cur.superResolved;
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function arraysEqual(a: readonly string[], b: readonly string[]): boolean {
|
|
127
|
+
return a.length === b.length && a.every((v, i) => v === b[i]);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Walk every object.projection in the root and enforce the pass-through +
|
|
132
|
+
* key-correspondence rules. Returns errors; never mutates the tree.
|
|
133
|
+
*/
|
|
134
|
+
export function validateIdentityPassthrough(root: MetaData): ParseError[] {
|
|
135
|
+
const errors: ParseError[] = [];
|
|
136
|
+
|
|
137
|
+
for (const obj of root
|
|
138
|
+
.ownChildren()
|
|
139
|
+
.filter(
|
|
140
|
+
(c) => c.type === TYPE_OBJECT && c.subType === OBJECT_SUBTYPE_PROJECTION,
|
|
141
|
+
)) {
|
|
142
|
+
for (const identity of obj
|
|
143
|
+
.ownChildren()
|
|
144
|
+
.filter((c) => c.type === TYPE_IDENTITY)) {
|
|
145
|
+
if (identity.superRef === undefined) {
|
|
146
|
+
errors.push(
|
|
147
|
+
new ParseError(
|
|
148
|
+
`identity '${identity.name}' on projection '${obj.name}' must extend an entity identity ` +
|
|
149
|
+
`(e.g. extends: "Customer.id") — a projection identity is a pass-through (FR-024)`,
|
|
150
|
+
{
|
|
151
|
+
code: "ERR_PROJECTION_IDENTITY_NOT_EXTENDED",
|
|
152
|
+
source: identity.source,
|
|
153
|
+
},
|
|
154
|
+
),
|
|
155
|
+
);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const res = resolveIdentityPassthrough(identity);
|
|
160
|
+
// Unresolved or non-identity target: ERR_UNRESOLVED_SUPER /
|
|
161
|
+
// ERR_EXTENDS_TARGET_MISMATCH already reported by the deferred-super pass.
|
|
162
|
+
if (res === undefined) continue;
|
|
163
|
+
|
|
164
|
+
if (res.missing.length > 0) {
|
|
165
|
+
const missingRefs = res.missing
|
|
166
|
+
.map((f) => `'${res.entity.name}.${f}'`)
|
|
167
|
+
.join(", ");
|
|
168
|
+
errors.push(
|
|
169
|
+
new ParseError(
|
|
170
|
+
`identity '${identity.name}' on projection '${obj.name}' does not correspond to its ` +
|
|
171
|
+
`extended identity: no local field extends ${missingRefs} — every field of the ` +
|
|
172
|
+
`extended identity needs a pass-through field on the projection (FR-024)`,
|
|
173
|
+
{ code: "ERR_IDENTITY_KEY_MISMATCH", source: identity.source },
|
|
174
|
+
),
|
|
175
|
+
);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const explicit = identityOwnFields(identity);
|
|
180
|
+
if (explicit !== undefined && !arraysEqual(explicit, res.computedFields)) {
|
|
181
|
+
errors.push(
|
|
182
|
+
new ParseError(
|
|
183
|
+
`identity '${identity.name}' on projection '${obj.name}' declares @fields ` +
|
|
184
|
+
`[${explicit.join(", ")}] but the computed pass-through key is ` +
|
|
185
|
+
`[${res.computedFields.join(", ")}] — omit @fields (it is derived) or make them agree (FR-024)`,
|
|
186
|
+
{ code: "ERR_IDENTITY_KEY_MISMATCH", source: identity.source },
|
|
187
|
+
),
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return errors;
|
|
194
|
+
}
|
|
@@ -9,14 +9,17 @@ import { SUBTYPE_BASE } from "../../shared/base-types.js";
|
|
|
9
9
|
// - base : abstract template (no runtime semantics)
|
|
10
10
|
// - entity : persistent record (typically has @primary identity)
|
|
11
11
|
// - value : value-object (no identity; equality by content)
|
|
12
|
+
// - projection : derived read-only representation of entities (FR-024, ADR-0028)
|
|
12
13
|
//
|
|
13
14
|
export const OBJECT_SUBTYPE_ENTITY = "entity";
|
|
14
15
|
export const OBJECT_SUBTYPE_VALUE = "value";
|
|
16
|
+
export const OBJECT_SUBTYPE_PROJECTION = "projection";
|
|
15
17
|
|
|
16
18
|
export const OBJECT_SUBTYPES = [
|
|
17
19
|
SUBTYPE_BASE,
|
|
18
20
|
OBJECT_SUBTYPE_ENTITY,
|
|
19
21
|
OBJECT_SUBTYPE_VALUE,
|
|
22
|
+
OBJECT_SUBTYPE_PROJECTION,
|
|
20
23
|
] as const;
|
|
21
24
|
export type ObjectSubType = (typeof OBJECT_SUBTYPES)[number];
|
|
22
25
|
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// AUTO-GENERATED by scripts/generate-embedded-metamodel.ts — DO NOT EDIT.
|
|
2
|
+
// Canonical source: repo-root spec/metamodel/object.json
|
|
3
|
+
// Regenerate: bun run scripts/generate-embedded-metamodel.ts
|
|
4
|
+
//
|
|
5
|
+
// Embeds the canonical FR-033 ProviderDefinition so the provider can register
|
|
6
|
+
// itself wherever the on-disk spec/ tree is unavailable (bundled builds).
|
|
7
|
+
import type { ProviderDefinition } from "../../provider-data.js";
|
|
8
|
+
|
|
9
|
+
export const OBJECT_DEFINITION: ProviderDefinition = {
|
|
10
|
+
"provider": "metaobjects-core-types",
|
|
11
|
+
"types": [
|
|
12
|
+
{
|
|
13
|
+
"type": "object",
|
|
14
|
+
"subType": "base",
|
|
15
|
+
"description": "Abstract object base — the shared root subtype that concrete object subtypes (entity/value/projection) specialize. Declares the structural children common to EVERY object subtype (the intersection: field/identity/validator/layout/source); subtype-specific children (relationship, template) and attrs (discriminator) ride their own subtypes. Has no runtime semantics of its own; not authored directly.",
|
|
16
|
+
"children": [
|
|
17
|
+
{
|
|
18
|
+
"type": "field",
|
|
19
|
+
"subType": "*",
|
|
20
|
+
"name": "*",
|
|
21
|
+
"min": 0,
|
|
22
|
+
"max": null
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"type": "identity",
|
|
26
|
+
"subType": "*",
|
|
27
|
+
"name": "*",
|
|
28
|
+
"min": 0,
|
|
29
|
+
"max": null
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "validator",
|
|
33
|
+
"subType": "*",
|
|
34
|
+
"name": "*",
|
|
35
|
+
"min": 0,
|
|
36
|
+
"max": null
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"type": "layout",
|
|
40
|
+
"subType": "*",
|
|
41
|
+
"name": "*",
|
|
42
|
+
"min": 0,
|
|
43
|
+
"max": null
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"type": "source",
|
|
47
|
+
"subType": "*",
|
|
48
|
+
"name": "*",
|
|
49
|
+
"min": 0,
|
|
50
|
+
"max": null
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"type": "object",
|
|
56
|
+
"subType": "entity",
|
|
57
|
+
"extendsBase": true,
|
|
58
|
+
"description": "An object that owns its data: own identity, writable sources, and lifecycle. The default object subtype — a bare `object:` key resolves to entity. May co-locate templates (template.prompt and friends) with the owning entity.",
|
|
59
|
+
"rules": "object.entity owns data — it declares its own identity, its primary source must be a writable @kind (read-only kinds may appear only in a read role), and it carries lifecycle. A field carrying origin.* is derived ⇒ read-only wherever it lives, including on an entity. Templates (template.*) may be nested so a prompt can be co-located with its owning entity. See ADR-0028 (object taxonomy).",
|
|
60
|
+
"children": [
|
|
61
|
+
{
|
|
62
|
+
"type": "relationship",
|
|
63
|
+
"subType": "*",
|
|
64
|
+
"name": "*",
|
|
65
|
+
"min": 0,
|
|
66
|
+
"max": null
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"type": "template",
|
|
70
|
+
"subType": "*",
|
|
71
|
+
"name": "*",
|
|
72
|
+
"min": 0,
|
|
73
|
+
"max": null
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"type": "attr",
|
|
77
|
+
"subType": "string",
|
|
78
|
+
"name": "discriminator",
|
|
79
|
+
"min": 0,
|
|
80
|
+
"max": 1,
|
|
81
|
+
"description": "FR-014: names the field on this entity (resolvable via extends:) that holds the subtype-discriminator value. Subtypes of this entity declare @discriminatorValue to bind their rows to a discriminator value. The discriminator field itself is an ordinary field declaration (typically field.enum or field.int / field.string)."
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"type": "attr",
|
|
85
|
+
"subType": "string",
|
|
86
|
+
"name": "discriminatorValue",
|
|
87
|
+
"min": 0,
|
|
88
|
+
"max": 1,
|
|
89
|
+
"description": "FR-014: on a subtype of an entity with @discriminator — the value that identifies rows of this subtype in the shared discriminator field. Wire form is always a string; the underlying field's subtype (enum / int / string) controls codegen + storage coercion. Required on every concrete subtype of a discriminated entity."
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"type": "object",
|
|
95
|
+
"subType": "value",
|
|
96
|
+
"extendsBase": true,
|
|
97
|
+
"description": "A value object — pure shape with NO identity and NO source, ever. Constructed (by caller / assembly / embedding), never populated from a store. May `extends` an entity's fields to reuse shape. Equality is by content.",
|
|
98
|
+
"rules": "object.value is pure shape: it NEVER declares an identity and NEVER declares a source, in any role. It is constructed — by a caller, by assembly, or by embedding — and is never populated from a backing store. It may `extends` an entity's fields to reuse their shape. @normalize is the object-level default ASCII normalization mode applied to this value's enum fields' tolerant extract (each field may still override per-field). See ADR-0028 (object taxonomy, value purity).",
|
|
99
|
+
"children": [
|
|
100
|
+
{
|
|
101
|
+
"type": "relationship",
|
|
102
|
+
"subType": "*",
|
|
103
|
+
"name": "*",
|
|
104
|
+
"min": 0,
|
|
105
|
+
"max": null
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"type": "object",
|
|
111
|
+
"subType": "projection",
|
|
112
|
+
"extendsBase": true,
|
|
113
|
+
"description": "A derived read-only representation of entities. Its fields are extends-bound / origin-derived / self-declared-under-external-assembly, all read-only at the subtype level. Identity is optional and MUST extend an entity identity; sources are restricted to read-only @kinds. The declared field set IS the exposure (inclusive, fail-closed).",
|
|
114
|
+
"rules": "object.projection is a derived read-only representation: every field is extends-bound, origin-derived, or self-declared-under-external-assembly, and all are read-only at the subtype level. Identity is optional and, when present, MUST extend an entity identity. Sources are restricted to read-only @kinds. The declared field set IS the exposure — an inclusive list, fail-closed. A projection NEVER declares relationships (derivation is expressed via @via, not a relationship child) and NEVER co-locates templates — hence its child set omits both relationship and template. See ADR-0028 (object taxonomy, projection)."
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
};
|
|
@@ -28,8 +28,6 @@ import {
|
|
|
28
28
|
FIELD_SUBTYPE_ENUM,
|
|
29
29
|
FIELD_SUBTYPE_INT,
|
|
30
30
|
FIELD_SUBTYPE_LONG,
|
|
31
|
-
FIELD_SUBTYPE_SHORT,
|
|
32
|
-
FIELD_SUBTYPE_BYTE,
|
|
33
31
|
FIELD_SUBTYPE_STRING,
|
|
34
32
|
FIELD_ATTR_VALUES,
|
|
35
33
|
} from "../field/field-constants.js";
|
|
@@ -37,8 +35,6 @@ import {
|
|
|
37
35
|
const NUMERIC_DISCRIMINATOR_SUBTYPES = new Set<string>([
|
|
38
36
|
FIELD_SUBTYPE_INT,
|
|
39
37
|
FIELD_SUBTYPE_LONG,
|
|
40
|
-
FIELD_SUBTYPE_SHORT,
|
|
41
|
-
FIELD_SUBTYPE_BYTE,
|
|
42
38
|
]);
|
|
43
39
|
|
|
44
40
|
export function validateDiscriminator(root: MetaData): ParseError[] {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FIELD_SUBTYPE_UUID } from "../field/field-constants.js";
|
|
1
|
+
import { FIELD_SUBTYPE_UUID, FIELD_SUBTYPE_CURRENCY, FIELD_SUBTYPE_ENUM } from "../field/field-constants.js";
|
|
2
2
|
|
|
3
3
|
// Query concern constants — filter operators, sort order values.
|
|
4
4
|
//
|
|
@@ -39,13 +39,15 @@ export type FilterOp = (typeof FILTER_OPS)[number];
|
|
|
39
39
|
|
|
40
40
|
export const OPS_BY_SUBTYPE: Readonly<Record<string, readonly FilterOp[]>> = {
|
|
41
41
|
string: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_IN, FILTER_OP_LIKE, FILTER_OP_IS_NULL],
|
|
42
|
+
// enum: string-backed — same op band as string.
|
|
43
|
+
[FIELD_SUBTYPE_ENUM]: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_IN, FILTER_OP_LIKE, FILTER_OP_IS_NULL],
|
|
42
44
|
int: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
|
|
43
|
-
short: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
|
|
44
|
-
byte: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
|
|
45
45
|
long: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
|
|
46
46
|
double: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
|
|
47
47
|
float: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
|
|
48
48
|
decimal: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
|
|
49
|
+
// currency: integer minor units — an orderable number. Numeric ops, no `like`.
|
|
50
|
+
[FIELD_SUBTYPE_CURRENCY]: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
|
|
49
51
|
boolean: [FILTER_OP_EQ, FILTER_OP_IS_NULL],
|
|
50
52
|
date: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
|
|
51
53
|
time: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// M:N junction FK derivation — the single source of truth for which junction
|
|
2
|
+
// columns are the SOURCE side and the TARGET side of a many-to-many relationship.
|
|
3
|
+
//
|
|
4
|
+
// A M:N relationship (`@cardinality: "many"`, `@objectRef: <target>`,
|
|
5
|
+
// `@through: <junction>`) does NOT restate its FK columns. They are derived from
|
|
6
|
+
// the junction entity's two `identity.reference` children — one resolving to the
|
|
7
|
+
// source entity, one to the target — exactly as 1:N FK direction is declared
|
|
8
|
+
// (`find-reference.ts` is the analogous SSOT).
|
|
9
|
+
//
|
|
10
|
+
// Three modes (see the FR-018 design):
|
|
11
|
+
// 1. Hetero (source != target): the reference resolving to the source entity
|
|
12
|
+
// gives sourceField; the one resolving to the target gives targetField.
|
|
13
|
+
// 2. Directed self-join (source == target, @sourceRefField set): both
|
|
14
|
+
// references resolve to the same entity, so @sourceRefField names the
|
|
15
|
+
// source-side FK field; the OTHER reference is the target side.
|
|
16
|
+
// 3. Symmetric self-join (source == target, @symmetric: true): undirected; the
|
|
17
|
+
// two references are taken in declaration order (sourceField = first,
|
|
18
|
+
// targetField = second). Resolution unions both at read time.
|
|
19
|
+
// Ambiguous (source == target, neither @sourceRefField nor @symmetric) → throw.
|
|
20
|
+
|
|
21
|
+
import type { MetaObject } from "../object/meta-object.js";
|
|
22
|
+
import type { MetaRoot } from "../../shared/meta-root.js";
|
|
23
|
+
import type { MetaRelationship } from "./meta-relationship.js";
|
|
24
|
+
import type { MetaReferenceIdentity } from "../identity/meta-identity.js";
|
|
25
|
+
import { stripPackage } from "../../naming.js";
|
|
26
|
+
|
|
27
|
+
/** Thrown when a M:N relationship's junction FK fields cannot be derived. */
|
|
28
|
+
export class M2MDerivationError extends Error {
|
|
29
|
+
readonly code = "ERR_INVALID_RELATIONSHIP";
|
|
30
|
+
constructor(message: string) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.name = "M2MDerivationError";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface M2MFields {
|
|
37
|
+
/** The junction FK field holding the source-entity key. */
|
|
38
|
+
readonly sourceField: string;
|
|
39
|
+
/** The junction FK field holding the target-entity key. */
|
|
40
|
+
readonly targetField: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** First @fields entry of a reference (the physical FK column on the junction). */
|
|
44
|
+
function refFkField(ref: MetaReferenceIdentity): string | undefined {
|
|
45
|
+
return ref.fields[0];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Derive the source/target junction FK fields for a M:N relationship.
|
|
50
|
+
*
|
|
51
|
+
* @param rel the M:N relationship (carries @objectRef + @through + optional
|
|
52
|
+
* @sourceRefField / @symmetric)
|
|
53
|
+
* @param source the entity declaring `rel`
|
|
54
|
+
* @param root the loaded model root (to find the junction entity)
|
|
55
|
+
* @throws M2MDerivationError when the junction is missing/malformed or the
|
|
56
|
+
* self-join is ambiguous.
|
|
57
|
+
*/
|
|
58
|
+
export function deriveM2MFields(
|
|
59
|
+
rel: MetaRelationship,
|
|
60
|
+
source: MetaObject,
|
|
61
|
+
root: MetaRoot,
|
|
62
|
+
): M2MFields {
|
|
63
|
+
const throughName = rel.through;
|
|
64
|
+
if (throughName === undefined) {
|
|
65
|
+
throw new M2MDerivationError(
|
|
66
|
+
`relationship "${source.name}.${rel.name}" is missing @through (required for M:N derivation)`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
const junction = root.findObject(throughName);
|
|
70
|
+
if (junction === undefined) {
|
|
71
|
+
throw new M2MDerivationError(
|
|
72
|
+
`relationship "${source.name}.${rel.name}" @through "${throughName}" does not resolve to an entity`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const targetName = rel.objectRef;
|
|
77
|
+
if (targetName === undefined) {
|
|
78
|
+
throw new M2MDerivationError(
|
|
79
|
+
`relationship "${source.name}.${rel.name}" is missing @objectRef (the M:N target)`,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const refs = junction.referenceIdentities();
|
|
84
|
+
if (refs.length !== 2) {
|
|
85
|
+
throw new M2MDerivationError(
|
|
86
|
+
`junction "${throughName}" for relationship "${source.name}.${rel.name}" must declare exactly two ` +
|
|
87
|
+
`identity.reference children (found ${refs.length})`,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const isSelfJoin = stripPackage(targetName) === source.name;
|
|
92
|
+
|
|
93
|
+
if (!isSelfJoin) {
|
|
94
|
+
// Hetero: match each reference by the entity it resolves to.
|
|
95
|
+
const sourceRef = refs.find((r) => r.targetEntity !== undefined && stripPackage(r.targetEntity) === source.name);
|
|
96
|
+
const targetRef = refs.find((r) => r.targetEntity !== undefined && stripPackage(r.targetEntity) === stripPackage(targetName));
|
|
97
|
+
const sourceField = sourceRef ? refFkField(sourceRef) : undefined;
|
|
98
|
+
const targetField = targetRef ? refFkField(targetRef) : undefined;
|
|
99
|
+
if (sourceField === undefined || targetField === undefined) {
|
|
100
|
+
throw new M2MDerivationError(
|
|
101
|
+
`junction "${throughName}" for relationship "${source.name}.${rel.name}" must declare one ` +
|
|
102
|
+
`identity.reference to "${source.name}" and one to "${stripPackage(targetName)}"`,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
return { sourceField, targetField };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Self-join: both references resolve to the same entity.
|
|
109
|
+
if (rel.symmetric) {
|
|
110
|
+
// Undirected: take references in declaration order; union happens at read time.
|
|
111
|
+
const a = refFkField(refs[0]!);
|
|
112
|
+
const b = refFkField(refs[1]!);
|
|
113
|
+
if (a === undefined || b === undefined) {
|
|
114
|
+
throw new M2MDerivationError(
|
|
115
|
+
`symmetric junction "${throughName}" for "${source.name}.${rel.name}" has a reference with no @fields`,
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
return { sourceField: a, targetField: b };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const sourceRefField = rel.sourceRefField;
|
|
122
|
+
if (sourceRefField === undefined) {
|
|
123
|
+
throw new M2MDerivationError(
|
|
124
|
+
`self-join relationship "${source.name}.${rel.name}" through "${throughName}" is ambiguous: ` +
|
|
125
|
+
`set @sourceRefField (directed) or @symmetric (undirected)`,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Directed self-join: @sourceRefField names the source-side FK; the other ref is the target.
|
|
130
|
+
const sourceRef = refs.find((r) => refFkField(r) === sourceRefField);
|
|
131
|
+
if (sourceRef === undefined) {
|
|
132
|
+
throw new M2MDerivationError(
|
|
133
|
+
`@sourceRefField "${sourceRefField}" on "${source.name}.${rel.name}" does not match any ` +
|
|
134
|
+
`identity.reference FK field on junction "${throughName}"`,
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
const targetRef = refs.find((r) => r !== sourceRef);
|
|
138
|
+
const targetField = targetRef ? refFkField(targetRef) : undefined;
|
|
139
|
+
if (targetField === undefined) {
|
|
140
|
+
throw new M2MDerivationError(
|
|
141
|
+
`junction "${throughName}" for "${source.name}.${rel.name}" has no distinct target-side reference`,
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
return { sourceField: sourceRefField, targetField };
|
|
145
|
+
}
|
|
@@ -6,8 +6,9 @@ import { MetaData } from "../../shared/meta-data.js";
|
|
|
6
6
|
import {
|
|
7
7
|
RELATIONSHIP_ATTR_CARDINALITY,
|
|
8
8
|
RELATIONSHIP_ATTR_OBJECT_REF,
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
RELATIONSHIP_ATTR_THROUGH,
|
|
10
|
+
RELATIONSHIP_ATTR_SOURCE_REF_FIELD,
|
|
11
|
+
RELATIONSHIP_ATTR_SYMMETRIC,
|
|
11
12
|
RELATIONSHIP_ATTR_ON_DELETE,
|
|
12
13
|
RELATIONSHIP_ATTR_ON_UPDATE,
|
|
13
14
|
} from "./relationship-constants.js";
|
|
@@ -24,16 +25,21 @@ export class MetaRelationship extends MetaData {
|
|
|
24
25
|
return typeof v === "string" ? v : undefined;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
/**
|
|
28
|
-
get
|
|
29
|
-
const v = this.ownAttr(
|
|
28
|
+
/** Junction (through) entity name for M:N relationships. */
|
|
29
|
+
get through(): string | undefined {
|
|
30
|
+
const v = this.ownAttr(RELATIONSHIP_ATTR_THROUGH);
|
|
30
31
|
return typeof v === "string" ? v : undefined;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
/**
|
|
34
|
-
get
|
|
35
|
-
const
|
|
36
|
-
return
|
|
34
|
+
/** Source-side FK field on the junction (directed self-join disambiguator). */
|
|
35
|
+
get sourceRefField(): string | undefined {
|
|
36
|
+
const v = this.ownAttr(RELATIONSHIP_ATTR_SOURCE_REF_FIELD);
|
|
37
|
+
return typeof v === "string" ? v : undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Whether this M:N relationship is an undirected (symmetric) self-join. */
|
|
41
|
+
get symmetric(): boolean {
|
|
42
|
+
return this.ownAttr(RELATIONSHIP_ATTR_SYMMETRIC) === true;
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
/** Referential action on parent delete. Undefined when not explicitly set (default derives from subtype). */
|
|
@@ -24,8 +24,12 @@ export type RelationshipSubType = (typeof RELATIONSHIP_SUBTYPES)[number];
|
|
|
24
24
|
|
|
25
25
|
export const RELATIONSHIP_ATTR_CARDINALITY = "cardinality";
|
|
26
26
|
export const RELATIONSHIP_ATTR_OBJECT_REF = "objectRef";
|
|
27
|
-
|
|
28
|
-
export const
|
|
27
|
+
/** M:N junction (through) entity — a third entity declaring two identity.reference children. */
|
|
28
|
+
export const RELATIONSHIP_ATTR_THROUGH = "through";
|
|
29
|
+
/** M:N directed-self-join disambiguator — names the source-side FK field on the junction. */
|
|
30
|
+
export const RELATIONSHIP_ATTR_SOURCE_REF_FIELD = "sourceRefField";
|
|
31
|
+
/** M:N undirected-self-join flag — union-on-read; valid only when objectRef == the declaring entity. */
|
|
32
|
+
export const RELATIONSHIP_ATTR_SYMMETRIC = "symmetric";
|
|
29
33
|
|
|
30
34
|
// ---------------------------------------------------------------------------
|
|
31
35
|
// Relationship cardinality values (for RELATIONSHIP_ATTR_CARDINALITY)
|