@metaobjectsdev/metadata 0.5.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/LICENSE +189 -0
- package/README.md +29 -0
- package/dist/attr-class-map.d.ts +26 -0
- package/dist/attr-class-map.d.ts.map +1 -0
- package/dist/attr-class-map.js +44 -0
- package/dist/attr-class-map.js.map +1 -0
- package/dist/attr-schema-validate.d.ts +9 -0
- package/dist/attr-schema-validate.d.ts.map +1 -0
- package/dist/attr-schema-validate.js +100 -0
- package/dist/attr-schema-validate.js.map +1 -0
- 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/core/attr/attr-constants.d.ts +12 -0
- package/dist/core/attr/attr-constants.d.ts.map +1 -0
- package/dist/core/attr/attr-constants.js +27 -0
- package/dist/core/attr/attr-constants.js.map +1 -0
- package/dist/core/attr/meta-attr-filter.d.ts +10 -0
- package/dist/core/attr/meta-attr-filter.d.ts.map +1 -0
- package/dist/core/attr/meta-attr-filter.js +56 -0
- package/dist/core/attr/meta-attr-filter.js.map +1 -0
- package/dist/core/attr/meta-attr-properties.d.ts +9 -0
- package/dist/core/attr/meta-attr-properties.d.ts.map +1 -0
- package/dist/core/attr/meta-attr-properties.js +22 -0
- package/dist/core/attr/meta-attr-properties.js.map +1 -0
- package/dist/core/attr/meta-attr-stringarray.d.ts +9 -0
- package/dist/core/attr/meta-attr-stringarray.d.ts.map +1 -0
- package/dist/core/attr/meta-attr-stringarray.js +29 -0
- package/dist/core/attr/meta-attr-stringarray.js.map +1 -0
- package/dist/core/attr/meta-attr.d.ts +37 -0
- package/dist/core/attr/meta-attr.d.ts.map +1 -0
- package/dist/core/attr/meta-attr.js +97 -0
- package/dist/core/attr/meta-attr.js.map +1 -0
- package/dist/core/export-json.d.ts +29 -0
- package/dist/core/export-json.d.ts.map +1 -0
- package/dist/core/export-json.js +45 -0
- package/dist/core/export-json.js.map +1 -0
- package/dist/core/field/field-constants.d.ts +40 -0
- package/dist/core/field/field-constants.d.ts.map +1 -0
- package/dist/core/field/field-constants.js +66 -0
- package/dist/core/field/field-constants.js.map +1 -0
- package/dist/core/field/field-schema.d.ts +6 -0
- package/dist/core/field/field-schema.d.ts.map +1 -0
- package/dist/core/field/field-schema.js +92 -0
- package/dist/core/field/field-schema.js.map +1 -0
- package/dist/core/field/meta-field.d.ts +50 -0
- package/dist/core/field/meta-field.d.ts.map +1 -0
- package/dist/core/field/meta-field.js +121 -0
- package/dist/core/field/meta-field.js.map +1 -0
- 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-constants.d.ts +19 -0
- package/dist/core/identity/identity-constants.d.ts.map +1 -0
- package/dist/core/identity/identity-constants.js +35 -0
- package/dist/core/identity/identity-constants.js.map +1 -0
- package/dist/core/identity/identity-schema.d.ts +6 -0
- package/dist/core/identity/identity-schema.d.ts.map +1 -0
- package/dist/core/identity/identity-schema.js +55 -0
- package/dist/core/identity/identity-schema.js.map +1 -0
- package/dist/core/identity/meta-identity.d.ts +71 -0
- package/dist/core/identity/meta-identity.d.ts.map +1 -0
- package/dist/core/identity/meta-identity.js +129 -0
- package/dist/core/identity/meta-identity.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +11 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/object/meta-object.d.ts +39 -0
- package/dist/core/object/meta-object.d.ts.map +1 -0
- package/dist/core/object/meta-object.js +80 -0
- package/dist/core/object/meta-object.js.map +1 -0
- package/dist/core/object/object-constants.d.ts +5 -0
- package/dist/core/object/object-constants.d.ts.map +1 -0
- package/dist/core/object/object-constants.js +18 -0
- package/dist/core/object/object-constants.js.map +1 -0
- package/dist/core/object/object-schema.d.ts +4 -0
- package/dist/core/object/object-schema.d.ts.map +1 -0
- package/dist/core/object/object-schema.js +5 -0
- package/dist/core/object/object-schema.js.map +1 -0
- package/dist/core/parser-yaml.d.ts +3 -0
- package/dist/core/parser-yaml.d.ts.map +1 -0
- package/dist/core/parser-yaml.js +39 -0
- package/dist/core/parser-yaml.js.map +1 -0
- package/dist/core/query/query-constants.d.ts +20 -0
- package/dist/core/query/query-constants.d.ts.map +1 -0
- package/dist/core/query/query-constants.js +56 -0
- package/dist/core/query/query-constants.js.map +1 -0
- package/dist/core/relationship/find-reference.d.ts +22 -0
- package/dist/core/relationship/find-reference.d.ts.map +1 -0
- package/dist/core/relationship/find-reference.js +29 -0
- package/dist/core/relationship/find-reference.js.map +1 -0
- package/dist/core/relationship/meta-relationship.d.ts +11 -0
- package/dist/core/relationship/meta-relationship.d.ts.map +1 -0
- package/dist/core/relationship/meta-relationship.js +27 -0
- package/dist/core/relationship/meta-relationship.js.map +1 -0
- package/dist/core/relationship/relationship-constants.d.ts +14 -0
- package/dist/core/relationship/relationship-constants.d.ts.map +1 -0
- package/dist/core/relationship/relationship-constants.js +28 -0
- package/dist/core/relationship/relationship-constants.js.map +1 -0
- package/dist/core/relationship/relationship-schema.d.ts +4 -0
- package/dist/core/relationship/relationship-schema.d.ts.map +1 -0
- package/dist/core/relationship/relationship-schema.js +37 -0
- package/dist/core/relationship/relationship-schema.js.map +1 -0
- package/dist/core/validator/meta-validator.d.ts +29 -0
- package/dist/core/validator/meta-validator.d.ts.map +1 -0
- package/dist/core/validator/meta-validator.js +49 -0
- package/dist/core/validator/meta-validator.js.map +1 -0
- package/dist/core/validator/validator-constants.d.ts +11 -0
- package/dist/core/validator/validator-constants.d.ts.map +1 -0
- package/dist/core/validator/validator-constants.js +25 -0
- package/dist/core/validator/validator-constants.js.map +1 -0
- package/dist/core/validator/validator-schema.d.ts +4 -0
- package/dist/core/validator/validator-schema.d.ts.map +1 -0
- package/dist/core/validator/validator-schema.js +38 -0
- package/dist/core/validator/validator-schema.js.map +1 -0
- package/dist/core/yaml-desugar.d.ts +10 -0
- package/dist/core/yaml-desugar.d.ts.map +1 -0
- package/dist/core/yaml-desugar.js +99 -0
- package/dist/core/yaml-desugar.js.map +1 -0
- 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 +20 -0
- package/dist/core-types.d.ts.map +1 -0
- package/dist/core-types.js +225 -0
- package/dist/core-types.js.map +1 -0
- package/dist/data-converter.d.ts +17 -0
- package/dist/data-converter.d.ts.map +1 -0
- package/dist/data-converter.js +117 -0
- package/dist/data-converter.js.map +1 -0
- package/dist/data-type.d.ts +15 -0
- package/dist/data-type.d.ts.map +1 -0
- package/dist/data-type.js +25 -0
- package/dist/data-type.js.map +1 -0
- 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 +26 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +59 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/loader/meta-data-loader.d.ts +87 -0
- package/dist/loader/meta-data-loader.d.ts.map +1 -0
- package/dist/loader/meta-data-loader.js +232 -0
- package/dist/loader/meta-data-loader.js.map +1 -0
- package/dist/loader/meta-data-source.d.ts +23 -0
- package/dist/loader/meta-data-source.d.ts.map +1 -0
- package/dist/loader/meta-data-source.js +20 -0
- package/dist/loader/meta-data-source.js.map +1 -0
- package/dist/loader/validation-passes.d.ts +7 -0
- package/dist/loader/validation-passes.d.ts.map +1 -0
- package/dist/loader/validation-passes.js +244 -0
- package/dist/loader/validation-passes.js.map +1 -0
- 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/naming.d.ts +27 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/naming.js +72 -0
- package/dist/naming.js.map +1 -0
- package/dist/object-serializer.d.ts +10 -0
- package/dist/object-serializer.d.ts.map +1 -0
- package/dist/object-serializer.js +128 -0
- package/dist/object-serializer.js.map +1 -0
- package/dist/overlay.d.ts +2 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +6 -0
- package/dist/overlay.js.map +1 -0
- package/dist/parser-core.d.ts +47 -0
- package/dist/parser-core.d.ts.map +1 -0
- package/dist/parser-core.js +516 -0
- package/dist/parser-core.js.map +1 -0
- package/dist/parser-json.d.ts +4 -0
- package/dist/parser-json.d.ts.map +1 -0
- package/dist/parser-json.js +19 -0
- package/dist/parser-json.js.map +1 -0
- 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-constants.d.ts +5 -0
- package/dist/persistence/db/db-constants.d.ts.map +1 -0
- package/dist/persistence/db/db-constants.js +6 -0
- package/dist/persistence/db/db-constants.js.map +1 -0
- package/dist/persistence/db/db-provider.d.ts +3 -0
- package/dist/persistence/db/db-provider.d.ts.map +1 -0
- package/dist/persistence/db/db-provider.js +29 -0
- package/dist/persistence/db/db-provider.js.map +1 -0
- package/dist/persistence/db/db-schema.d.ts +8 -0
- package/dist/persistence/db/db-schema.d.ts.map +1 -0
- package/dist/persistence/db/db-schema.js +27 -0
- package/dist/persistence/db/db-schema.js.map +1 -0
- package/dist/persistence/origin/meta-origin.d.ts +32 -0
- package/dist/persistence/origin/meta-origin.d.ts.map +1 -0
- package/dist/persistence/origin/meta-origin.js +55 -0
- package/dist/persistence/origin/meta-origin.js.map +1 -0
- package/dist/persistence/origin/origin-constants.d.ts +12 -0
- package/dist/persistence/origin/origin-constants.d.ts.map +1 -0
- package/dist/persistence/origin/origin-constants.js +27 -0
- package/dist/persistence/origin/origin-constants.js.map +1 -0
- package/dist/persistence/origin/origin-schema.d.ts +4 -0
- package/dist/persistence/origin/origin-schema.d.ts.map +1 -0
- package/dist/persistence/origin/origin-schema.js +49 -0
- package/dist/persistence/origin/origin-schema.js.map +1 -0
- package/dist/persistence/source/meta-source.d.ts +18 -0
- package/dist/persistence/source/meta-source.d.ts.map +1 -0
- package/dist/persistence/source/meta-source.js +31 -0
- package/dist/persistence/source/meta-source.js.map +1 -0
- package/dist/persistence/source/source-constants.d.ts +16 -0
- package/dist/persistence/source/source-constants.d.ts.map +1 -0
- package/dist/persistence/source/source-constants.js +28 -0
- package/dist/persistence/source/source-constants.js.map +1 -0
- package/dist/presentation/layout/layout-constants.d.ts +10 -0
- package/dist/presentation/layout/layout-constants.d.ts.map +1 -0
- package/dist/presentation/layout/layout-constants.js +21 -0
- package/dist/presentation/layout/layout-constants.js.map +1 -0
- package/dist/presentation/layout/layout-schema.d.ts +4 -0
- package/dist/presentation/layout/layout-schema.d.ts.map +1 -0
- package/dist/presentation/layout/layout-schema.js +46 -0
- package/dist/presentation/layout/layout-schema.js.map +1 -0
- package/dist/presentation/layout/meta-layout.d.ts +23 -0
- package/dist/presentation/layout/meta-layout.d.ts.map +1 -0
- package/dist/presentation/layout/meta-layout.js +47 -0
- package/dist/presentation/layout/meta-layout.js.map +1 -0
- package/dist/presentation/view/meta-view.d.ts +4 -0
- package/dist/presentation/view/meta-view.d.ts.map +1 -0
- package/dist/presentation/view/meta-view.js +8 -0
- package/dist/presentation/view/meta-view.js.map +1 -0
- package/dist/presentation/view/view-constants.d.ts +20 -0
- package/dist/presentation/view/view-constants.d.ts.map +1 -0
- package/dist/presentation/view/view-constants.js +47 -0
- package/dist/presentation/view/view-constants.js.map +1 -0
- package/dist/presentation/view/view-schema.d.ts +4 -0
- package/dist/presentation/view/view-schema.d.ts.map +1 -0
- package/dist/presentation/view/view-schema.js +15 -0
- package/dist/presentation/view/view-schema.js.map +1 -0
- package/dist/provider.d.ts +20 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +58 -0
- package/dist/provider.js.map +1 -0
- package/dist/registry.d.ts +89 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +107 -0
- package/dist/registry.js.map +1 -0
- package/dist/serializer-json.d.ts +16 -0
- package/dist/serializer-json.d.ts.map +1 -0
- package/dist/serializer-json.js +154 -0
- package/dist/serializer-json.js.map +1 -0
- package/dist/shared/base-types.d.ts +23 -0
- package/dist/shared/base-types.d.ts.map +1 -0
- package/dist/shared/base-types.js +43 -0
- package/dist/shared/base-types.js.map +1 -0
- package/dist/shared/meta-data.d.ts +123 -0
- package/dist/shared/meta-data.d.ts.map +1 -0
- package/dist/shared/meta-data.js +365 -0
- package/dist/shared/meta-data.js.map +1 -0
- package/dist/shared/meta-root.d.ts +12 -0
- package/dist/shared/meta-root.d.ts.map +1 -0
- package/dist/shared/meta-root.js +24 -0
- package/dist/shared/meta-root.js.map +1 -0
- package/dist/shared/structural.d.ts +20 -0
- package/dist/shared/structural.d.ts.map +1 -0
- package/dist/shared/structural.js +49 -0
- package/dist/shared/structural.js.map +1 -0
- package/dist/subtype-rules.d.ts +8 -0
- package/dist/subtype-rules.d.ts.map +1 -0
- package/dist/subtype-rules.js +34 -0
- package/dist/subtype-rules.js.map +1 -0
- package/dist/super-resolve.d.ts +34 -0
- package/dist/super-resolve.d.ts.map +1 -0
- package/dist/super-resolve.js +124 -0
- package/dist/super-resolve.js.map +1 -0
- package/package.json +50 -0
- package/src/attr-class-map.ts +64 -0
- package/src/attr-schema-validate.ts +134 -0
- package/src/core/attr/attr-constants.ts +31 -0
- package/src/core/attr/meta-attr-filter.ts +67 -0
- package/src/core/attr/meta-attr-properties.ts +26 -0
- package/src/core/attr/meta-attr-stringarray.ts +31 -0
- package/src/core/attr/meta-attr.ts +125 -0
- package/src/core/export-json.ts +66 -0
- package/src/core/field/field-constants.ts +79 -0
- package/src/core/field/field-schema.ts +121 -0
- package/src/core/field/meta-field.ts +179 -0
- package/src/core/file-meta-data-loader.ts +89 -0
- package/src/core/file-source.ts +52 -0
- package/src/core/identity/identity-constants.ts +44 -0
- package/src/core/identity/identity-schema.ts +80 -0
- package/src/core/identity/meta-identity.ts +148 -0
- package/src/core/index.ts +12 -0
- package/src/core/object/meta-object.ts +151 -0
- package/src/core/object/object-constants.ts +21 -0
- package/src/core/object/object-schema.ts +7 -0
- package/src/core/parser-yaml.ts +54 -0
- package/src/core/query/query-constants.ts +66 -0
- package/src/core/relationship/find-reference.ts +44 -0
- package/src/core/relationship/meta-relationship.ts +36 -0
- package/src/core/relationship/relationship-constants.ts +38 -0
- package/src/core/relationship/relationship-schema.ts +49 -0
- package/src/core/validator/meta-validator.ts +62 -0
- package/src/core/validator/validator-constants.ts +31 -0
- package/src/core/validator/validator-schema.ts +50 -0
- package/src/core/yaml-desugar.ts +145 -0
- package/src/core-types.ts +329 -0
- package/src/data-converter.ts +125 -0
- package/src/data-type.ts +33 -0
- package/src/errors.ts +68 -0
- package/src/index.ts +165 -0
- package/src/loader/meta-data-loader.ts +307 -0
- package/src/loader/meta-data-source.ts +35 -0
- package/src/loader/validation-passes.ts +370 -0
- package/src/naming.ts +86 -0
- package/src/object-serializer.ts +153 -0
- package/src/overlay.ts +5 -0
- package/src/parser-core.ts +815 -0
- package/src/parser-json.ts +28 -0
- package/src/persistence/db/db-constants.ts +6 -0
- package/src/persistence/db/db-provider.ts +36 -0
- package/src/persistence/db/db-schema.ts +40 -0
- package/src/persistence/origin/meta-origin.ts +67 -0
- package/src/persistence/origin/origin-constants.ts +35 -0
- package/src/persistence/origin/origin-schema.ts +66 -0
- package/src/persistence/source/meta-source.ts +38 -0
- package/src/persistence/source/source-constants.ts +35 -0
- package/src/presentation/layout/layout-constants.ts +27 -0
- package/src/presentation/layout/layout-schema.ts +62 -0
- package/src/presentation/layout/meta-layout.ts +61 -0
- package/src/presentation/view/meta-view.ts +8 -0
- package/src/presentation/view/view-constants.ts +53 -0
- package/src/presentation/view/view-schema.ts +21 -0
- package/src/provider.ts +85 -0
- package/src/registry.ts +190 -0
- package/src/serializer-json.ts +210 -0
- package/src/shared/base-types.ts +52 -0
- package/src/shared/meta-data.ts +443 -0
- package/src/shared/meta-root.ts +33 -0
- package/src/shared/structural.ts +62 -0
- package/src/subtype-rules.ts +56 -0
- package/src/super-resolve.ts +147 -0
package/src/provider.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Type provider model — provider-based, extensible metamodel registration.
|
|
2
|
+
//
|
|
3
|
+
// A MetaDataTypeProvider contributes (and/or extends) registered types. The
|
|
4
|
+
// contract is cross-language identical (Java MetaDataTypeProvider parity);
|
|
5
|
+
// discovery is per-language — for TS it is explicit composition via
|
|
6
|
+
// composeRegistry. See docs/superpowers/specs/2026-05-17-type-provider-model-design.md.
|
|
7
|
+
|
|
8
|
+
import { TypeRegistry } from "./registry.js";
|
|
9
|
+
import { MetaModelError } from "./errors.js";
|
|
10
|
+
|
|
11
|
+
/** A unit of metamodel registration. One provider per package. */
|
|
12
|
+
export interface MetaDataTypeProvider {
|
|
13
|
+
/** Stable id; other providers reference it in `dependencies`. */
|
|
14
|
+
readonly id: string;
|
|
15
|
+
/** Ids of providers that must register before this one. Default: none. */
|
|
16
|
+
readonly dependencies?: readonly string[];
|
|
17
|
+
/** Human/AI-facing description of what this provider contributes. */
|
|
18
|
+
readonly description?: string;
|
|
19
|
+
/** Register new types and/or extend existing ones. */
|
|
20
|
+
registerTypes(registry: TypeRegistry): void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Build a TypeRegistry by composing providers. Providers are topologically
|
|
25
|
+
* sorted by their `dependencies`; the sort is stable — providers with no
|
|
26
|
+
* ordering constraint between them keep input order. Throws on a duplicate
|
|
27
|
+
* provider id, a missing dependency, or a dependency cycle.
|
|
28
|
+
*/
|
|
29
|
+
export function composeRegistry(
|
|
30
|
+
providers: readonly MetaDataTypeProvider[],
|
|
31
|
+
): TypeRegistry {
|
|
32
|
+
const ordered = topoSortProviders(providers);
|
|
33
|
+
const registry = new TypeRegistry();
|
|
34
|
+
for (const provider of ordered) {
|
|
35
|
+
provider.registerTypes(registry);
|
|
36
|
+
}
|
|
37
|
+
return registry;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function topoSortProviders(
|
|
41
|
+
providers: readonly MetaDataTypeProvider[],
|
|
42
|
+
): MetaDataTypeProvider[] {
|
|
43
|
+
// Duplicate-id check.
|
|
44
|
+
const ids = new Set<string>();
|
|
45
|
+
for (const p of providers) {
|
|
46
|
+
if (ids.has(p.id)) {
|
|
47
|
+
throw new MetaModelError(`composeRegistry: duplicate provider id "${p.id}"`, { code: "ERR_PROVIDER_DUPLICATE_ID" });
|
|
48
|
+
}
|
|
49
|
+
ids.add(p.id);
|
|
50
|
+
}
|
|
51
|
+
// Missing-dependency check.
|
|
52
|
+
for (const p of providers) {
|
|
53
|
+
for (const dep of p.dependencies ?? []) {
|
|
54
|
+
if (!ids.has(dep)) {
|
|
55
|
+
throw new MetaModelError(
|
|
56
|
+
`composeRegistry: provider "${p.id}" depends on "${dep}", which is not in the provider set`,
|
|
57
|
+
{ code: "ERR_PROVIDER_MISSING_DEPENDENCY" },
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Stable topological sort: repeatedly emit the first (input-order) provider
|
|
63
|
+
// whose dependencies are all already emitted. O(n^2) — n is a handful.
|
|
64
|
+
const result: MetaDataTypeProvider[] = [];
|
|
65
|
+
const emitted = new Set<string>();
|
|
66
|
+
while (result.length < providers.length) {
|
|
67
|
+
const next = providers.find(
|
|
68
|
+
(p) =>
|
|
69
|
+
!emitted.has(p.id) &&
|
|
70
|
+
(p.dependencies ?? []).every((d) => emitted.has(d)),
|
|
71
|
+
);
|
|
72
|
+
if (next === undefined) {
|
|
73
|
+
const stuck = providers
|
|
74
|
+
.filter((p) => !emitted.has(p.id))
|
|
75
|
+
.map((p) => p.id);
|
|
76
|
+
throw new MetaModelError(
|
|
77
|
+
`composeRegistry: dependency cycle among providers [${stuck.join(", ")}]`,
|
|
78
|
+
{ code: "ERR_PROVIDER_DEPENDENCY_CYCLE" },
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
result.push(next);
|
|
82
|
+
emitted.add(next.id);
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
package/src/registry.ts
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import type { AttrValue, MetaData } from "./shared/meta-data.js";
|
|
2
|
+
import { SUBTYPE_BASE, TYPE_ATTR } from "./shared/base-types.js";
|
|
3
|
+
import { CHILD_RULE_WILDCARD } from "./shared/structural.js";
|
|
4
|
+
import { type AttrSubType } from "./core/attr/attr-constants.js";
|
|
5
|
+
import type { DataType } from "./data-type.js";
|
|
6
|
+
import { MetaModelError } from "./errors.js";
|
|
7
|
+
|
|
8
|
+
export class TypeId {
|
|
9
|
+
constructor(
|
|
10
|
+
public readonly type: string,
|
|
11
|
+
public readonly subType: string,
|
|
12
|
+
) {}
|
|
13
|
+
|
|
14
|
+
toString(): string {
|
|
15
|
+
return `${this.type}.${this.subType}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
equals(other: TypeId): boolean {
|
|
19
|
+
return this.type === other.type && this.subType === other.subType;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ChildRule {
|
|
24
|
+
/** `"*"` matches any type. */
|
|
25
|
+
childType: string;
|
|
26
|
+
/** `"*"` matches any subtype. */
|
|
27
|
+
childSubType: string;
|
|
28
|
+
/** `"*"` matches any name. */
|
|
29
|
+
childName: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface AttrSchema {
|
|
33
|
+
/** Attribute name WITHOUT the "@" prefix (e.g. "dbColumn", "currency"). */
|
|
34
|
+
name: string;
|
|
35
|
+
/**
|
|
36
|
+
* The attribute's value type — one of the registered attr subtypes.
|
|
37
|
+
*
|
|
38
|
+
* Optional: when absent, the attr is declared-but-untyped (no parse-time
|
|
39
|
+
* coercion; value stored raw via `toAttrValue`). Use this for polymorphic
|
|
40
|
+
* attrs whose value type is determined by the owning node at consumption
|
|
41
|
+
* time (e.g. `@default`, which is typed by its owning field's subtype).
|
|
42
|
+
*
|
|
43
|
+
* `SUBTYPE_BASE` ("base") MUST NOT be used here — it is the universal root
|
|
44
|
+
* subtype for object/field/etc. nodes and carries no "untyped" semantics for
|
|
45
|
+
* attrs. Attempting to register an AttrSchema with `valueType: "base"` throws.
|
|
46
|
+
*/
|
|
47
|
+
valueType?: AttrSubType;
|
|
48
|
+
/** Whether this attribute must be present on the node. */
|
|
49
|
+
required: boolean;
|
|
50
|
+
/** Default value applied when the attribute is absent. Optional. */
|
|
51
|
+
default?: AttrValue;
|
|
52
|
+
/** When set, the attribute's value must be one of these (a closed enum). Optional. */
|
|
53
|
+
allowedValues?: readonly AttrValue[];
|
|
54
|
+
/** Human/AI-facing description of what the attribute means. */
|
|
55
|
+
description: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface TypeDefinition {
|
|
59
|
+
typeId: TypeId;
|
|
60
|
+
description: string;
|
|
61
|
+
factory: (typeId: TypeId, name: string) => MetaData;
|
|
62
|
+
childRules: ChildRule[];
|
|
63
|
+
attributes: AttrSchema[];
|
|
64
|
+
/** The coarse value-type classification, for (type, subType)s whose nodes
|
|
65
|
+
* carry a typed value (field, attr). Absent for non-value-bearing types. */
|
|
66
|
+
dataType?: DataType;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export class TypeRegistry {
|
|
70
|
+
/** Keyed by `"type.subType"`. */
|
|
71
|
+
private readonly _defs = new Map<string, TypeDefinition>();
|
|
72
|
+
|
|
73
|
+
/** Per-type insertion-ordered subtype lists. */
|
|
74
|
+
private readonly _subTypes = new Map<string, string[]>();
|
|
75
|
+
|
|
76
|
+
/** Per-type designated default subType (queried by the YAML desugar). */
|
|
77
|
+
private readonly _defaultSubTypes = new Map<string, string>();
|
|
78
|
+
|
|
79
|
+
register(def: TypeDefinition): void {
|
|
80
|
+
const key = def.typeId.toString();
|
|
81
|
+
if (this._defs.has(key)) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`TypeRegistry: duplicate registration for "${key}" (type="${def.typeId.type}", subType="${def.typeId.subType}")`,
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Reject SUBTYPE_BASE as an attr valueType. "base" is the universal root
|
|
88
|
+
// subtype for object/field/etc. nodes; it must NOT be used as an attr value
|
|
89
|
+
// type because it carries no meaningful type semantics for attrs (its DataType
|
|
90
|
+
// resolves to DATA_TYPE_STRING, silently coercing boolean/number defaults to
|
|
91
|
+
// strings). Polymorphic attrs (e.g. @default) must omit valueType instead.
|
|
92
|
+
for (const attr of def.attributes) {
|
|
93
|
+
if (attr.valueType === SUBTYPE_BASE) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
`TypeRegistry.register: attr "${attr.name}" on "${key}" declares valueType "${SUBTYPE_BASE}", ` +
|
|
96
|
+
`which is not valid for attrs. Use no valueType (omit the field) for a polymorphic/untyped attr.`,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this._defs.set(key, def);
|
|
102
|
+
|
|
103
|
+
const list = this._subTypes.get(def.typeId.type);
|
|
104
|
+
if (list !== undefined) {
|
|
105
|
+
list.push(def.typeId.subType);
|
|
106
|
+
} else {
|
|
107
|
+
this._subTypes.set(def.typeId.type, [def.typeId.subType]);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
find(type: string, subType: string): TypeDefinition | undefined {
|
|
112
|
+
return this._defs.get(`${type}.${subType}`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
has(type: string, subType: string): boolean {
|
|
116
|
+
return this.find(type, subType) !== undefined;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
allTypes(): TypeId[] {
|
|
120
|
+
return Array.from(this._defs.values()).map((def) => def.typeId);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
allSubTypesOf(type: string): string[] {
|
|
124
|
+
return [...(this._subTypes.get(type) ?? [])];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Designate the default subType for a bare `type` key (used by YAML authoring sugar). */
|
|
128
|
+
setDefaultSubType(type: string, subType: string): void {
|
|
129
|
+
this._defaultSubTypes.set(type, subType);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** The designated default subType for a type, or undefined if none was designated. */
|
|
133
|
+
defaultSubTypeOf(type: string): string | undefined {
|
|
134
|
+
return this._defaultSubTypes.get(type);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** The declared attribute schema for a (type, subType), or [] if the
|
|
138
|
+
* pair is unregistered or declares no attributes. */
|
|
139
|
+
attrsOf(type: string, subType: string): AttrSchema[] {
|
|
140
|
+
return [...(this.find(type, subType)?.attributes ?? [])];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Additively enrich an already-registered (type, subType): append attributes
|
|
145
|
+
* and/or child rules. Does NOT touch factory / typeId / dataType / default
|
|
146
|
+
* subType — a type's identity belongs to whoever registered it. Used by
|
|
147
|
+
* providers to extend types another provider defined.
|
|
148
|
+
*/
|
|
149
|
+
extend(
|
|
150
|
+
type: string,
|
|
151
|
+
subType: string,
|
|
152
|
+
ext: { attributes?: AttrSchema[]; childRules?: ChildRule[] },
|
|
153
|
+
): void {
|
|
154
|
+
const def = this.find(type, subType);
|
|
155
|
+
if (def === undefined) {
|
|
156
|
+
throw new Error(
|
|
157
|
+
`TypeRegistry.extend: no registered type "${type}.${subType}" to extend`,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
for (const attr of ext.attributes ?? []) {
|
|
161
|
+
if (attr.valueType === SUBTYPE_BASE) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
`TypeRegistry.extend: attr "${attr.name}" being added to "${type}.${subType}" declares valueType "${SUBTYPE_BASE}", ` +
|
|
164
|
+
`which is not valid for attrs. Use no valueType (omit the field) for a polymorphic/untyped attr.`,
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
if (def.attributes.some((a) => a.name === attr.name)) {
|
|
168
|
+
throw new MetaModelError(
|
|
169
|
+
`TypeRegistry.extend: attribute "${attr.name}" is already declared on "${type}.${subType}"`,
|
|
170
|
+
{ code: "ERR_PROVIDER_ATTR_CONFLICT" },
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
def.attributes.push(attr);
|
|
174
|
+
}
|
|
175
|
+
for (const rule of ext.childRules ?? []) {
|
|
176
|
+
def.childRules.push(rule);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function childRuleMatches(
|
|
182
|
+
rule: ChildRule,
|
|
183
|
+
child: { type: string; subType: string; name: string },
|
|
184
|
+
): boolean {
|
|
185
|
+
return (
|
|
186
|
+
(rule.childType === CHILD_RULE_WILDCARD || rule.childType === child.type) &&
|
|
187
|
+
(rule.childSubType === CHILD_RULE_WILDCARD || rule.childSubType === child.subType) &&
|
|
188
|
+
(rule.childName === CHILD_RULE_WILDCARD || rule.childName === child.name)
|
|
189
|
+
);
|
|
190
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// Canonical JSON serializer — redesigned (post-v0.3) format.
|
|
2
|
+
//
|
|
3
|
+
// Every node serializes to a single-key map { "<type>.<subType>": <body> }.
|
|
4
|
+
// The wrapper key fuses type and subType. The body emits keys in the canonical
|
|
5
|
+
// order, each included only when non-default:
|
|
6
|
+
// 1. name 2. package 3. extends 4. abstract
|
|
7
|
+
// 5. overlay 6. isArray 7. @-attrs (alphabetical) 8. children
|
|
8
|
+
|
|
9
|
+
import type { MetaData, AttrValue } from "./shared/meta-data.js";
|
|
10
|
+
import {
|
|
11
|
+
ATTR_PREFIX,
|
|
12
|
+
TYPE_SUBTYPE_SEPARATOR,
|
|
13
|
+
RESERVED_KEY_NAME,
|
|
14
|
+
RESERVED_KEY_PACKAGE,
|
|
15
|
+
RESERVED_KEY_EXTENDS,
|
|
16
|
+
RESERVED_KEY_ABSTRACT,
|
|
17
|
+
RESERVED_KEY_IS_ARRAY,
|
|
18
|
+
RESERVED_KEY_CHILDREN,
|
|
19
|
+
} from "./shared/structural.js";
|
|
20
|
+
import {
|
|
21
|
+
ATTR_SUBTYPE_STRING,
|
|
22
|
+
ATTR_SUBTYPE_INT,
|
|
23
|
+
ATTR_SUBTYPE_LONG,
|
|
24
|
+
ATTR_SUBTYPE_DOUBLE,
|
|
25
|
+
ATTR_SUBTYPE_BOOLEAN,
|
|
26
|
+
ATTR_SUBTYPE_STRINGARRAY,
|
|
27
|
+
} from "./core/attr/attr-constants.js";
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Public API
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
export interface SerializeOptions {
|
|
34
|
+
/** Pretty-print indent. 0 = no whitespace. Default 2. */
|
|
35
|
+
indent?: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function serializeJson(model: MetaData, opts?: SerializeOptions): string {
|
|
39
|
+
const indent = opts?.indent ?? 2;
|
|
40
|
+
|
|
41
|
+
const nodeObj = serializeNode(model, false);
|
|
42
|
+
return JSON.stringify(nodeObj, null, indent === 0 ? undefined : indent);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Infer attr subType from a JS value (for child-node form when subType isn't known)
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
// Java int range — used for distinguishing int vs long subtypes.
|
|
50
|
+
const JAVA_INT_MAX = 2 ** 31 - 1;
|
|
51
|
+
const JAVA_INT_MIN = -(2 ** 31);
|
|
52
|
+
|
|
53
|
+
export function inferAttrSubType(value: AttrValue): string {
|
|
54
|
+
if (Array.isArray(value)) return ATTR_SUBTYPE_STRINGARRAY;
|
|
55
|
+
if (typeof value === "boolean") return ATTR_SUBTYPE_BOOLEAN;
|
|
56
|
+
if (typeof value === "number") {
|
|
57
|
+
if (!Number.isInteger(value)) return ATTR_SUBTYPE_DOUBLE;
|
|
58
|
+
return value >= JAVA_INT_MIN && value <= JAVA_INT_MAX
|
|
59
|
+
? ATTR_SUBTYPE_INT
|
|
60
|
+
: ATTR_SUBTYPE_LONG;
|
|
61
|
+
}
|
|
62
|
+
return ATTR_SUBTYPE_STRING;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Build a fused `type.subType` wrapper key. */
|
|
66
|
+
function fusedKey(type: string, subType: string): string {
|
|
67
|
+
return `${type}${TYPE_SUBTYPE_SEPARATOR}${subType}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Serialize a single node — returns { "<type>.<subType>": { ...body } }
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
function serializeNode(
|
|
75
|
+
model: MetaData,
|
|
76
|
+
effective: boolean,
|
|
77
|
+
): Record<string, unknown> {
|
|
78
|
+
const inner = serializeNodeInner(model, effective);
|
|
79
|
+
return { [fusedKey(model.type, model.subType)]: inner };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function serializeNodeInner(
|
|
83
|
+
model: MetaData,
|
|
84
|
+
effective: boolean,
|
|
85
|
+
): Record<string, unknown> {
|
|
86
|
+
// Canonical body-key order:
|
|
87
|
+
// 1. name 2. package 3. extends 4. abstract
|
|
88
|
+
// 5. overlay 6. isArray 7. inline @-attrs 8. children
|
|
89
|
+
|
|
90
|
+
const obj: Record<string, unknown> = {};
|
|
91
|
+
|
|
92
|
+
if (model.name !== "") {
|
|
93
|
+
obj[RESERVED_KEY_NAME] = model.name;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (model.package !== undefined && model.package !== "") {
|
|
97
|
+
obj[RESERVED_KEY_PACKAGE] = model.package;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (model.superRef !== undefined) {
|
|
101
|
+
obj[RESERVED_KEY_EXTENDS] = model.superRef;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (model.isAbstract === true) {
|
|
105
|
+
obj[RESERVED_KEY_ABSTRACT] = true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// NOTE: `overlay` is an authoring-time parser directive, not a property of
|
|
109
|
+
// the resolved tree. After a merge, the merged node is a normal node — the
|
|
110
|
+
// canonical serialization is the merged RESULT, which carries no overlay
|
|
111
|
+
// semantics. Re-emitting `overlay: true` would break round-trip stability
|
|
112
|
+
// (re-parsing would seek a non-existent node to merge into). So it is
|
|
113
|
+
// deliberately NOT serialized.
|
|
114
|
+
|
|
115
|
+
if (model.isArray === true) {
|
|
116
|
+
obj[RESERVED_KEY_IS_ARRAY] = true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// In effective mode use children()/attrs() (own + inherited via super chain);
|
|
120
|
+
// in own mode use ownChildren()/ownAttrs() (declared on this node only).
|
|
121
|
+
const childList = effective ? model.children() : model.ownChildren();
|
|
122
|
+
const attrMap = effective ? model.attrs() : model.ownAttrs();
|
|
123
|
+
|
|
124
|
+
const serializedChildren: Record<string, unknown>[] = [];
|
|
125
|
+
for (const child of childList) {
|
|
126
|
+
// Attrs never appear in children(); only structural nodes recurse.
|
|
127
|
+
serializedChildren.push(serializeNode(child, effective));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Attrs ALWAYS emit inline @name (D5 — attrs have no children, one canonical form).
|
|
131
|
+
for (const [attrName, attrValue] of attrMap) {
|
|
132
|
+
obj[`${ATTR_PREFIX}${attrName}`] = attrValue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (serializedChildren.length > 0) {
|
|
136
|
+
obj[RESERVED_KEY_CHILDREN] = serializedChildren;
|
|
137
|
+
}
|
|
138
|
+
return obj;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
// canonicalSerialize — deterministic serializer for cross-language conformance
|
|
143
|
+
//
|
|
144
|
+
// Wraps serializeJson with two extra guarantees:
|
|
145
|
+
// 1. Inline @-attrs are emitted in alphabetical order (not Map iteration order).
|
|
146
|
+
// 2. Output ends with exactly one trailing newline.
|
|
147
|
+
//
|
|
148
|
+
// Both behaviors are required so Java/Python/C# implementations can produce
|
|
149
|
+
// byte-identical output from the same input metamodel.
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
|
|
152
|
+
export function canonicalSerialize(model: MetaData): string {
|
|
153
|
+
const raw = serializeJson(model, { indent: 2 });
|
|
154
|
+
|
|
155
|
+
const parsed = JSON.parse(raw) as unknown;
|
|
156
|
+
const sorted = sortAttrKeys(parsed);
|
|
157
|
+
const out = JSON.stringify(sorted, null, 2);
|
|
158
|
+
|
|
159
|
+
return out + "\n";
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Like canonicalSerialize, but emits the EFFECTIVE tree — children() and
|
|
164
|
+
* attrs() at every node (own + inherited via the super chain), so the
|
|
165
|
+
* super-chain merge is materialized in the output.
|
|
166
|
+
* Used by the conformance harness's expected-effective fixtures.
|
|
167
|
+
*/
|
|
168
|
+
export function canonicalSerializeEffective(model: MetaData): string {
|
|
169
|
+
const nodeObj = serializeNode(model, true);
|
|
170
|
+
const raw = JSON.stringify(nodeObj, null, 2);
|
|
171
|
+
|
|
172
|
+
const parsed = JSON.parse(raw) as unknown;
|
|
173
|
+
const sorted = sortAttrKeys(parsed);
|
|
174
|
+
const out = JSON.stringify(sorted, null, 2);
|
|
175
|
+
|
|
176
|
+
return out + "\n";
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function sortAttrKeys(value: unknown): unknown {
|
|
180
|
+
if (Array.isArray(value)) {
|
|
181
|
+
return value.map(sortAttrKeys);
|
|
182
|
+
}
|
|
183
|
+
if (value !== null && typeof value === "object") {
|
|
184
|
+
const obj = value as Record<string, unknown>;
|
|
185
|
+
const keys = Object.keys(obj);
|
|
186
|
+
|
|
187
|
+
const structuralKeys: string[] = [];
|
|
188
|
+
const attrKeys: string[] = [];
|
|
189
|
+
for (const k of keys) {
|
|
190
|
+
if (k.startsWith(ATTR_PREFIX)) attrKeys.push(k);
|
|
191
|
+
else structuralKeys.push(k);
|
|
192
|
+
}
|
|
193
|
+
attrKeys.sort();
|
|
194
|
+
|
|
195
|
+
const result: Record<string, unknown> = {};
|
|
196
|
+
const hasChildren = structuralKeys.includes(RESERVED_KEY_CHILDREN);
|
|
197
|
+
for (const k of structuralKeys) {
|
|
198
|
+
if (k === RESERVED_KEY_CHILDREN) continue;
|
|
199
|
+
result[k] = sortAttrKeys(obj[k]);
|
|
200
|
+
}
|
|
201
|
+
for (const k of attrKeys) {
|
|
202
|
+
result[k] = sortAttrKeys(obj[k]);
|
|
203
|
+
}
|
|
204
|
+
if (hasChildren) {
|
|
205
|
+
result[RESERVED_KEY_CHILDREN] = sortAttrKeys(obj[RESERVED_KEY_CHILDREN]);
|
|
206
|
+
}
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
return value;
|
|
210
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Base type vocabulary — the 11 registered base types + universal/metadata subtypes.
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Base type names (the 11 registered base types — Java metaobjects-core vocabulary)
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
export const TYPE_METADATA = "metadata";
|
|
8
|
+
export const TYPE_OBJECT = "object";
|
|
9
|
+
export const TYPE_FIELD = "field";
|
|
10
|
+
export const TYPE_ATTR = "attr";
|
|
11
|
+
export const TYPE_VALIDATOR = "validator";
|
|
12
|
+
export const TYPE_VIEW = "view";
|
|
13
|
+
export const TYPE_IDENTITY = "identity";
|
|
14
|
+
export const TYPE_RELATIONSHIP = "relationship";
|
|
15
|
+
export const TYPE_LAYOUT = "layout";
|
|
16
|
+
export const TYPE_SOURCE = "source";
|
|
17
|
+
export const TYPE_ORIGIN = "origin";
|
|
18
|
+
|
|
19
|
+
export const BASE_TYPES = [
|
|
20
|
+
TYPE_METADATA,
|
|
21
|
+
TYPE_OBJECT,
|
|
22
|
+
TYPE_FIELD,
|
|
23
|
+
TYPE_ATTR,
|
|
24
|
+
TYPE_VALIDATOR,
|
|
25
|
+
TYPE_VIEW,
|
|
26
|
+
TYPE_IDENTITY,
|
|
27
|
+
TYPE_RELATIONSHIP,
|
|
28
|
+
TYPE_LAYOUT,
|
|
29
|
+
TYPE_SOURCE,
|
|
30
|
+
TYPE_ORIGIN,
|
|
31
|
+
] as const;
|
|
32
|
+
export type BaseType = (typeof BASE_TYPES)[number];
|
|
33
|
+
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Universal subtype
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
export const SUBTYPE_BASE = "base";
|
|
39
|
+
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Metadata subtypes (1)
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The metadata document root subtype. The root node is `metadata.root` in the
|
|
46
|
+
* canonical format. (Distinct from the universal SUBTYPE_BASE — the redesigned
|
|
47
|
+
* format spec confirms the root subtype is `root`, not `base`.)
|
|
48
|
+
*/
|
|
49
|
+
export const SUBTYPE_ROOT = "root";
|
|
50
|
+
|
|
51
|
+
export const METADATA_SUBTYPES = [SUBTYPE_ROOT] as const;
|
|
52
|
+
export type MetadataSubType = (typeof METADATA_SUBTYPES)[number];
|