@metaobjectsdev/metadata 0.9.0 → 0.11.0-rc.1
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 +96 -11
- package/dist/attr-schema-validate.js.map +1 -1
- 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/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/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/identity/identity-constants.d.ts.map +1 -1
- package/dist/core/identity/identity-constants.js +3 -0
- package/dist/core/identity/identity-constants.js.map +1 -1
- 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 +93 -0
- package/dist/core/identity/identity-definition.embedded.js.map +1 -0
- package/dist/core/identity/meta-identity.d.ts.map +1 -1
- package/dist/core/identity/meta-identity.js +8 -1
- package/dist/core/identity/meta-identity.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/validator/validator-constants.d.ts +14 -1
- package/dist/core/validator/validator-constants.d.ts.map +1 -1
- package/dist/core/validator/validator-constants.js +20 -1
- package/dist/core/validator/validator-constants.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 +255 -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-types.d.ts +5 -2
- package/dist/core-types.d.ts.map +1 -1
- package/dist/core-types.js +285 -116
- package/dist/core-types.js.map +1 -1
- package/dist/errors.d.ts +3 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +87 -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 +57 -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 +519 -34
- package/dist/loader/validation-passes.js.map +1 -1
- package/dist/loader/validation-registry.d.ts +10 -0
- package/dist/loader/validation-registry.d.ts.map +1 -0
- package/dist/loader/validation-registry.js +84 -0
- package/dist/loader/validation-registry.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 +84 -9
- package/dist/parser-core.js.map +1 -1
- package/dist/persistence/db/db-constants.d.ts +10 -0
- package/dist/persistence/db/db-constants.d.ts.map +1 -1
- package/dist/persistence/db/db-constants.js +14 -0
- package/dist/persistence/db/db-constants.js.map +1 -1
- 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 +227 -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/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/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/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/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 +184 -0
- package/dist/provider-data.d.ts.map +1 -0
- package/dist/provider-data.js +271 -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 +76 -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/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/validate-max-occurs.d.ts +5 -0
- package/dist/validate-max-occurs.d.ts.map +1 -0
- package/dist/validate-max-occurs.js +28 -0
- package/dist/validate-max-occurs.js.map +1 -0
- package/dist/validation-types.d.ts +36 -0
- package/dist/validation-types.d.ts.map +1 -0
- package/dist/validation-types.js +7 -0
- package/dist/validation-types.js.map +1 -0
- package/package.json +33 -22
- package/src/attr-schema-validate.ts +108 -8
- 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-constants.ts +4 -0
- package/src/core/identity/identity-definition.embedded.ts +100 -0
- package/src/core/identity/meta-identity.ts +8 -1
- 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-constants.ts +22 -1
- package/src/core/validator/validator-definition.embedded.ts +262 -0
- package/src/core/yaml-desugar.ts +96 -7
- package/src/core-types.ts +314 -150
- package/src/errors.ts +89 -2
- 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 +78 -7
- package/src/loader/shortcuts.ts +2 -2
- package/src/loader/validation-passes.ts +690 -34
- package/src/loader/validation-registry.ts +93 -0
- 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 +96 -9
- package/src/persistence/db/db-constants.ts +16 -0
- package/src/persistence/db/db-definition.embedded.ts +234 -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 +463 -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 +106 -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/validate-max-occurs.ts +39 -0
- package/src/validation-types.ts +57 -0
- package/dist/core/documentation/doc-schema.d.ts +0 -8
- package/dist/core/documentation/doc-schema.d.ts.map +0 -1
- package/dist/core/documentation/doc-schema.js +0 -53
- package/dist/core/documentation/doc-schema.js.map +0 -1
- package/dist/core/field/field-schema.d.ts +0 -22
- package/dist/core/field/field-schema.d.ts.map +0 -1
- package/dist/core/field/field-schema.js +0 -171
- package/dist/core/field/field-schema.js.map +0 -1
- package/dist/core/identity/identity-schema.d.ts +0 -6
- package/dist/core/identity/identity-schema.d.ts.map +0 -1
- package/dist/core/identity/identity-schema.js +0 -55
- package/dist/core/identity/identity-schema.js.map +0 -1
- package/dist/core/object/object-schema.d.ts +0 -4
- package/dist/core/object/object-schema.d.ts.map +0 -1
- package/dist/core/object/object-schema.js +0 -28
- package/dist/core/object/object-schema.js.map +0 -1
- package/dist/core/relationship/relationship-schema.d.ts +0 -4
- package/dist/core/relationship/relationship-schema.d.ts.map +0 -1
- package/dist/core/relationship/relationship-schema.js +0 -51
- package/dist/core/relationship/relationship-schema.js.map +0 -1
- package/dist/core/validator/validator-schema.d.ts +0 -4
- package/dist/core/validator/validator-schema.d.ts.map +0 -1
- package/dist/core/validator/validator-schema.js +0 -38
- package/dist/core/validator/validator-schema.js.map +0 -1
- package/dist/persistence/db/db-schema.d.ts +0 -14
- package/dist/persistence/db/db-schema.d.ts.map +0 -1
- package/dist/persistence/db/db-schema.js +0 -35
- package/dist/persistence/db/db-schema.js.map +0 -1
- package/dist/persistence/origin/origin-schema.d.ts +0 -4
- package/dist/persistence/origin/origin-schema.d.ts.map +0 -1
- package/dist/persistence/origin/origin-schema.js +0 -59
- package/dist/persistence/origin/origin-schema.js.map +0 -1
- package/dist/persistence/source/source-schema.d.ts +0 -4
- package/dist/persistence/source/source-schema.d.ts.map +0 -1
- package/dist/persistence/source/source-schema.js +0 -98
- package/dist/persistence/source/source-schema.js.map +0 -1
- package/dist/presentation/layout/layout-schema.d.ts +0 -4
- package/dist/presentation/layout/layout-schema.d.ts.map +0 -1
- package/dist/presentation/layout/layout-schema.js +0 -46
- package/dist/presentation/layout/layout-schema.js.map +0 -1
- package/dist/presentation/view/view-schema.d.ts +0 -4
- package/dist/presentation/view/view-schema.d.ts.map +0 -1
- package/dist/presentation/view/view-schema.js +0 -15
- package/dist/presentation/view/view-schema.js.map +0 -1
- package/dist/template/template-schema.d.ts +0 -3
- package/dist/template/template-schema.d.ts.map +0 -1
- package/dist/template/template-schema.js +0 -173
- package/dist/template/template-schema.js.map +0 -1
- 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,334 @@
|
|
|
1
|
+
// SP-G Registry Conformance — the TS reference emitter.
|
|
2
|
+
//
|
|
3
|
+
// Walks an assembled core TypeRegistry and serializes the LOGICAL metamodel
|
|
4
|
+
// vocabulary as a canonical, fully-sorted, byte-stable JSON manifest. This is
|
|
5
|
+
// the single-source contract the other four ports (C#, Java, Kotlin, Python)
|
|
6
|
+
// must byte-match — a structural gate against the SP-C class of silent
|
|
7
|
+
// vocabulary drift (a port's registry diverging — wrong attr names, missing
|
|
8
|
+
// subtypes, different required-ness — with every behavioral corpus still green).
|
|
9
|
+
//
|
|
10
|
+
// The IN/OUT boundary is documented in fixtures/registry-conformance/README.md.
|
|
11
|
+
// In short, the manifest emits: type.subType + per-type/per-attr `description`
|
|
12
|
+
// (FR-033) + attrs[{name, valueType, isArray, required, description, rules?,
|
|
13
|
+
// example?, whenToUse?}] + the structural constraint graph (children / parents /
|
|
14
|
+
// cardinality, FR-033) + commonAttrs + defaultSubTypes. EXCLUDED (per-port-
|
|
15
|
+
// physical or not-universally-tracked-on-the-registry): factories/native
|
|
16
|
+
// bindings; AttrSchema.default and allowedValues (Java's attr model —
|
|
17
|
+
// ChildRequirement — carries neither).
|
|
18
|
+
//
|
|
19
|
+
// FR-033 Task 5 GREW the manifest: it now also emits the documentation surface
|
|
20
|
+
// (every type/attr carries a required, non-empty `description`; optional `rules`/
|
|
21
|
+
// `example`/`whenToUse`) AND the full structural constraint graph (each type's
|
|
22
|
+
// `children` from childRules — childType/childSubType/childName + optional
|
|
23
|
+
// cardinality min/max/named — and optional `parents`). Growing the canonical
|
|
24
|
+
// RED-flags the other four ports' registry-conformance until they reconcile
|
|
25
|
+
// (the intended intermediate state, same as the FR-032 sweep).
|
|
26
|
+
|
|
27
|
+
import type { AttrSchema, ChildRule, TypeDefinition, TypeRegistry } from "./registry.js";
|
|
28
|
+
import { ATTR_SUBTYPE_STRING, ATTR_SUBTYPE_STRINGARRAY } from "./core/attr/attr-constants.js";
|
|
29
|
+
import {
|
|
30
|
+
EXCLUDED_PER_TYPE_ATTRS,
|
|
31
|
+
ExclusionReason,
|
|
32
|
+
isExcludedTypeSubType,
|
|
33
|
+
manifestRequiredOverride,
|
|
34
|
+
} from "./registry-manifest-exclusions.js";
|
|
35
|
+
|
|
36
|
+
/** One attribute in the manifest — the logical, cross-port-identical facet. */
|
|
37
|
+
interface ManifestAttr {
|
|
38
|
+
name: string;
|
|
39
|
+
/** The attr's SCALAR value-type subtype, or null for a polymorphic/untyped attr (e.g. @default). */
|
|
40
|
+
valueType: string | null;
|
|
41
|
+
/** True for an array-valued attr (a list of the scalar `valueType`); the orthogonal array axis. */
|
|
42
|
+
isArray: boolean;
|
|
43
|
+
required: boolean;
|
|
44
|
+
/** FR-033 — human/AI-facing description of the attribute (required, non-empty). */
|
|
45
|
+
description: string;
|
|
46
|
+
/** FR-033 — prose documenting the complex rules enforced in code. Emitted only when present. */
|
|
47
|
+
rules?: string;
|
|
48
|
+
/** FR-033 — an example value. Emitted only when present. */
|
|
49
|
+
example?: string;
|
|
50
|
+
/** FR-033 — guidance on when to reach for this attribute. Emitted only when present. */
|
|
51
|
+
whenToUse?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** One structural child rule of a type (FR-033 constraint graph). */
|
|
55
|
+
interface ManifestChild {
|
|
56
|
+
/** The admitted child `type` (`"*"` = any). */
|
|
57
|
+
childType: string;
|
|
58
|
+
/** The admitted child subType — a single subtype, `"*"` (any), or a list of admitted subtypes. */
|
|
59
|
+
childSubType: string | readonly string[];
|
|
60
|
+
/** The admitted child name (`"*"` = any). */
|
|
61
|
+
childName: string;
|
|
62
|
+
/** Cardinality lower bound — emitted only when defined on the rule. */
|
|
63
|
+
min?: number;
|
|
64
|
+
/** Cardinality upper bound (`null` = unbounded) — emitted only when defined on the rule. */
|
|
65
|
+
max?: number | null;
|
|
66
|
+
/** Whether the child must carry an explicit name — emitted only when defined on the rule. */
|
|
67
|
+
named?: boolean;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** One registered (type, subType) in the manifest, with its docs + attrs + constraint graph. */
|
|
71
|
+
interface ManifestType {
|
|
72
|
+
type: string;
|
|
73
|
+
subType: string;
|
|
74
|
+
/** FR-033 — human/AI-facing description of the type/subType (required, non-empty). */
|
|
75
|
+
description: string;
|
|
76
|
+
/** FR-033 — prose documenting the complex rules enforced in code. Emitted only when present. */
|
|
77
|
+
rules?: string;
|
|
78
|
+
/** FR-033 — an example. Emitted only when present. */
|
|
79
|
+
example?: string;
|
|
80
|
+
/** FR-033 — guidance on when to reach for this type/subType. Emitted only when present. */
|
|
81
|
+
whenToUse?: string;
|
|
82
|
+
attrs: ManifestAttr[];
|
|
83
|
+
/** FR-033 — the type's structural child rules (sorted), the constraint graph. */
|
|
84
|
+
children: ManifestChild[];
|
|
85
|
+
/** FR-033 — the child-side placement claim (sorted). Emitted only when present + non-empty. */
|
|
86
|
+
parents?: string[];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** The full canonical manifest. All collections are sorted for byte-stability. */
|
|
90
|
+
interface RegistryManifest {
|
|
91
|
+
types: ManifestType[];
|
|
92
|
+
commonAttrs: ManifestAttr[];
|
|
93
|
+
defaultSubTypes: Record<string, string>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** ASCII-string compare so the sort is locale-independent and byte-stable across ports. */
|
|
97
|
+
function compareStrings(a: string, b: string): number {
|
|
98
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Normalize one AttrSchema to the manifest's logical attr shape — decomposing
|
|
103
|
+
* array-ness into a scalar `valueType` + an orthogonal `isArray` flag.
|
|
104
|
+
*
|
|
105
|
+
* An attr is array-valued when its schema sets `isArray: true` (the cross-port
|
|
106
|
+
* model). For resilience, a legacy `valueType: "stringarray"` token is also
|
|
107
|
+
* decomposed to `{ valueType: "string", isArray: true }` — so no `stringarray`
|
|
108
|
+
* token ever reaches the manifest. A polymorphic attr (no valueType) is `null` +
|
|
109
|
+
* non-array.
|
|
110
|
+
*/
|
|
111
|
+
function toManifestAttr(attr: AttrSchema): ManifestAttr {
|
|
112
|
+
const isLegacyStringArray = attr.valueType === ATTR_SUBTYPE_STRINGARRAY;
|
|
113
|
+
const isArray = attr.isArray === true || isLegacyStringArray;
|
|
114
|
+
// The scalar value-type: a legacy stringarray token collapses to "string";
|
|
115
|
+
// otherwise the declared valueType (omitted → null for polymorphic attrs).
|
|
116
|
+
const valueType = isLegacyStringArray
|
|
117
|
+
? ATTR_SUBTYPE_STRING
|
|
118
|
+
: (attr.valueType ?? null);
|
|
119
|
+
// FR-033: the documentation surface (`description` required + non-empty;
|
|
120
|
+
// `rules`/`example`/`whenToUse` emitted ONLY when present) follows the
|
|
121
|
+
// existing facets, preserving key order for byte-stability.
|
|
122
|
+
const out: ManifestAttr = {
|
|
123
|
+
name: attr.name,
|
|
124
|
+
valueType,
|
|
125
|
+
isArray,
|
|
126
|
+
required: attr.required,
|
|
127
|
+
description: attr.description,
|
|
128
|
+
};
|
|
129
|
+
if (attr.rules !== undefined) out.rules = attr.rules;
|
|
130
|
+
if (attr.example !== undefined) out.example = attr.example;
|
|
131
|
+
if (attr.whenToUse !== undefined) out.whenToUse = attr.whenToUse;
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** The canonical sort key for a child rule: childType, then the childSubType
|
|
136
|
+
* string (or comma-joined list), then childName — ASCII codepoint compare. */
|
|
137
|
+
function childSubTypeKey(childSubType: string | readonly string[]): string {
|
|
138
|
+
return Array.isArray(childSubType) ? childSubType.join(",") : (childSubType as string);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Normalize one structural ChildRule to the manifest's child shape (FR-033).
|
|
143
|
+
* Cardinality (`min`/`max`/`named`) is emitted ONLY when defined on the rule —
|
|
144
|
+
* legacy wildcard rules leave them undefined and must NOT fabricate cardinality.
|
|
145
|
+
* `max` may legitimately be `null` (unbounded); `null` is emitted, `undefined`
|
|
146
|
+
* is omitted.
|
|
147
|
+
*/
|
|
148
|
+
function toManifestChild(rule: ChildRule): ManifestChild {
|
|
149
|
+
const out: ManifestChild = {
|
|
150
|
+
childType: rule.childType,
|
|
151
|
+
childSubType: rule.childSubType,
|
|
152
|
+
childName: rule.childName,
|
|
153
|
+
};
|
|
154
|
+
if (rule.min !== undefined) out.min = rule.min;
|
|
155
|
+
if (rule.max !== undefined) out.max = rule.max;
|
|
156
|
+
if (rule.named !== undefined) out.named = rule.named;
|
|
157
|
+
return out;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Sort the constraint graph by (childType, childSubTypeKey, childName) — ASCII. */
|
|
161
|
+
function sortedChildren(rules: readonly ChildRule[]): ManifestChild[] {
|
|
162
|
+
return rules
|
|
163
|
+
.map(toManifestChild)
|
|
164
|
+
.sort(
|
|
165
|
+
(a, b) =>
|
|
166
|
+
compareStrings(a.childType, b.childType) ||
|
|
167
|
+
compareStrings(childSubTypeKey(a.childSubType), childSubTypeKey(b.childSubType)) ||
|
|
168
|
+
compareStrings(a.childName, b.childName),
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** Sort attrs by name (ascending, ASCII). */
|
|
173
|
+
function sortedAttrs(attrs: readonly AttrSchema[]): ManifestAttr[] {
|
|
174
|
+
return attrs
|
|
175
|
+
.map(toManifestAttr)
|
|
176
|
+
.sort((a, b) => compareStrings(a.name, b.name));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Sort PER-TYPE attrs, keeping only those the explicit classification marks
|
|
181
|
+
* INCLUDED (logical cross-port vocabulary). A per-type attr classified with any
|
|
182
|
+
* `ExclusionReason` (structural keyword, native binding, per-type `description`
|
|
183
|
+
* commonAttr dup) is carved out — for a documented reason, never a silent
|
|
184
|
+
* name-match. The filter is a no-op for TS (which never registers the carved-out
|
|
185
|
+
* names as per-type attrs); it is applied uniformly so the cross-port contract
|
|
186
|
+
* is explicit. NOTE: `description` is filtered ONLY here — it remains in the
|
|
187
|
+
* `commonAttrs` block (built via `sortedAttrs`, unfiltered).
|
|
188
|
+
*/
|
|
189
|
+
function sortedPerTypeAttrs(
|
|
190
|
+
attrs: readonly AttrSchema[],
|
|
191
|
+
type: string,
|
|
192
|
+
subType: string,
|
|
193
|
+
): ManifestAttr[] {
|
|
194
|
+
return sortedAttrs(attrs.filter((a) => classifyPerTypeAttr(a.name) === INCLUDED)).map(
|
|
195
|
+
(attr) => {
|
|
196
|
+
// FR-024-pending requiredness override (the attr-level analogue of the
|
|
197
|
+
// Fr024Pending row carve-out): the TS registry already registers the
|
|
198
|
+
// FR-024 requiredness, but the manifest keeps emitting the pre-FR-024
|
|
199
|
+
// agreed value until the Phase-E atomic all-ports flip.
|
|
200
|
+
const required = manifestRequiredOverride(type, subType, attr.name);
|
|
201
|
+
return required === undefined ? attr : { ...attr, required };
|
|
202
|
+
},
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* The boundary classifier (Wave 3b). For every per-type attr the emitter
|
|
208
|
+
* encounters, the in/out decision is an EXPLICIT classification — never a silent
|
|
209
|
+
* default. Returns either an `ExclusionReason` (carved out, with a documented
|
|
210
|
+
* category) or `INCLUDED` (logical cross-port vocabulary). It is TOTAL: there is
|
|
211
|
+
* no "unclassified" third state, so a port can never silently let an unreasoned
|
|
212
|
+
* facet through — the self-documenting property the conformance test asserts.
|
|
213
|
+
*
|
|
214
|
+
* This replaces the prior tautology — a bare `EXCLUDED.has(name)` whose negative
|
|
215
|
+
* branch silently meant "logical". The decision is now centralized and reasoned;
|
|
216
|
+
* the cross-port byte-canonical + ADR-0023 (sealed agreed-vocabulary registry)
|
|
217
|
+
* together guarantee that an `INCLUDED` attr really is agreed vocabulary rather
|
|
218
|
+
* than an accidental registration, so inclusion-by-classification is sound.
|
|
219
|
+
*
|
|
220
|
+
* NOTE on liveness: a per-type attr exclusion (e.g. `extends`, `object`) is a
|
|
221
|
+
* CROSS-PORT carve-out that only the OO ports (Java/Kotlin) physically register;
|
|
222
|
+
* TS/C#/Python never register those names, so a single port's emitter cannot
|
|
223
|
+
* judge a carve-out "dead" — that is a cross-port property, asserted by the
|
|
224
|
+
* shared byte-canonical, not here.
|
|
225
|
+
*/
|
|
226
|
+
const INCLUDED = "included" as const;
|
|
227
|
+
export type AttrClassification = ExclusionReason | typeof INCLUDED;
|
|
228
|
+
|
|
229
|
+
export function classifyPerTypeAttr(name: string): AttrClassification {
|
|
230
|
+
return EXCLUDED_PER_TYPE_ATTRS.get(name) ?? INCLUDED;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Build one manifest type entry from its full TypeDefinition (FR-033). Key order
|
|
235
|
+
* is fixed for byte-stability: `type`, `subType`, `description`, then optional
|
|
236
|
+
* `rules`/`example`/`whenToUse` (emitted only when present), then `attrs`,
|
|
237
|
+
* `children` (the sorted constraint graph), and optional `parents` (emitted only
|
|
238
|
+
* when present + non-empty, sorted ASCII).
|
|
239
|
+
*/
|
|
240
|
+
function toManifestType(def: TypeDefinition): ManifestType {
|
|
241
|
+
// Build in fixed key order. Optional docs facets (rules/example/whenToUse) sit
|
|
242
|
+
// between `description` and `attrs`, so they are spread into the literal (when
|
|
243
|
+
// present) to preserve insertion order — `attrs`/`children`/`parents` follow.
|
|
244
|
+
const out: ManifestType = {
|
|
245
|
+
type: def.typeId.type,
|
|
246
|
+
subType: def.typeId.subType,
|
|
247
|
+
description: def.description,
|
|
248
|
+
...(def.rules !== undefined ? { rules: def.rules } : {}),
|
|
249
|
+
...(def.example !== undefined ? { example: def.example } : {}),
|
|
250
|
+
...(def.whenToUse !== undefined ? { whenToUse: def.whenToUse } : {}),
|
|
251
|
+
attrs: sortedPerTypeAttrs(def.attributes, def.typeId.type, def.typeId.subType),
|
|
252
|
+
children: sortedChildren(def.childRules),
|
|
253
|
+
};
|
|
254
|
+
if (def.parents !== undefined && def.parents.length > 0) {
|
|
255
|
+
out.parents = [...def.parents].sort(compareStrings);
|
|
256
|
+
}
|
|
257
|
+
return out;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Build the canonical registry manifest object from an assembled registry.
|
|
262
|
+
*
|
|
263
|
+
* The registry must already be composed (e.g. `composeRegistry(coreProviders)`)
|
|
264
|
+
* so all providers — core types, db-domain attrs, common doc attrs — have run.
|
|
265
|
+
*/
|
|
266
|
+
export function buildRegistryManifest(registry: TypeRegistry): RegistryManifest {
|
|
267
|
+
// Walk every registered (type, subType). `allTypes()` returns the TypeIds;
|
|
268
|
+
// `find` gives each one's full TypeDefinition (description / attributes /
|
|
269
|
+
// childRules / parents / rules / example / whenToUse) in a single lookup.
|
|
270
|
+
const types: ManifestType[] = registry
|
|
271
|
+
.allTypes()
|
|
272
|
+
// Skip excluded (type, subType) rows: the `metadata.base` inheritance
|
|
273
|
+
// anchor (C-5) + the generic TS-presentation `view.*` controls (B-2).
|
|
274
|
+
.filter((typeId) => !isExcludedTypeSubType(typeId.type, typeId.subType))
|
|
275
|
+
.map((typeId) =>
|
|
276
|
+
toManifestType(
|
|
277
|
+
// The type IS registered (it came from allTypes()), so find() is defined.
|
|
278
|
+
registry.find(typeId.type, typeId.subType) as TypeDefinition,
|
|
279
|
+
),
|
|
280
|
+
)
|
|
281
|
+
// Sort by the full "type.subType" key for a stable, port-independent order.
|
|
282
|
+
.sort((a, b) =>
|
|
283
|
+
compareStrings(`${a.type}.${a.subType}`, `${b.type}.${b.subType}`),
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
const commonAttrs = sortedAttrs(registry.getCommonAttrs());
|
|
287
|
+
|
|
288
|
+
// defaultSubTypes: rebuild with sorted keys so JSON.stringify emits a stable
|
|
289
|
+
// key order. There is no public "all default subTypes" accessor, so derive
|
|
290
|
+
// the candidate type names from the registered types and probe each.
|
|
291
|
+
const typeNames = Array.from(new Set(types.map((t) => t.type))).sort(
|
|
292
|
+
compareStrings,
|
|
293
|
+
);
|
|
294
|
+
const defaultSubTypes: Record<string, string> = {};
|
|
295
|
+
for (const typeName of typeNames) {
|
|
296
|
+
const defaultSub = registry.defaultSubTypeOf(typeName);
|
|
297
|
+
if (defaultSub !== undefined) {
|
|
298
|
+
defaultSubTypes[typeName] = defaultSub;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return { types, commonAttrs, defaultSubTypes };
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Emit the canonical registry manifest as a byte-stable JSON string.
|
|
307
|
+
*
|
|
308
|
+
* Serialization contract — every port MUST match this exactly:
|
|
309
|
+
* - 2-space indentation (JSON.stringify(_, _, 2)).
|
|
310
|
+
* - Object keys in a fixed order (JSON.stringify preserves insertion order):
|
|
311
|
+
* the manifest is built with `types`, `commonAttrs`, `defaultSubTypes`.
|
|
312
|
+
* - Each attr: `name`, `valueType`, `isArray`, `required`, `description`,
|
|
313
|
+
* then optional `rules`, `example`, `whenToUse` (each omitted when absent).
|
|
314
|
+
* - Each type: `type`, `subType`, `description`, then optional `rules`,
|
|
315
|
+
* `example`, `whenToUse` (omitted when absent), then `attrs`, `children`,
|
|
316
|
+
* then optional `parents` (omitted when absent/empty).
|
|
317
|
+
* - Each child (FR-033 constraint graph): `childType`, `childSubType`,
|
|
318
|
+
* `childName`, then optional `min`, `max`, `named` (each emitted ONLY when
|
|
319
|
+
* defined on the rule — legacy wildcard rules omit all three; `max: null`
|
|
320
|
+
* is emitted when the rule sets it null, omitted when undefined).
|
|
321
|
+
* - All arrays sorted: `types` by "type.subType"; each `attrs` by name;
|
|
322
|
+
* each type's `children` by the tuple (childType, childSubTypeKey, childName)
|
|
323
|
+
* where childSubTypeKey is the string or the comma-joined list; `parents`
|
|
324
|
+
* ascending; `commonAttrs` by name; `defaultSubTypes` keys sorted.
|
|
325
|
+
* - `valueType: null` literal for polymorphic/untyped attrs.
|
|
326
|
+
* - `childSubType` is a string OR a string[] (a list of admitted subtypes).
|
|
327
|
+
* - `description` is required + non-empty on every type and attr (gated by the
|
|
328
|
+
* coverage assertion in registry-conformance.test.ts — mirrors ADR-0023).
|
|
329
|
+
* - A single trailing newline (matches the repo's committed-canonical style).
|
|
330
|
+
*/
|
|
331
|
+
export function emitRegistryManifest(registry: TypeRegistry): string {
|
|
332
|
+
const manifest = buildRegistryManifest(registry);
|
|
333
|
+
return `${JSON.stringify(manifest, null, 2)}\n`;
|
|
334
|
+
}
|
package/src/registry.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { SUBTYPE_BASE, TYPE_ATTR } from "./shared/base-types.js";
|
|
|
3
3
|
import { CHILD_RULE_WILDCARD } from "./shared/structural.js";
|
|
4
4
|
import { type AttrSubType } from "./core/attr/attr-constants.js";
|
|
5
5
|
import type { DataType } from "./data-type.js";
|
|
6
|
+
import type { ReferenceDescriptor, NodeValidator } from "./validation-types.js";
|
|
6
7
|
import { MetaModelError } from "./errors.js";
|
|
7
8
|
|
|
8
9
|
export class TypeId {
|
|
@@ -23,10 +24,25 @@ export class TypeId {
|
|
|
23
24
|
export interface ChildRule {
|
|
24
25
|
/** `"*"` matches any type. */
|
|
25
26
|
childType: string;
|
|
26
|
-
/**
|
|
27
|
-
|
|
27
|
+
/**
|
|
28
|
+
* `"*"` matches any subtype. A list (FR-033) admits any one of several
|
|
29
|
+
* subtypes (e.g. a `source` child may be `["rdb", "view"]`).
|
|
30
|
+
*/
|
|
31
|
+
childSubType: string | readonly string[];
|
|
28
32
|
/** `"*"` matches any name. */
|
|
29
33
|
childName: string;
|
|
34
|
+
/**
|
|
35
|
+
* FR-033 — cardinality lower bound. A required child has `min >= 1`. Optional
|
|
36
|
+
* on the interface for back-compat with rules authored before FR-033.
|
|
37
|
+
*/
|
|
38
|
+
min?: number;
|
|
39
|
+
/**
|
|
40
|
+
* FR-033 — cardinality upper bound; `null` means unbounded (0..∞). Optional
|
|
41
|
+
* for back-compat.
|
|
42
|
+
*/
|
|
43
|
+
max?: number | null;
|
|
44
|
+
/** FR-033 — whether the child must carry an explicit name. */
|
|
45
|
+
named?: boolean;
|
|
30
46
|
}
|
|
31
47
|
|
|
32
48
|
export interface AttrSchema {
|
|
@@ -45,6 +61,16 @@ export interface AttrSchema {
|
|
|
45
61
|
* attrs. Attempting to register an AttrSchema with `valueType: "base"` throws.
|
|
46
62
|
*/
|
|
47
63
|
valueType?: AttrSubType;
|
|
64
|
+
/**
|
|
65
|
+
* Whether this attribute is array-valued (a list of the scalar `valueType`).
|
|
66
|
+
*
|
|
67
|
+
* Array-ness is a single orthogonal axis — a `string` attr with `isArray: true`
|
|
68
|
+
* is what was formerly the `stringarray` subtype. The loader coerces an
|
|
69
|
+
* array-flagged attr through the array string-attr coercion (bare-string →
|
|
70
|
+
* one-element array). Mirrors Java's `StringAttribute + @isArray` model.
|
|
71
|
+
* Absent/false = scalar.
|
|
72
|
+
*/
|
|
73
|
+
isArray?: boolean;
|
|
48
74
|
/** Whether this attribute must be present on the node. */
|
|
49
75
|
required: boolean;
|
|
50
76
|
/** Default value applied when the attribute is absent. Optional. */
|
|
@@ -53,6 +79,12 @@ export interface AttrSchema {
|
|
|
53
79
|
allowedValues?: readonly AttrValue[];
|
|
54
80
|
/** Human/AI-facing description of what the attribute means. */
|
|
55
81
|
description: string;
|
|
82
|
+
/** FR-033 — prose documenting the complex rules enforced in code. Optional. */
|
|
83
|
+
rules?: string;
|
|
84
|
+
/** FR-033 — an example value, shown only in the provider detail page. Optional. */
|
|
85
|
+
example?: string;
|
|
86
|
+
/** FR-033 — guidance on when to reach for this attribute. Optional. */
|
|
87
|
+
whenToUse?: string;
|
|
56
88
|
}
|
|
57
89
|
|
|
58
90
|
export interface TypeDefinition {
|
|
@@ -64,6 +96,33 @@ export interface TypeDefinition {
|
|
|
64
96
|
/** The coarse value-type classification, for (type, subType)s whose nodes
|
|
65
97
|
* carry a typed value (field, attr). Absent for non-value-bearing types. */
|
|
66
98
|
dataType?: DataType;
|
|
99
|
+
/**
|
|
100
|
+
* FR-033 — the child-side placement claim: the `type.subType`s under which a
|
|
101
|
+
* node of this type is allowed. Additive (an extension provider names a parent
|
|
102
|
+
* without editing the parent's definition). Optional.
|
|
103
|
+
*/
|
|
104
|
+
parents?: readonly string[];
|
|
105
|
+
/** FR-033 — prose documenting the complex rules enforced in code. Optional. */
|
|
106
|
+
rules?: string;
|
|
107
|
+
/** FR-033 — an example, shown only in the provider detail page. Optional. */
|
|
108
|
+
example?: string;
|
|
109
|
+
/** FR-033 — guidance on when to reach for this type/subType. Optional. */
|
|
110
|
+
whenToUse?: string;
|
|
111
|
+
/** Max children of this type.subType per parent (`1` = singleton). Loader-enforced. */
|
|
112
|
+
maxOccurs?: number;
|
|
113
|
+
/** Default name for a singleton (`maxOccurs===1`) child declared with no name. */
|
|
114
|
+
defaultName?: string;
|
|
115
|
+
/**
|
|
116
|
+
* Cross-references this node's attrs declare — resolved generically against the symbol
|
|
117
|
+
* table (a dangling/kind-mismatched target fails the load). Carried by the type's
|
|
118
|
+
* registration, so a downstream provider's references validate with no core changes.
|
|
119
|
+
*/
|
|
120
|
+
references?: ReferenceDescriptor[];
|
|
121
|
+
/**
|
|
122
|
+
* The type's imperative validator (logic config can't express). Invoked by the recursive
|
|
123
|
+
* validation walk. Owned by the provider that owns the type.
|
|
124
|
+
*/
|
|
125
|
+
validate?: NodeValidator;
|
|
67
126
|
}
|
|
68
127
|
|
|
69
128
|
export class TypeRegistry {
|
|
@@ -79,7 +138,41 @@ export class TypeRegistry {
|
|
|
79
138
|
/** Attrs accepted on every metatype (declared by providers). */
|
|
80
139
|
private readonly _commonAttrs: AttrSchema[] = [];
|
|
81
140
|
|
|
141
|
+
/**
|
|
142
|
+
* ADR-0023 Decision 2 — sealed state. Once sealed, every mutating registration
|
|
143
|
+
* method (`register`/`setDefaultSubType`/`registerCommonAttrs`/`extend`) throws
|
|
144
|
+
* `ERR_REGISTRY_SEALED`. The library seals its composed registry after the agreed
|
|
145
|
+
* metamodel providers bootstrap, so nothing can register made-up metamodel
|
|
146
|
+
* attributes post-bootstrap. A downstream app composes its own (unsealed) registry.
|
|
147
|
+
*/
|
|
148
|
+
private _sealed = false;
|
|
149
|
+
|
|
150
|
+
/** Seal the registry: every subsequent mutating registration throws
|
|
151
|
+
* `ERR_REGISTRY_SEALED`. Idempotent. Reads are unaffected. */
|
|
152
|
+
seal(): void {
|
|
153
|
+
this._sealed = true;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Whether this registry has been sealed (ADR-0023). */
|
|
157
|
+
isSealed(): boolean {
|
|
158
|
+
return this._sealed;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Guard at the top of every mutating registration method. */
|
|
162
|
+
private checkNotSealed(operation: string): void {
|
|
163
|
+
if (this._sealed) {
|
|
164
|
+
throw new MetaModelError(
|
|
165
|
+
`TypeRegistry is sealed (ADR-0023): ${operation} is not permitted after metamodel ` +
|
|
166
|
+
`bootstrap. Made-up metamodel attributes/types are structurally disallowed — a new ` +
|
|
167
|
+
`metamodel attribute requires a registered provider + human agreement. Downstream apps ` +
|
|
168
|
+
`that need extra vocabulary must compose their own (unsealed) registry.`,
|
|
169
|
+
{ code: "ERR_REGISTRY_SEALED" },
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
82
174
|
register(def: TypeDefinition): void {
|
|
175
|
+
this.checkNotSealed(`register("${def.typeId.toString()}")`);
|
|
83
176
|
const key = def.typeId.toString();
|
|
84
177
|
if (this._defs.has(key)) {
|
|
85
178
|
throw new Error(
|
|
@@ -129,6 +222,7 @@ export class TypeRegistry {
|
|
|
129
222
|
|
|
130
223
|
/** Designate the default subType for a bare `type` key (used by YAML authoring sugar). */
|
|
131
224
|
setDefaultSubType(type: string, subType: string): void {
|
|
225
|
+
this.checkNotSealed(`setDefaultSubType("${type}")`);
|
|
132
226
|
this._defaultSubTypes.set(type, subType);
|
|
133
227
|
}
|
|
134
228
|
|
|
@@ -150,6 +244,7 @@ export class TypeRegistry {
|
|
|
150
244
|
* per-type attrs are resolved at validation time (Task 1.3).
|
|
151
245
|
*/
|
|
152
246
|
registerCommonAttrs(attrs: AttrSchema[]): void {
|
|
247
|
+
this.checkNotSealed("registerCommonAttrs");
|
|
153
248
|
for (const attr of attrs) {
|
|
154
249
|
if (attr.valueType === SUBTYPE_BASE) {
|
|
155
250
|
throw new Error(
|
|
@@ -182,6 +277,7 @@ export class TypeRegistry {
|
|
|
182
277
|
subType: string,
|
|
183
278
|
ext: { attributes?: AttrSchema[]; childRules?: ChildRule[] },
|
|
184
279
|
): void {
|
|
280
|
+
this.checkNotSealed(`extend("${type}.${subType}")`);
|
|
185
281
|
const def = this.find(type, subType);
|
|
186
282
|
if (def === undefined) {
|
|
187
283
|
throw new Error(
|
|
@@ -213,9 +309,16 @@ export function childRuleMatches(
|
|
|
213
309
|
rule: ChildRule,
|
|
214
310
|
child: { type: string; subType: string; name: string },
|
|
215
311
|
): boolean {
|
|
312
|
+
// FR-033 — childSubType may be a wildcard, a single subtype, or a list of
|
|
313
|
+
// admitted subtypes.
|
|
314
|
+
const subTypeMatches =
|
|
315
|
+
rule.childSubType === CHILD_RULE_WILDCARD ||
|
|
316
|
+
(Array.isArray(rule.childSubType)
|
|
317
|
+
? rule.childSubType.includes(child.subType)
|
|
318
|
+
: rule.childSubType === child.subType);
|
|
216
319
|
return (
|
|
217
320
|
(rule.childType === CHILD_RULE_WILDCARD || rule.childType === child.type) &&
|
|
218
|
-
|
|
321
|
+
subTypeMatches &&
|
|
219
322
|
(rule.childName === CHILD_RULE_WILDCARD || rule.childName === child.name)
|
|
220
323
|
);
|
|
221
324
|
}
|
package/src/shared/structural.ts
CHANGED
|
@@ -52,6 +52,14 @@ export const TYPE_SUBTYPE_SEPARATOR = ".";
|
|
|
52
52
|
/** Separator between package segments and between package and name. */
|
|
53
53
|
export const PACKAGE_SEPARATOR = "::";
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* FR-024 (ADR-0029): separator between an owner object and a nested child in a
|
|
57
|
+
* dotted `extends` reference (`Customer.id`, `acme::sales::Customer.id`).
|
|
58
|
+
* Names cannot contain `.`, so a `.` in the final `::`-segment of a ref
|
|
59
|
+
* unambiguously marks a child-targeting reference.
|
|
60
|
+
*/
|
|
61
|
+
export const CHILD_REF_SEPARATOR = ".";
|
|
62
|
+
|
|
55
63
|
/** Relative-reference "go up one level" marker. */
|
|
56
64
|
export const PACKAGE_PARENT = "..";
|
|
57
65
|
|