@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
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// FileMetaDataLoader — discovers file-backed MetaDataSources and runs the
|
|
2
|
+
// MetaDataLoader pipeline over them. A UrlMetaDataLoader will slot in the
|
|
3
|
+
// same way later.
|
|
4
|
+
|
|
5
|
+
import type { Stats } from "node:fs";
|
|
6
|
+
import { readdir, stat } from "node:fs/promises";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { MetaDataLoader, type LoadResult } from "../loader/meta-data-loader.js";
|
|
9
|
+
import { FileSource } from "./file-source.js";
|
|
10
|
+
import { parseYaml } from "./parser-yaml.js";
|
|
11
|
+
import type { ParseOptions, ParseResult } from "../parser-core.js";
|
|
12
|
+
import type { MetaDataSource } from "../loader/meta-data-source.js";
|
|
13
|
+
|
|
14
|
+
/** Minimal glob matcher supporting `*` (any chars except `/`) and `**` (any chars). */
|
|
15
|
+
function matchSimpleGlob(pattern: string, value: string): boolean {
|
|
16
|
+
const regexStr = pattern
|
|
17
|
+
.replace(/[.+^${}()|[\]\\]/g, "\\$&")
|
|
18
|
+
.replace(/\*\*/g, "::DOUBLESTAR::")
|
|
19
|
+
.replace(/\*/g, "[^/]*")
|
|
20
|
+
.replace(/::DOUBLESTAR::/g, ".*");
|
|
21
|
+
return new RegExp(`^${regexStr}$`).test(value);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class FileMetaDataLoader extends MetaDataLoader {
|
|
25
|
+
/** Adds YAML parsing on top of the base loader's JSON-only `parseSource`. */
|
|
26
|
+
protected override parseSource(
|
|
27
|
+
content: string,
|
|
28
|
+
source: MetaDataSource,
|
|
29
|
+
parseOpts: ParseOptions,
|
|
30
|
+
): ParseResult {
|
|
31
|
+
if (source.format === "yaml") {
|
|
32
|
+
return parseYaml(content, parseOpts);
|
|
33
|
+
}
|
|
34
|
+
return super.parseSource(content, source, parseOpts);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Load every `.json` / `.yaml` / `.yml` file in a directory (non-recursive),
|
|
39
|
+
* in deterministic ordinal filename order.
|
|
40
|
+
* @param opts.exclude glob patterns (relative to dir) to skip — `*` / `**`.
|
|
41
|
+
*/
|
|
42
|
+
async loadDirectory(dir: string, opts?: { exclude?: string[] }): Promise<LoadResult> {
|
|
43
|
+
let entries: string[];
|
|
44
|
+
try {
|
|
45
|
+
// Sorted for deterministic multi-file load order: the overlay merge is
|
|
46
|
+
// order-sensitive (last-writer-wins on attr conflicts), so the scan must
|
|
47
|
+
// not depend on filesystem readdir order. Ordinal filename sort is
|
|
48
|
+
// reproducible across the Java/Python/C# ports.
|
|
49
|
+
entries = (await readdir(dir)).sort();
|
|
50
|
+
} catch (err) {
|
|
51
|
+
// Surface the I/O failure as a collected error via the empty-source path.
|
|
52
|
+
const emptyResult = await this.load([]);
|
|
53
|
+
return {
|
|
54
|
+
...emptyResult,
|
|
55
|
+
errors: [
|
|
56
|
+
new Error(`loadDirectory: cannot read ${dir}: ${(err as Error).message}`),
|
|
57
|
+
...emptyResult.errors,
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const excludes = opts?.exclude ?? [];
|
|
63
|
+
const paths: string[] = [];
|
|
64
|
+
for (const entry of entries) {
|
|
65
|
+
const lower = entry.toLowerCase();
|
|
66
|
+
if (!lower.endsWith(".json") && !lower.endsWith(".yaml") && !lower.endsWith(".yml")) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const filePath = join(dir, entry);
|
|
70
|
+
let statResult: Stats;
|
|
71
|
+
try {
|
|
72
|
+
statResult = await stat(filePath);
|
|
73
|
+
} catch {
|
|
74
|
+
// Entry vanished between readdir and stat (TOCTOU) or is not accessible.
|
|
75
|
+
// Skip it rather than breaking the no-throw contract of loadDirectory.
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (!statResult.isFile()) continue;
|
|
79
|
+
if (excludes.some((p) => matchSimpleGlob(p, entry))) continue;
|
|
80
|
+
paths.push(filePath);
|
|
81
|
+
}
|
|
82
|
+
return this.loadFiles(paths);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Load an explicit list of file paths, in order. */
|
|
86
|
+
async loadFiles(paths: string[]): Promise<LoadResult> {
|
|
87
|
+
return this.load(paths.map((p) => new FileSource(p)));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// FileSource — a MetaDataSource backed by a file on disk. Server-side only
|
|
2
|
+
// (touches node:fs); lives under src/core/ so the browser-safe root never
|
|
3
|
+
// imports it.
|
|
4
|
+
|
|
5
|
+
import { basename, extname } from "node:path";
|
|
6
|
+
import type { MetaDataFormat, MetaDataSource } from "../loader/meta-data-source.js";
|
|
7
|
+
|
|
8
|
+
/** Infer a source format from a file extension. `.yaml`/`.yml` → "yaml";
|
|
9
|
+
* everything else (including `.json`) → "json", the canonical default. */
|
|
10
|
+
function inferFormat(path: string): MetaDataFormat {
|
|
11
|
+
const ext = extname(path).toLowerCase();
|
|
12
|
+
return ext === ".yaml" || ext === ".yml" ? "yaml" : "json";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// File reader — Bun-first (Bun.file().text()) with a Node fallback
|
|
16
|
+
// (node:fs/promises.readFile). Matches CLAUDE.md's Bun-first / Node-compatible policy.
|
|
17
|
+
let _readText: ((path: string) => Promise<string>) | undefined;
|
|
18
|
+
|
|
19
|
+
async function getReadText(): Promise<(path: string) => Promise<string>> {
|
|
20
|
+
if (_readText !== undefined) return _readText;
|
|
21
|
+
if (typeof Bun !== "undefined") {
|
|
22
|
+
_readText = (p) => Bun.file(p).text();
|
|
23
|
+
} else {
|
|
24
|
+
const { readFile } = await import("node:fs/promises");
|
|
25
|
+
_readText = (p) => readFile(p, "utf-8");
|
|
26
|
+
}
|
|
27
|
+
return _readText;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** A metadata source backed by a file on disk. */
|
|
31
|
+
export class FileSource implements MetaDataSource {
|
|
32
|
+
readonly id: string;
|
|
33
|
+
readonly format: MetaDataFormat;
|
|
34
|
+
private readonly _path: string;
|
|
35
|
+
|
|
36
|
+
constructor(path: string) {
|
|
37
|
+
this._path = path;
|
|
38
|
+
// basename() for readable error messages; cross-platform (handles both / and \). Full path retained for read().
|
|
39
|
+
this.id = basename(path);
|
|
40
|
+
this.format = inferFormat(path);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** The absolute/relative path this source reads from. */
|
|
44
|
+
get path(): string {
|
|
45
|
+
return this._path;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async read(): Promise<string> {
|
|
49
|
+
const readText = await getReadText();
|
|
50
|
+
return readText(this._path);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Identity concern constants — subtypes, attr keys, and generation strategy values.
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Identity subtypes (3: primary, secondary, reference — NO base; Java doesn't register one)
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
export const IDENTITY_SUBTYPE_PRIMARY = "primary";
|
|
8
|
+
export const IDENTITY_SUBTYPE_SECONDARY = "secondary";
|
|
9
|
+
export const IDENTITY_SUBTYPE_REFERENCE = "reference";
|
|
10
|
+
|
|
11
|
+
export const IDENTITY_SUBTYPES = [
|
|
12
|
+
IDENTITY_SUBTYPE_PRIMARY,
|
|
13
|
+
IDENTITY_SUBTYPE_SECONDARY,
|
|
14
|
+
IDENTITY_SUBTYPE_REFERENCE,
|
|
15
|
+
] as const;
|
|
16
|
+
export type IdentitySubType = (typeof IDENTITY_SUBTYPES)[number];
|
|
17
|
+
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Identity attrs
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
export const IDENTITY_ATTR_FIELDS = "fields";
|
|
23
|
+
export const IDENTITY_ATTR_GENERATION = "generation";
|
|
24
|
+
/** On secondary identities: true → uniqueIndex; false/absent → index. Defaults to true for back-compat. */
|
|
25
|
+
export const IDENTITY_ATTR_UNIQUE = "unique";
|
|
26
|
+
/** Identity-reference attr: target entity (bare or dotted `Entity.field` / `Entity.fA,fB`). */
|
|
27
|
+
export const IDENTITY_REFERENCE_ATTR_REFERENCES = "references";
|
|
28
|
+
/** Identity-reference attr: physical-enforcement flag. Default true → hard FK constraint; false → logical-only reference. */
|
|
29
|
+
export const IDENTITY_REFERENCE_ATTR_ENFORCE = "enforce";
|
|
30
|
+
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Identity generation strategies (values for IDENTITY_ATTR_GENERATION)
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
export const GENERATION_INCREMENT = "increment";
|
|
36
|
+
export const GENERATION_UUID = "uuid";
|
|
37
|
+
export const GENERATION_ASSIGNED = "assigned";
|
|
38
|
+
|
|
39
|
+
export const GENERATION_VALUES = [
|
|
40
|
+
GENERATION_INCREMENT,
|
|
41
|
+
GENERATION_UUID,
|
|
42
|
+
GENERATION_ASSIGNED,
|
|
43
|
+
] as const;
|
|
44
|
+
export type GenerationValue = (typeof GENERATION_VALUES)[number];
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Identity attribute schemas — per-subtype attr inventories for identity types.
|
|
2
|
+
// Consumed by registerCoreTypes().
|
|
3
|
+
|
|
4
|
+
import type { AttrSchema } from "../../registry.js";
|
|
5
|
+
import {
|
|
6
|
+
ATTR_SUBTYPE_STRING,
|
|
7
|
+
ATTR_SUBTYPE_BOOLEAN,
|
|
8
|
+
ATTR_SUBTYPE_STRINGARRAY,
|
|
9
|
+
} from "../attr/attr-constants.js";
|
|
10
|
+
import {
|
|
11
|
+
IDENTITY_SUBTYPE_PRIMARY,
|
|
12
|
+
IDENTITY_SUBTYPE_SECONDARY,
|
|
13
|
+
IDENTITY_SUBTYPE_REFERENCE,
|
|
14
|
+
IDENTITY_ATTR_FIELDS,
|
|
15
|
+
IDENTITY_ATTR_GENERATION,
|
|
16
|
+
IDENTITY_ATTR_UNIQUE,
|
|
17
|
+
IDENTITY_REFERENCE_ATTR_REFERENCES,
|
|
18
|
+
IDENTITY_REFERENCE_ATTR_ENFORCE,
|
|
19
|
+
GENERATION_VALUES,
|
|
20
|
+
} from "./identity-constants.js";
|
|
21
|
+
|
|
22
|
+
/** Attrs on identity.primary / identity.secondary — @fields is required. */
|
|
23
|
+
export const identityFieldsAttr: AttrSchema = {
|
|
24
|
+
name: IDENTITY_ATTR_FIELDS,
|
|
25
|
+
valueType: ATTR_SUBTYPE_STRINGARRAY,
|
|
26
|
+
required: true,
|
|
27
|
+
description:
|
|
28
|
+
"The field name(s) composing this identity. Single-element for a simple PK/index, multiple for a composite.",
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const primaryIdentityAttrs: AttrSchema[] = [
|
|
32
|
+
{ ...identityFieldsAttr },
|
|
33
|
+
{
|
|
34
|
+
name: IDENTITY_ATTR_GENERATION,
|
|
35
|
+
valueType: ATTR_SUBTYPE_STRING,
|
|
36
|
+
required: false,
|
|
37
|
+
allowedValues: [...GENERATION_VALUES],
|
|
38
|
+
description:
|
|
39
|
+
"Primary-key value generation strategy: 'increment' (auto-increment), 'uuid', or 'assigned' (caller-supplied).",
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const secondaryIdentityAttrs: AttrSchema[] = [
|
|
44
|
+
{ ...identityFieldsAttr },
|
|
45
|
+
{
|
|
46
|
+
name: IDENTITY_ATTR_UNIQUE,
|
|
47
|
+
valueType: ATTR_SUBTYPE_BOOLEAN,
|
|
48
|
+
required: false,
|
|
49
|
+
description:
|
|
50
|
+
"When true (default), the secondary identity is a UNIQUE index; false makes it a plain (non-unique) index.",
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
const referenceIdentityAttrs: AttrSchema[] = [
|
|
55
|
+
{ ...identityFieldsAttr },
|
|
56
|
+
{
|
|
57
|
+
name: IDENTITY_REFERENCE_ATTR_REFERENCES,
|
|
58
|
+
valueType: ATTR_SUBTYPE_STRING,
|
|
59
|
+
required: true,
|
|
60
|
+
description:
|
|
61
|
+
"Target of the reference. Bare entity name (e.g. 'Program') resolves to that entity's primary identity. " +
|
|
62
|
+
"Dotted forms ('Program.id' or 'Program.fieldA,fieldB') target an explicit field set on the entity.",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: IDENTITY_REFERENCE_ATTR_ENFORCE,
|
|
66
|
+
valueType: ATTR_SUBTYPE_BOOLEAN,
|
|
67
|
+
required: false,
|
|
68
|
+
description:
|
|
69
|
+
"When true (default), the backend physically enforces the reference (SQL FK constraint, " +
|
|
70
|
+
"document validation rule, graph edge guarantee). Set false to declare a logical reference " +
|
|
71
|
+
"for navigation/typing/codegen only — the value may dangle at the backend level.",
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
/** Attrs per identity subtype. primary adds @generation; secondary adds @unique. */
|
|
76
|
+
export const IDENTITY_ATTRS_MAP = new Map<string, AttrSchema[]>([
|
|
77
|
+
[IDENTITY_SUBTYPE_PRIMARY, [...primaryIdentityAttrs]],
|
|
78
|
+
[IDENTITY_SUBTYPE_SECONDARY, [...secondaryIdentityAttrs]],
|
|
79
|
+
[IDENTITY_SUBTYPE_REFERENCE, [...referenceIdentityAttrs]],
|
|
80
|
+
]);
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// MetaIdentity — concrete node class for type=identity nodes.
|
|
2
|
+
// MetaPrimaryIdentity and MetaSecondaryIdentity are co-located subtype classes.
|
|
3
|
+
//
|
|
4
|
+
// Extends MetaData directly: no model wrapper, no metaOf() indirection.
|
|
5
|
+
|
|
6
|
+
import { MetaData } from "../../shared/meta-data.js";
|
|
7
|
+
import {
|
|
8
|
+
IDENTITY_SUBTYPE_PRIMARY,
|
|
9
|
+
IDENTITY_SUBTYPE_SECONDARY,
|
|
10
|
+
IDENTITY_SUBTYPE_REFERENCE,
|
|
11
|
+
IDENTITY_ATTR_FIELDS,
|
|
12
|
+
IDENTITY_ATTR_GENERATION,
|
|
13
|
+
IDENTITY_ATTR_UNIQUE,
|
|
14
|
+
IDENTITY_REFERENCE_ATTR_REFERENCES,
|
|
15
|
+
IDENTITY_REFERENCE_ATTR_ENFORCE,
|
|
16
|
+
} from "./identity-constants.js";
|
|
17
|
+
import type { MetaRoot } from "../../shared/meta-root.js";
|
|
18
|
+
|
|
19
|
+
/** Strongly-typed identity generation strategies. */
|
|
20
|
+
export type IdentityGeneration = "increment" | "uuid" | "assigned";
|
|
21
|
+
|
|
22
|
+
export class MetaIdentity extends MetaData {
|
|
23
|
+
get fields(): string[] {
|
|
24
|
+
const f = this.ownAttr(IDENTITY_ATTR_FIELDS);
|
|
25
|
+
return Array.isArray(f) ? (f as string[]) : [];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Whether the identity enforces uniqueness.
|
|
30
|
+
* Defaults to true; explicit `@unique: false` makes it a non-unique index.
|
|
31
|
+
*/
|
|
32
|
+
get unique(): boolean {
|
|
33
|
+
return this.ownAttr(IDENTITY_ATTR_UNIQUE) !== false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
isPrimary(): boolean {
|
|
37
|
+
return this.subType === IDENTITY_SUBTYPE_PRIMARY;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
isSecondary(): boolean {
|
|
41
|
+
return this.subType === IDENTITY_SUBTYPE_SECONDARY;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
isReference(): boolean {
|
|
45
|
+
return this.subType === IDENTITY_SUBTYPE_REFERENCE;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
isComposite(): boolean {
|
|
49
|
+
return this.fields.length > 1;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Primary identity (the entity's PK). Always unique by definition.
|
|
55
|
+
* Carries `@generation` (increment / uuid / assigned).
|
|
56
|
+
*/
|
|
57
|
+
export class MetaPrimaryIdentity extends MetaIdentity {
|
|
58
|
+
get generation(): IdentityGeneration | undefined {
|
|
59
|
+
const v = this.ownAttr(IDENTITY_ATTR_GENERATION);
|
|
60
|
+
return typeof v === "string" ? (v as IdentityGeneration) : undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Secondary identity — a unique or non-unique index on one or more fields.
|
|
66
|
+
* `@generation` does not apply here.
|
|
67
|
+
*/
|
|
68
|
+
export class MetaSecondaryIdentity extends MetaIdentity {}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Reference identity — a field (or compound field set) on this entity whose
|
|
72
|
+
* value(s) identify an instance of another entity.
|
|
73
|
+
*
|
|
74
|
+
* Maps to: SQL foreign key, document linked reference, graph edge target,
|
|
75
|
+
* OO pointer/reference. Backend-agnostic at the metamodel level.
|
|
76
|
+
*
|
|
77
|
+
* Carries `@references` — either a bare entity name (defaults to that
|
|
78
|
+
* entity's primary identity) or a dotted `Entity.field` or
|
|
79
|
+
* `Entity.fieldA,fieldB` form for explicit field/compound targets.
|
|
80
|
+
*/
|
|
81
|
+
export class MetaReferenceIdentity extends MetaIdentity {
|
|
82
|
+
/** Raw `@references` attr value, unparsed. */
|
|
83
|
+
get referencesRaw(): string | undefined {
|
|
84
|
+
const v = this.ownAttr(IDENTITY_REFERENCE_ATTR_REFERENCES);
|
|
85
|
+
return typeof v === "string" ? v : undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Target entity name (the bit before the dot, or the whole bare value). */
|
|
89
|
+
get targetEntity(): string | undefined {
|
|
90
|
+
const raw = this.referencesRaw;
|
|
91
|
+
if (raw === undefined) return undefined;
|
|
92
|
+
const dotIdx = raw.indexOf(".");
|
|
93
|
+
return dotIdx === -1 ? raw : raw.slice(0, dotIdx);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Whether the reference is physically enforced by the backend.
|
|
98
|
+
* Default true (hard FK constraint emitted). Explicit `@enforce: false`
|
|
99
|
+
* marks the reference as logical-only — drizzle-schema skips `.references()`
|
|
100
|
+
* and migrate-ts's expected schema omits the FK descriptor. relations()
|
|
101
|
+
* block and projection JOIN inference are unaffected.
|
|
102
|
+
*/
|
|
103
|
+
get enforce(): boolean {
|
|
104
|
+
return this.ownAttr(IDENTITY_REFERENCE_ATTR_ENFORCE) !== false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Target field names. Empty array means "use the target's primary identity"
|
|
109
|
+
* (the bare-entity form). For dotted forms, returns the field(s) after the
|
|
110
|
+
* dot (comma-split, trimmed).
|
|
111
|
+
*/
|
|
112
|
+
get targetFields(): string[] {
|
|
113
|
+
const raw = this.referencesRaw;
|
|
114
|
+
if (raw === undefined) return [];
|
|
115
|
+
const dotIdx = raw.indexOf(".");
|
|
116
|
+
if (dotIdx === -1) return [];
|
|
117
|
+
return raw
|
|
118
|
+
.slice(dotIdx + 1)
|
|
119
|
+
.split(",")
|
|
120
|
+
.map((s) => s.trim())
|
|
121
|
+
.filter((s) => s.length > 0);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Resolve the target field on the referenced entity that this reference
|
|
126
|
+
* points at. Priority: explicit dotted-form `@references: "Entity.field"`
|
|
127
|
+
* override → target entity's primary identity field → "id" fallback.
|
|
128
|
+
*
|
|
129
|
+
* Returns undefined only if the target entity cannot be found in `root`.
|
|
130
|
+
* Centralizes the FK-target resolution rule used by projection view DDL,
|
|
131
|
+
* Drizzle schema emit, and migration schema comparison.
|
|
132
|
+
*/
|
|
133
|
+
resolvedTargetPkField(root: MetaRoot): string | undefined {
|
|
134
|
+
const explicit = this.targetFields[0];
|
|
135
|
+
if (explicit !== undefined) return explicit;
|
|
136
|
+
|
|
137
|
+
const targetName = this.targetEntity;
|
|
138
|
+
if (targetName === undefined) return undefined;
|
|
139
|
+
const targetObj = root.findObject(targetName);
|
|
140
|
+
if (!targetObj) return undefined;
|
|
141
|
+
|
|
142
|
+
const primary = targetObj.primaryIdentity();
|
|
143
|
+
const fields = primary?.ownAttr(IDENTITY_ATTR_FIELDS) as string | string[] | undefined;
|
|
144
|
+
if (typeof fields === "string") return fields.split(",")[0]!.trim();
|
|
145
|
+
if (Array.isArray(fields) && fields.length > 0) return String(fields[0]).trim();
|
|
146
|
+
return "id";
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// @metaobjectsdev/metadata/core — server-side capabilities.
|
|
2
|
+
//
|
|
3
|
+
// This entry point holds everything that touches node:fs or the `yaml`
|
|
4
|
+
// dependency: the file loaders, the YAML authoring parser, and the
|
|
5
|
+
// load-and-export convenience. The root `@metaobjectsdev/metadata` entry is
|
|
6
|
+
// browser-safe and imports none of this. See the package README.
|
|
7
|
+
|
|
8
|
+
export { FileSource } from "./file-source.js";
|
|
9
|
+
export { FileMetaDataLoader } from "./file-meta-data-loader.js";
|
|
10
|
+
export { parseYaml } from "./parser-yaml.js";
|
|
11
|
+
export { loadAndExportJson } from "./export-json.js";
|
|
12
|
+
export type { ExportResult } from "./export-json.js";
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// MetaObject — concrete node class for type=object nodes.
|
|
2
|
+
//
|
|
3
|
+
// Extends MetaData directly: no model wrapper, no metaOf() indirection.
|
|
4
|
+
// Children are already concrete typed nodes; accessors filter by type constant.
|
|
5
|
+
|
|
6
|
+
import { MetaData } from "../../shared/meta-data.js";
|
|
7
|
+
import {
|
|
8
|
+
TYPE_FIELD,
|
|
9
|
+
TYPE_IDENTITY,
|
|
10
|
+
TYPE_RELATIONSHIP,
|
|
11
|
+
TYPE_VALIDATOR,
|
|
12
|
+
TYPE_SOURCE,
|
|
13
|
+
TYPE_LAYOUT,
|
|
14
|
+
} from "../../shared/base-types.js";
|
|
15
|
+
import {
|
|
16
|
+
SOURCE_SUBTYPE_DB_TABLE,
|
|
17
|
+
SOURCE_DB_TABLE_ATTR_NAME,
|
|
18
|
+
} from "../../persistence/source/source-constants.js";
|
|
19
|
+
import {
|
|
20
|
+
OBJECT_SUBTYPE_ENTITY,
|
|
21
|
+
OBJECT_SUBTYPE_VALUE,
|
|
22
|
+
} from "./object-constants.js";
|
|
23
|
+
import {
|
|
24
|
+
IDENTITY_SUBTYPE_PRIMARY,
|
|
25
|
+
IDENTITY_SUBTYPE_SECONDARY,
|
|
26
|
+
IDENTITY_SUBTYPE_REFERENCE,
|
|
27
|
+
} from "../identity/identity-constants.js";
|
|
28
|
+
import type { MetaField } from "../field/meta-field.js";
|
|
29
|
+
import type { MetaIdentity, MetaReferenceIdentity } from "../identity/meta-identity.js";
|
|
30
|
+
import type { MetaLayout } from "../../presentation/layout/meta-layout.js";
|
|
31
|
+
import type { MetaRelationship } from "../relationship/meta-relationship.js";
|
|
32
|
+
import type { MetaValidator } from "../validator/meta-validator.js";
|
|
33
|
+
|
|
34
|
+
export class MetaObject extends MetaData {
|
|
35
|
+
get dbTable(): string | undefined {
|
|
36
|
+
return this.cached("dbTable", () => {
|
|
37
|
+
const source = this.children().find(
|
|
38
|
+
(c) => c.type === TYPE_SOURCE && c.subType === SOURCE_SUBTYPE_DB_TABLE,
|
|
39
|
+
);
|
|
40
|
+
const name = source?.ownAttr(SOURCE_DB_TABLE_ATTR_NAME);
|
|
41
|
+
return typeof name === "string" && name !== "" ? name : undefined;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
isEntity(): boolean {
|
|
46
|
+
return this.subType === OBJECT_SUBTYPE_ENTITY;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
isValue(): boolean {
|
|
50
|
+
return this.subType === OBJECT_SUBTYPE_VALUE;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** All effective fields (own + inherited via extends). */
|
|
54
|
+
fields(): MetaField[] {
|
|
55
|
+
return this.cached("fields", () =>
|
|
56
|
+
this.children().filter((c): c is MetaField => c.type === TYPE_FIELD),
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Own fields only — excludes fields inherited via extends. Java parity: getMetaFields(false). */
|
|
61
|
+
ownFields(): MetaField[] {
|
|
62
|
+
return this.cached("ownFields", () =>
|
|
63
|
+
this.ownChildren().filter((c): c is MetaField => c.type === TYPE_FIELD),
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** All effective identities (own + inherited via extends). */
|
|
68
|
+
identities(): MetaIdentity[] {
|
|
69
|
+
return this.cached("identities", () =>
|
|
70
|
+
this.children().filter((c): c is MetaIdentity => c.type === TYPE_IDENTITY),
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Own identities only — excludes inherited. */
|
|
75
|
+
ownIdentities(): MetaIdentity[] {
|
|
76
|
+
return this.cached("ownIdentities", () =>
|
|
77
|
+
this.ownChildren().filter((c): c is MetaIdentity => c.type === TYPE_IDENTITY),
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Returns the single primary identity, if any. */
|
|
82
|
+
primaryIdentity(): MetaIdentity | undefined {
|
|
83
|
+
return this.cached("primaryIdentity", () =>
|
|
84
|
+
this.identities().find((i) => i.subType === IDENTITY_SUBTYPE_PRIMARY),
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Secondary identities. */
|
|
89
|
+
secondaryIdentities(): MetaIdentity[] {
|
|
90
|
+
return this.cached("secondaryIdentities", () =>
|
|
91
|
+
this.identities().filter((i) => i.subType === IDENTITY_SUBTYPE_SECONDARY),
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Reference identities — fields on this entity that identify another entity. */
|
|
96
|
+
referenceIdentities(): MetaReferenceIdentity[] {
|
|
97
|
+
return this.cached("referenceIdentities", () =>
|
|
98
|
+
this.identities().filter((i): i is MetaReferenceIdentity =>
|
|
99
|
+
i.subType === IDENTITY_SUBTYPE_REFERENCE,
|
|
100
|
+
),
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** All effective relationships (own + inherited via extends). */
|
|
105
|
+
relationships(): MetaRelationship[] {
|
|
106
|
+
return this.cached("relationships", () =>
|
|
107
|
+
this.children().filter((c): c is MetaRelationship => c.type === TYPE_RELATIONSHIP),
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Own relationships only — excludes inherited. */
|
|
112
|
+
ownRelationships(): MetaRelationship[] {
|
|
113
|
+
return this.cached("ownRelationships", () =>
|
|
114
|
+
this.ownChildren().filter((c): c is MetaRelationship => c.type === TYPE_RELATIONSHIP),
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** All effective validators (own + inherited via extends). */
|
|
119
|
+
validators(): MetaValidator[] {
|
|
120
|
+
return this.cached("validators", () =>
|
|
121
|
+
this.children().filter((c): c is MetaValidator => c.type === TYPE_VALIDATOR),
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Own validators only — excludes validators inherited via extends. Java parity: getChildren(Class, false). */
|
|
126
|
+
ownValidators(): MetaValidator[] {
|
|
127
|
+
return this.cached("ownValidators", () =>
|
|
128
|
+
this.ownChildren().filter((c): c is MetaValidator => c.type === TYPE_VALIDATOR),
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** All effective layouts (own + inherited via extends). */
|
|
133
|
+
layouts(): MetaLayout[] {
|
|
134
|
+
return this.cached("layouts", () =>
|
|
135
|
+
this.children().filter((c): c is MetaLayout => c.type === TYPE_LAYOUT),
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Own layouts only — excludes inherited. */
|
|
140
|
+
ownLayouts(): MetaLayout[] {
|
|
141
|
+
return this.cached("ownLayouts", () =>
|
|
142
|
+
this.ownChildren().filter((c): c is MetaLayout => c.type === TYPE_LAYOUT),
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
findField(name: string): MetaField | undefined {
|
|
147
|
+
return this.cached(`findField:${name}`, () =>
|
|
148
|
+
this.fields().find((f) => f.name === name),
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Object concern constants — subtypes for the object.* type family.
|
|
2
|
+
|
|
3
|
+
import { SUBTYPE_BASE } from "../../shared/base-types.js";
|
|
4
|
+
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Object subtypes (cross-language, conceptual)
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
//
|
|
9
|
+
// - base : abstract template (no runtime semantics)
|
|
10
|
+
// - entity : persistent record (typically has @primary identity)
|
|
11
|
+
// - value : value-object (no identity; equality by content)
|
|
12
|
+
//
|
|
13
|
+
export const OBJECT_SUBTYPE_ENTITY = "entity";
|
|
14
|
+
export const OBJECT_SUBTYPE_VALUE = "value";
|
|
15
|
+
|
|
16
|
+
export const OBJECT_SUBTYPES = [
|
|
17
|
+
SUBTYPE_BASE,
|
|
18
|
+
OBJECT_SUBTYPE_ENTITY,
|
|
19
|
+
OBJECT_SUBTYPE_VALUE,
|
|
20
|
+
] as const;
|
|
21
|
+
export type ObjectSubType = (typeof OBJECT_SUBTYPES)[number];
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Authoring YAML parser.
|
|
2
|
+
//
|
|
3
|
+
// parseYaml is a front-end: yaml.parse → desugar → the shared buildTree
|
|
4
|
+
// (parser-core.ts). The desugar applies the four authoring-sugar rules so the
|
|
5
|
+
// resulting typed tree is identical to the one the equivalent canonical JSON
|
|
6
|
+
// produces.
|
|
7
|
+
|
|
8
|
+
import { parse as parseYamlText } from "yaml";
|
|
9
|
+
import { ParseError } from "../errors.js";
|
|
10
|
+
import { buildTree, errOpts } from "../parser-core.js";
|
|
11
|
+
import type { ParseOptions, ParseResult } from "../parser-core.js";
|
|
12
|
+
import { desugar } from "./yaml-desugar.js";
|
|
13
|
+
|
|
14
|
+
export function parseYaml(content: string, opts: ParseOptions): ParseResult {
|
|
15
|
+
// Strip UTF-8 BOM if present (consistent with parseJson).
|
|
16
|
+
const normalizedContent =
|
|
17
|
+
content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;
|
|
18
|
+
|
|
19
|
+
// YAML syntax errors throw — consistent with parseJson on invalid JSON.
|
|
20
|
+
// The loader's per-source try/catch collects the throw into LoadResult.errors.
|
|
21
|
+
let parsed: unknown;
|
|
22
|
+
try {
|
|
23
|
+
parsed = parseYamlText(normalizedContent);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
throw new ParseError(
|
|
26
|
+
`Invalid YAML: ${(err as Error).message}`,
|
|
27
|
+
{ ...errOpts(opts.sourceName), code: "ERR_MALFORMED_YAML" },
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Desugar the sugared authoring object into the canonical structure.
|
|
32
|
+
const { canonical, errors: desugarErrors } = desugar(parsed, opts.registry);
|
|
33
|
+
|
|
34
|
+
// If the desugar could not produce a usable document at all, surface the
|
|
35
|
+
// first desugar error as a throw — parallels parseJson's top-level throws.
|
|
36
|
+
if (Object.keys(canonical).length === 0) {
|
|
37
|
+
throw new ParseError(
|
|
38
|
+
desugarErrors[0]!,
|
|
39
|
+
{ ...errOpts(opts.sourceName), code: "ERR_MALFORMED_YAML" },
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const result = buildTree(canonical, opts);
|
|
44
|
+
|
|
45
|
+
// Merge collected desugar errors ahead of buildTree's own collected errors.
|
|
46
|
+
const desugarParseErrors = desugarErrors.map(
|
|
47
|
+
(msg) => new ParseError(msg, { ...errOpts(opts.sourceName), code: "ERR_MALFORMED_YAML" }),
|
|
48
|
+
);
|
|
49
|
+
return {
|
|
50
|
+
root: result.root,
|
|
51
|
+
warnings: result.warnings,
|
|
52
|
+
errors: [...desugarParseErrors, ...result.errors],
|
|
53
|
+
};
|
|
54
|
+
}
|