@metaobjectsdev/metadata 1.0.12 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/attr-schema-validate.d.ts.map +1 -1
- package/dist/attr-schema-validate.js +9 -12
- package/dist/attr-schema-validate.js.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/core/attr/meta-attr-filter.d.ts.map +1 -1
- package/dist/core/attr/meta-attr-filter.js +8 -2
- package/dist/core/attr/meta-attr-filter.js.map +1 -1
- package/dist/core/attr/meta-attr.d.ts +14 -0
- package/dist/core/attr/meta-attr.d.ts.map +1 -1
- package/dist/core/attr/meta-attr.js +23 -1
- package/dist/core/attr/meta-attr.js.map +1 -1
- package/dist/core/field/shared-enum.d.ts +21 -0
- package/dist/core/field/shared-enum.d.ts.map +1 -0
- package/dist/core/field/shared-enum.js +49 -0
- package/dist/core/field/shared-enum.js.map +1 -0
- package/dist/core/identity/meta-identity.d.ts +1 -1
- package/dist/core/identity/meta-identity.d.ts.map +1 -1
- package/dist/core/identity/meta-identity.js +8 -13
- package/dist/core/identity/meta-identity.js.map +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/object/object-constants.d.ts +14 -1
- package/dist/core/object/object-constants.d.ts.map +1 -1
- package/dist/core/object/object-constants.js +18 -0
- package/dist/core/object/object-constants.js.map +1 -1
- package/dist/core/object/object-definition.embedded.d.ts.map +1 -1
- package/dist/core/object/object-definition.embedded.js +80 -0
- package/dist/core/object/object-definition.embedded.js.map +1 -1
- package/dist/core/relationship/derive-m2m-fields.d.ts +1 -1
- package/dist/core/relationship/derive-m2m-fields.d.ts.map +1 -1
- package/dist/core/relationship/derive-m2m-fields.js +15 -44
- package/dist/core/relationship/derive-m2m-fields.js.map +1 -1
- package/dist/core/relationship/find-reference.d.ts.map +1 -1
- package/dist/core/relationship/find-reference.js +4 -2
- package/dist/core/relationship/find-reference.js.map +1 -1
- package/dist/core/relationship/resolve-relationship-reference.d.ts +6 -5
- package/dist/core/relationship/resolve-relationship-reference.d.ts.map +1 -1
- package/dist/core/relationship/resolve-relationship-reference.js +9 -7
- package/dist/core/relationship/resolve-relationship-reference.js.map +1 -1
- package/dist/core/reporting/meta-dimension.d.ts +13 -0
- package/dist/core/reporting/meta-dimension.d.ts.map +1 -0
- package/dist/core/reporting/meta-dimension.js +30 -0
- package/dist/core/reporting/meta-dimension.js.map +1 -0
- package/dist/core/reporting/meta-measure.d.ts +24 -0
- package/dist/core/reporting/meta-measure.d.ts.map +1 -0
- package/dist/core/reporting/meta-measure.js +54 -0
- package/dist/core/reporting/meta-measure.js.map +1 -0
- package/dist/core/reporting/meta-segment.d.ts +6 -0
- package/dist/core/reporting/meta-segment.d.ts.map +1 -0
- package/dist/core/reporting/meta-segment.js +13 -0
- package/dist/core/reporting/meta-segment.js.map +1 -0
- package/dist/core/reporting/report-accessors.d.ts +27 -0
- package/dist/core/reporting/report-accessors.d.ts.map +1 -0
- package/dist/core/reporting/report-accessors.js +56 -0
- package/dist/core/reporting/report-accessors.js.map +1 -0
- package/dist/core/reporting/report-describe.d.ts +59 -0
- package/dist/core/reporting/report-describe.d.ts.map +1 -0
- package/dist/core/reporting/report-describe.js +182 -0
- package/dist/core/reporting/report-describe.js.map +1 -0
- package/dist/core/reporting/report-read-model.d.ts +34 -0
- package/dist/core/reporting/report-read-model.d.ts.map +1 -0
- package/dist/core/reporting/report-read-model.js +165 -0
- package/dist/core/reporting/report-read-model.js.map +1 -0
- package/dist/core/reporting/report-shape.d.ts +103 -0
- package/dist/core/reporting/report-shape.d.ts.map +1 -0
- package/dist/core/reporting/report-shape.js +398 -0
- package/dist/core/reporting/report-shape.js.map +1 -0
- package/dist/core/reporting/reporting-constants.d.ts +65 -0
- package/dist/core/reporting/reporting-constants.d.ts.map +1 -0
- package/dist/core/reporting/reporting-constants.js +84 -0
- package/dist/core/reporting/reporting-constants.js.map +1 -0
- package/dist/core/reporting/reporting-definition.embedded.d.ts +3 -0
- package/dist/core/reporting/reporting-definition.embedded.d.ts.map +1 -0
- package/dist/core/reporting/reporting-definition.embedded.js +185 -0
- package/dist/core/reporting/reporting-definition.embedded.js.map +1 -0
- package/dist/core/requirement/resolve-claim.d.ts +8 -0
- package/dist/core/requirement/resolve-claim.d.ts.map +1 -1
- package/dist/core/requirement/resolve-claim.js +21 -0
- package/dist/core/requirement/resolve-claim.js.map +1 -1
- package/dist/core/yaml-desugar.d.ts.map +1 -1
- package/dist/core/yaml-desugar.js +12 -82
- package/dist/core/yaml-desugar.js.map +1 -1
- package/dist/core-types.d.ts.map +1 -1
- package/dist/core-types.js +28 -1
- package/dist/core-types.js.map +1 -1
- package/dist/docs-ref.d.ts +19 -0
- package/dist/docs-ref.d.ts.map +1 -0
- package/dist/docs-ref.js +37 -0
- package/dist/docs-ref.js.map +1 -0
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +24 -6
- package/dist/errors.js.map +1 -1
- package/dist/fmt.d.ts.map +1 -1
- package/dist/fmt.js +3 -1
- package/dist/fmt.js.map +1 -1
- package/dist/index.d.ts +15 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -4
- package/dist/index.js.map +1 -1
- package/dist/loader/declared-duplicate-fields.d.ts +19 -0
- package/dist/loader/declared-duplicate-fields.d.ts.map +1 -0
- package/dist/loader/declared-duplicate-fields.js +97 -0
- package/dist/loader/declared-duplicate-fields.js.map +1 -0
- package/dist/loader/meta-data-loader.d.ts.map +1 -1
- package/dist/loader/meta-data-loader.js +18 -1
- package/dist/loader/meta-data-loader.js.map +1 -1
- package/dist/loader/reporting-validation.d.ts +11 -0
- package/dist/loader/reporting-validation.d.ts.map +1 -0
- package/dist/loader/reporting-validation.js +883 -0
- package/dist/loader/reporting-validation.js.map +1 -0
- package/dist/loader/resolve-references.d.ts +8 -0
- package/dist/loader/resolve-references.d.ts.map +1 -0
- package/dist/loader/resolve-references.js +132 -0
- package/dist/loader/resolve-references.js.map +1 -0
- package/dist/loader/validation-passes.d.ts.map +1 -1
- package/dist/loader/validation-passes.js +14 -9
- package/dist/loader/validation-passes.js.map +1 -1
- package/dist/loader/validation-registry.d.ts.map +1 -1
- package/dist/loader/validation-registry.js +33 -10
- package/dist/loader/validation-registry.js.map +1 -1
- package/dist/metamodel-docs/index.js +3 -3
- package/dist/metamodel-docs/index.js.map +1 -1
- package/dist/metamodel-docs/render.js +4 -4
- package/dist/metamodel-docs/render.js.map +1 -1
- package/dist/naming-refs.d.ts +102 -50
- package/dist/naming-refs.d.ts.map +1 -1
- package/dist/naming-refs.js +223 -97
- package/dist/naming-refs.js.map +1 -1
- package/dist/naming.d.ts +65 -7
- package/dist/naming.d.ts.map +1 -1
- package/dist/naming.js +98 -5
- package/dist/naming.js.map +1 -1
- package/dist/object-serializer.d.ts.map +1 -1
- package/dist/object-serializer.js +6 -9
- package/dist/object-serializer.js.map +1 -1
- package/dist/parser-core.d.ts.map +1 -1
- package/dist/parser-core.js +18 -48
- package/dist/parser-core.js.map +1 -1
- package/dist/persistence/db/db-definition.embedded.js +2 -2
- package/dist/persistence/db/db-definition.embedded.js.map +1 -1
- package/dist/persistence/source/meta-source.d.ts +5 -2
- package/dist/persistence/source/meta-source.d.ts.map +1 -1
- package/dist/persistence/source/meta-source.js +10 -6
- package/dist/persistence/source/meta-source.js.map +1 -1
- package/dist/registry-manifest-exclusions.js +2 -2
- package/dist/registry-manifest-exclusions.js.map +1 -1
- package/dist/registry-manifest.d.ts +1 -1
- package/dist/registry-manifest.js +1 -1
- package/dist/release-docs.d.ts +11 -0
- package/dist/release-docs.d.ts.map +1 -0
- package/dist/release-docs.js +48 -0
- package/dist/release-docs.js.map +1 -0
- package/dist/serializer-json.d.ts +15 -1
- package/dist/serializer-json.d.ts.map +1 -1
- package/dist/serializer-json.js +55 -17
- package/dist/serializer-json.js.map +1 -1
- package/dist/shared/base-types.d.ts +7 -1
- package/dist/shared/base-types.d.ts.map +1 -1
- package/dist/shared/base-types.js +9 -0
- package/dist/shared/base-types.js.map +1 -1
- package/dist/shared/meta-data.d.ts +10 -0
- package/dist/shared/meta-data.d.ts.map +1 -1
- package/dist/shared/meta-data.js +22 -1
- package/dist/shared/meta-data.js.map +1 -1
- package/dist/shared/meta-root.d.ts +13 -1
- package/dist/shared/meta-root.d.ts.map +1 -1
- package/dist/shared/meta-root.js +19 -1
- package/dist/shared/meta-root.js.map +1 -1
- package/dist/super-resolve.d.ts +4 -1
- package/dist/super-resolve.d.ts.map +1 -1
- package/dist/super-resolve.js +44 -65
- package/dist/super-resolve.js.map +1 -1
- package/dist/vocabulary-catalog.js +2 -2
- package/dist/vocabulary-catalog.js.map +1 -1
- package/package.json +6 -1
- package/src/attr-schema-validate.ts +9 -13
- package/src/constants.ts +1 -0
- package/src/core/attr/meta-attr-filter.ts +8 -1
- package/src/core/attr/meta-attr.ts +24 -1
- package/src/core/field/shared-enum.ts +53 -0
- package/src/core/identity/meta-identity.ts +9 -12
- package/src/core/index.ts +5 -0
- package/src/core/object/object-constants.ts +19 -0
- package/src/core/object/object-definition.embedded.ts +80 -0
- package/src/core/relationship/derive-m2m-fields.ts +15 -48
- package/src/core/relationship/find-reference.ts +4 -2
- package/src/core/relationship/resolve-relationship-reference.ts +11 -9
- package/src/core/reporting/meta-dimension.ts +41 -0
- package/src/core/reporting/meta-measure.ts +75 -0
- package/src/core/reporting/meta-segment.ts +14 -0
- package/src/core/reporting/report-accessors.ts +73 -0
- package/src/core/reporting/report-describe.ts +206 -0
- package/src/core/reporting/report-read-model.ts +177 -0
- package/src/core/reporting/report-shape.ts +493 -0
- package/src/core/reporting/reporting-constants.ts +104 -0
- package/src/core/reporting/reporting-definition.embedded.ts +192 -0
- package/src/core/requirement/resolve-claim.ts +20 -0
- package/src/core/yaml-desugar.ts +9 -89
- package/src/core-types.ts +41 -0
- package/src/docs-ref.ts +41 -0
- package/src/errors.ts +24 -6
- package/src/fmt.ts +3 -1
- package/src/index.ts +73 -5
- package/src/loader/declared-duplicate-fields.ts +114 -0
- package/src/loader/meta-data-loader.ts +25 -1
- package/src/loader/reporting-validation.ts +1137 -0
- package/src/loader/resolve-references.ts +144 -0
- package/src/loader/validation-passes.ts +13 -9
- package/src/loader/validation-registry.ts +37 -9
- package/src/metamodel-docs/index.ts +3 -3
- package/src/metamodel-docs/render.ts +4 -4
- package/src/naming-refs.ts +237 -94
- package/src/naming.ts +131 -11
- package/src/object-serializer.ts +7 -9
- package/src/parser-core.ts +19 -56
- package/src/persistence/db/db-definition.embedded.ts +2 -2
- package/src/persistence/source/meta-source.ts +10 -6
- package/src/registry-manifest-exclusions.ts +2 -2
- package/src/registry-manifest.ts +1 -1
- package/src/release-docs.ts +48 -0
- package/src/serializer-json.ts +79 -12
- package/src/shared/base-types.ts +9 -0
- package/src/shared/meta-data.ts +22 -1
- package/src/shared/meta-root.ts +20 -1
- package/src/super-resolve.ts +49 -63
- package/src/vocabulary-catalog.ts +2 -2
package/src/index.ts
CHANGED
|
@@ -42,9 +42,52 @@ export * from "./core/identity/identity-constants.js";
|
|
|
42
42
|
export * from "./core/index/index-constants.js";
|
|
43
43
|
export * from "./core/requirement/requirement-constants.js";
|
|
44
44
|
export { MetaRequirement } from "./core/requirement/meta-requirement.js";
|
|
45
|
+
export * from "./core/reporting/reporting-constants.js";
|
|
46
|
+
export { MetaDimension } from "./core/reporting/meta-dimension.js";
|
|
47
|
+
export { MetaMeasure } from "./core/reporting/meta-measure.js";
|
|
48
|
+
export { MetaSegment } from "./core/reporting/meta-segment.js";
|
|
49
|
+
export {
|
|
50
|
+
reportFrom,
|
|
51
|
+
reportSpine,
|
|
52
|
+
reportDimensionItems,
|
|
53
|
+
reportMeasureNames,
|
|
54
|
+
reportMeasureItemName,
|
|
55
|
+
reportMeasureItemOwner,
|
|
56
|
+
reportDerivedFieldName,
|
|
57
|
+
type ReportDimensionItem,
|
|
58
|
+
} from "./core/reporting/report-accessors.js";
|
|
59
|
+
export {
|
|
60
|
+
measureDerivedSubType,
|
|
61
|
+
reportShape,
|
|
62
|
+
reportSpineEntity,
|
|
63
|
+
reportSpineHops,
|
|
64
|
+
reportingMemberOwner,
|
|
65
|
+
reportingViaHops,
|
|
66
|
+
resolveReportingFieldRef,
|
|
67
|
+
resolveDimensionOf,
|
|
68
|
+
type ReportField,
|
|
69
|
+
type ReportFieldRole,
|
|
70
|
+
type ReportShape,
|
|
71
|
+
} from "./core/reporting/report-shape.js";
|
|
72
|
+
export { reportReadModel, reportReadSource } from "./core/reporting/report-read-model.js";
|
|
73
|
+
export {
|
|
74
|
+
describeDimension,
|
|
75
|
+
describeDimensionColumn,
|
|
76
|
+
describeFilter,
|
|
77
|
+
describeMeasure,
|
|
78
|
+
describeReportField,
|
|
79
|
+
describeReportRowScope,
|
|
80
|
+
describeReportRows,
|
|
81
|
+
describeRowScope,
|
|
82
|
+
describeSegment,
|
|
83
|
+
reportFieldTypeName,
|
|
84
|
+
reportNotServedReason,
|
|
85
|
+
reportingDescribedAttrs,
|
|
86
|
+
} from "./core/reporting/report-describe.js";
|
|
45
87
|
// Shared `@implementedBy` resolution — one resolver for the CLI's requirement
|
|
46
88
|
// checks and codegen's requirement-test fan-out (FR-038).
|
|
47
89
|
export {
|
|
90
|
+
effectiveRequirementPackage,
|
|
48
91
|
resolveClaim,
|
|
49
92
|
resolveClaimTarget,
|
|
50
93
|
resolveMember,
|
|
@@ -81,6 +124,9 @@ export {
|
|
|
81
124
|
// Core node classes
|
|
82
125
|
export { MetaObject } from "./core/object/meta-object.js";
|
|
83
126
|
export { MetaField } from "./core/field/meta-field.js";
|
|
127
|
+
// The one authority for "which type does this enum field have" — the loader's #246
|
|
128
|
+
// check and every codegen site share it (ADR-0026 Amendment 1).
|
|
129
|
+
export { isSharedEnumDeclaration, resolveSharedEnumDeclaration } from "./core/field/shared-enum.js";
|
|
84
130
|
export { MetaAttr } from "./core/attr/meta-attr.js";
|
|
85
131
|
|
|
86
132
|
// Runtime object model — backing objects + FQN→factory binding (Phase A).
|
|
@@ -193,7 +239,7 @@ export { ExclusionReason } from "./registry-manifest-exclusions.js";
|
|
|
193
239
|
|
|
194
240
|
// FR-033 S3 — metamodel doc-gen: tiered, LLM-readable docs FOR THE METAMODEL
|
|
195
241
|
// (the type/subtype/attr vocabulary), generated from the strict registry.
|
|
196
|
-
// Distinct from `
|
|
242
|
+
// Distinct from the `docs` generator (which documents a user's entities).
|
|
197
243
|
export {
|
|
198
244
|
renderMetamodelDocs,
|
|
199
245
|
buildMetamodelProvenance,
|
|
@@ -251,7 +297,22 @@ export type { FormatFileOptions, FormatFileResult } from "./fmt.js";
|
|
|
251
297
|
export { resolveSuperRef } from "./super-resolve.js";
|
|
252
298
|
|
|
253
299
|
// FR-032 (ADR-0032) — canonical reference expansion + FQN object matching.
|
|
254
|
-
export {
|
|
300
|
+
export {
|
|
301
|
+
expandRef,
|
|
302
|
+
isRelativeRef,
|
|
303
|
+
refMatchesObject,
|
|
304
|
+
resolveObjectRef,
|
|
305
|
+
resolveRef,
|
|
306
|
+
lookupCanonical,
|
|
307
|
+
refTarget,
|
|
308
|
+
spellRef,
|
|
309
|
+
splitChildTail,
|
|
310
|
+
RefOverDropError,
|
|
311
|
+
didYouMeanHint,
|
|
312
|
+
didYouMeanSuperHint,
|
|
313
|
+
REF_BEARING_ATTR_NAMES,
|
|
314
|
+
} from "./naming-refs.js";
|
|
315
|
+
export { resolveReferences } from "./loader/resolve-references.js";
|
|
255
316
|
|
|
256
317
|
// Loader hierarchy
|
|
257
318
|
export { MetaDataLoader, declaredTopLevelKeys } from "./loader/meta-data-loader.js";
|
|
@@ -299,17 +360,24 @@ export type { Scope, CompiledScope } from "./scope.js";
|
|
|
299
360
|
export { validateAttrSchema } from "./attr-schema-validate.js";
|
|
300
361
|
export type { AttrSchemaValidationResult } from "./attr-schema-validate.js";
|
|
301
362
|
|
|
363
|
+
// Guide URLs pinned to the running release's tag (prerelease → main).
|
|
364
|
+
export {
|
|
365
|
+
DOCS_REPO_URL, DOCS_DEFAULT_REF, docsRefForVersion, docsBlobUrl, pinDocsRefs,
|
|
366
|
+
} from "./docs-ref.js";
|
|
367
|
+
|
|
302
368
|
// Naming — hoisted from runtime-ts in v0.2.3 so multiple consumers (runtime-ts, migrate-ts, codegen-ts)
|
|
303
369
|
// share identical name resolution. See spec §4.1.
|
|
304
370
|
export {
|
|
305
|
-
toSnakeCase, toKebabCase, pluralize,
|
|
306
|
-
applyColumnNamingStrategy, DEFAULT_COLUMN_NAMING_STRATEGY,
|
|
371
|
+
toSnakeCase, toKebabCase, pluralize, pluralizeTableNameLegacy,
|
|
372
|
+
applyColumnNamingStrategy, DEFAULT_COLUMN_NAMING_STRATEGY, COLUMN_NAMING_STRATEGIES,
|
|
373
|
+
TABLE_NAMING_RULES, DEFAULT_PHYSICAL_NAMING, physicalNamingOf, applyTableNamingRule,
|
|
374
|
+
PHYSICAL_NAMING_MIGRATION_GUIDE, PHYSICAL_NAMING_MIGRATION_GUIDE_PATH, physicalNamingRemovedMessage,
|
|
307
375
|
resolveTableName, resolveColumnName, resolveTableSchema, resolveIndexName,
|
|
308
376
|
primaryRdbSource, sourceAddressKey,
|
|
309
377
|
buildNameMap,
|
|
310
378
|
stripPackage, packageOfResolutionKey,
|
|
311
379
|
} from "./naming.js";
|
|
312
|
-
export type { EntityNameMap, ColumnNamingStrategy } from "./naming.js";
|
|
380
|
+
export type { EntityNameMap, ColumnNamingStrategy, PhysicalNaming, TableNamingRule } from "./naming.js";
|
|
313
381
|
|
|
314
382
|
// Retired vocabulary: the map the loader reads to explain a retirement, and the raw-document
|
|
315
383
|
// rewriter `meta upgrade` drives from the SAME entries — so the error message and the fix
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// declaredDuplicateFields — structural pre-parse walk for the `meta verify` field lint.
|
|
2
|
+
//
|
|
3
|
+
// Two `field.*` children with the same `name` in ONE object's `children` list load
|
|
4
|
+
// with no error on every port, and the loaded model keeps no trace of it: the parser's
|
|
5
|
+
// merge rule folds the later declaration into the first (a different subtype is
|
|
6
|
+
// discarded outright). So the question "was this field declared twice?" can only be
|
|
7
|
+
// answered from the document, before the merge — the same reason
|
|
8
|
+
// `declaredTopLevelKeys` exists for the overlay lint.
|
|
9
|
+
//
|
|
10
|
+
// Scope, deliberately narrow:
|
|
11
|
+
// - ONE children list. The same field declared in a base file and again in an
|
|
12
|
+
// overlay file is the overlay merge working as designed, and a subtype
|
|
13
|
+
// redeclaring an inherited field is an override. Neither is in one list.
|
|
14
|
+
// - Root-level objects only, addressed by the resolution key the parser gives them.
|
|
15
|
+
|
|
16
|
+
import { TYPE_FIELD, TYPE_METADATA, TYPE_OBJECT, SUBTYPE_ROOT } from "../shared/base-types.js";
|
|
17
|
+
import {
|
|
18
|
+
PACKAGE_SEPARATOR,
|
|
19
|
+
RESERVED_KEY_CHILDREN,
|
|
20
|
+
RESERVED_KEY_NAME,
|
|
21
|
+
RESERVED_KEY_PACKAGE,
|
|
22
|
+
TYPE_SUBTYPE_SEPARATOR,
|
|
23
|
+
} from "../shared/structural.js";
|
|
24
|
+
import { expandPackageForPath } from "../parser-core.js";
|
|
25
|
+
import { parseYamlWithPositions } from "../core/yaml-positions-walker.js";
|
|
26
|
+
import type { MetaDataFormat } from "./meta-data-source.js";
|
|
27
|
+
|
|
28
|
+
/** The YAML authoring sugar for `isArray: true` — a suffix on the wrapper key. */
|
|
29
|
+
const ARRAY_SUFFIX = "[]";
|
|
30
|
+
|
|
31
|
+
/** One field name declared more than once in one object's `children` list. */
|
|
32
|
+
export interface DeclaredDuplicateField {
|
|
33
|
+
/** The declaring object's resolution key (`<package>::<name>`, or the bare name). */
|
|
34
|
+
object: string;
|
|
35
|
+
/** The repeated field name. */
|
|
36
|
+
field: string;
|
|
37
|
+
/** How many times the list declares it (always 2 or more). */
|
|
38
|
+
count: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function isRecord(v: unknown): v is Record<string, unknown> {
|
|
42
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The TYPE segment of a wrapper key: `field.string[]` and the bare `field` are both `field`. */
|
|
46
|
+
function wrapperType(key: string): string {
|
|
47
|
+
const dot = key.indexOf(TYPE_SUBTYPE_SEPARATOR);
|
|
48
|
+
const head = dot < 0 ? key : key.slice(0, dot);
|
|
49
|
+
return head.endsWith(ARRAY_SUFFIX) ? head.slice(0, -ARRAY_SUFFIX.length) : head;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** A node's declared name: the body's `name`, or the body itself when YAML wrote a scalar. */
|
|
53
|
+
function declaredName(body: unknown): string | undefined {
|
|
54
|
+
const name = isRecord(body) ? body[RESERVED_KEY_NAME] : body;
|
|
55
|
+
return typeof name === "string" && name !== "" ? name : undefined;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Structurally scan a source's raw content and report every field name a root-level
|
|
60
|
+
* object declares more than once in its own `children` list, in document order.
|
|
61
|
+
*
|
|
62
|
+
* Malformed shapes return `[]` rather than throwing — the real parse is where a
|
|
63
|
+
* structural error surfaces. A syntax error does throw, as `declaredTopLevelKeys` does.
|
|
64
|
+
*/
|
|
65
|
+
export function declaredDuplicateFields(
|
|
66
|
+
content: string,
|
|
67
|
+
format: MetaDataFormat,
|
|
68
|
+
): ReadonlyArray<DeclaredDuplicateField> {
|
|
69
|
+
// Strip UTF-8 BOM if present (mirrors parseJson / parseYaml).
|
|
70
|
+
const normalized = content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;
|
|
71
|
+
let parsed: unknown;
|
|
72
|
+
if (format === "json") parsed = JSON.parse(normalized);
|
|
73
|
+
else if (format === "yaml") parsed = parseYamlWithPositions(normalized).value;
|
|
74
|
+
else return [];
|
|
75
|
+
if (!isRecord(parsed)) return [];
|
|
76
|
+
|
|
77
|
+
// JSON fuses the subtype onto the root key; sigil-free YAML may write the bare type.
|
|
78
|
+
const rootBody = parsed[`${TYPE_METADATA}${TYPE_SUBTYPE_SEPARATOR}${SUBTYPE_ROOT}`] ?? parsed[TYPE_METADATA];
|
|
79
|
+
if (!isRecord(rootBody)) return [];
|
|
80
|
+
const rawRootPkg = rootBody[RESERVED_KEY_PACKAGE];
|
|
81
|
+
const rootPkg = typeof rawRootPkg === "string" ? rawRootPkg : "";
|
|
82
|
+
const children = rootBody[RESERVED_KEY_CHILDREN];
|
|
83
|
+
if (!Array.isArray(children)) return [];
|
|
84
|
+
|
|
85
|
+
const out: DeclaredDuplicateField[] = [];
|
|
86
|
+
for (const child of children) {
|
|
87
|
+
if (!isRecord(child)) continue;
|
|
88
|
+
for (const [wrapperKey, body] of Object.entries(child)) {
|
|
89
|
+
if (wrapperType(wrapperKey) !== TYPE_OBJECT || !isRecord(body)) continue;
|
|
90
|
+
const name = declaredName(body);
|
|
91
|
+
const members = body[RESERVED_KEY_CHILDREN];
|
|
92
|
+
if (name === undefined || !Array.isArray(members)) continue;
|
|
93
|
+
|
|
94
|
+
const counts = new Map<string, number>();
|
|
95
|
+
for (const member of members) {
|
|
96
|
+
if (!isRecord(member)) continue;
|
|
97
|
+
for (const [memberKey, memberBody] of Object.entries(member)) {
|
|
98
|
+
if (wrapperType(memberKey) !== TYPE_FIELD) continue;
|
|
99
|
+
const fieldName = declaredName(memberBody);
|
|
100
|
+
if (fieldName !== undefined) counts.set(fieldName, (counts.get(fieldName) ?? 0) + 1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const rawOwnPkg = body[RESERVED_KEY_PACKAGE];
|
|
105
|
+
const pkg =
|
|
106
|
+
typeof rawOwnPkg === "string" && rawOwnPkg !== "" ? expandPackageForPath(rootPkg, rawOwnPkg) : rootPkg;
|
|
107
|
+
const object = pkg !== "" ? `${pkg}${PACKAGE_SEPARATOR}${name}` : name;
|
|
108
|
+
for (const [field, count] of counts) {
|
|
109
|
+
if (count > 1) out.push({ object, field, count });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
@@ -26,6 +26,7 @@ import type { LoaderWarning } from "../source.js";
|
|
|
26
26
|
import { codeSource, resolvedSource } from "../source.js";
|
|
27
27
|
import { parseJson } from "../parser-json.js";
|
|
28
28
|
import { validateDataGridSortFields, validateFilterableHasIndex, validateFilterableHasSupportedOps, validateSortableHasSupportedSubtype, validateOriginPaths, validateDerivedFieldProvidability, validateDataGridFilterValues, validateFieldObjectStorage, validateFieldMap, validateTemplatePayloadRefs, validateFieldDefaults, validateRelationships, validateOneSideReferenceResolution, validateM2MJunctionPairing, validateIndexLookupFields, validateProjectionFilter, validateRetiredRequirementLinks } from "./validation-passes.js";
|
|
29
|
+
import { validateReporting } from "./reporting-validation.js";
|
|
29
30
|
import { runRegisteredValidation } from "./validation-registry.js";
|
|
30
31
|
import { validateSourceRoles } from "../persistence/source/validate-source-roles.js";
|
|
31
32
|
import { validateSourceEscapes } from "../persistence/source/validate-source-escapes.js";
|
|
@@ -35,6 +36,7 @@ import { validateFieldMutability } from "../core/field/validate-field-mutability
|
|
|
35
36
|
import { validateEnumNormalizeAmbiguity } from "../core/field/validate-enum-normalize-ambiguity.js";
|
|
36
37
|
import { validateDiscriminator } from "../core/object/validate-discriminator.js";
|
|
37
38
|
import { resolveDeferredSupers, EXTENDS_TARGET_MISMATCH_RULE } from "../super-resolve.js";
|
|
39
|
+
import { resolveReferences } from "./resolve-references.js";
|
|
38
40
|
import { validateSubtypeRules } from "../subtype-rules.js";
|
|
39
41
|
import { validateMaxOccurs } from "../validate-max-occurs.js";
|
|
40
42
|
import { validateIdentityPassthrough } from "../core/identity/validate-identity-passthrough.js";
|
|
@@ -43,6 +45,7 @@ import type { MetaDataFormat, MetaDataSource } from "./meta-data-source.js";
|
|
|
43
45
|
import { InMemoryStringSource } from "./meta-data-source.js";
|
|
44
46
|
import type { ParseOptions, ParseResult, PendingOverlay } from "../parser-core.js";
|
|
45
47
|
import { expandPackageForPath, applyPendingOverlays } from "../parser-core.js";
|
|
48
|
+
import { didYouMeanSuperHint } from "../naming-refs.js";
|
|
46
49
|
|
|
47
50
|
// Local mirror of DirectorySource's options shape. Deliberately inlined here
|
|
48
51
|
// (instead of `import type`'d from ./sources/directory-source.js) so the
|
|
@@ -589,9 +592,22 @@ export class MetaDataLoader {
|
|
|
589
592
|
);
|
|
590
593
|
continue;
|
|
591
594
|
}
|
|
595
|
+
if (failure.kind === "over-drop") {
|
|
596
|
+
// ADR-0059 R2 — `..::` dropped more segments than the package has.
|
|
597
|
+
errors.push(
|
|
598
|
+
new ParseError(
|
|
599
|
+
`the extends ref '${failure.ref}' on ${failure.nodeFqn} climbs above the root package — each '..::' drops one segment of the declaring package`,
|
|
600
|
+
{
|
|
601
|
+
code: "ERR_BAD_ATTR_VALUE",
|
|
602
|
+
source: resolvedSource(failure.source, failure.nodeFqn, failure.ref),
|
|
603
|
+
},
|
|
604
|
+
),
|
|
605
|
+
);
|
|
606
|
+
continue;
|
|
607
|
+
}
|
|
592
608
|
errors.push(
|
|
593
609
|
new ParseError(
|
|
594
|
-
`the SuperClass '${failure.ref}' does not exist (referenced by ${failure.nodeFqn})`,
|
|
610
|
+
`the SuperClass '${failure.ref}' does not exist (referenced by ${failure.nodeFqn})${didYouMeanSuperHint(root, failure.ref)}`,
|
|
595
611
|
{
|
|
596
612
|
code: "ERR_UNRESOLVED_SUPER",
|
|
597
613
|
source: resolvedSource(failure.source, failure.nodeFqn, failure.ref),
|
|
@@ -646,6 +662,10 @@ export class MetaDataLoader {
|
|
|
646
662
|
// an aggregate-derived or dangling ref is fail-closed (ERR_BAD_ATTR_FILTER).
|
|
647
663
|
errors.push(...validateProjectionFilter(root));
|
|
648
664
|
|
|
665
|
+
// FR-044 — reporting vocabulary cross-node rules (dimensions, measures,
|
|
666
|
+
// segments, reports, relative-date filter values).
|
|
667
|
+
errors.push(...validateReporting(root));
|
|
668
|
+
|
|
649
669
|
// FR-017 — M:N relationship validation (deferred-resolution): @through names a
|
|
650
670
|
// junction declaring two identity.reference children; @sourceRefField matches one;
|
|
651
671
|
// @symmetric is self-join-only + mutually exclusive with @sourceRefField; M:N attrs
|
|
@@ -745,6 +765,10 @@ export class MetaDataLoader {
|
|
|
745
765
|
// finite number, boolean → true|false). Enum @default membership is validated
|
|
746
766
|
// by validateAttrSchema (Check 5). Cross-port parity with Java/Python/C#.
|
|
747
767
|
errors.push(...validateFieldDefaults(root));
|
|
768
|
+
|
|
769
|
+
// ADR-0059 R5 — after the last validation pass, before freeze: resolve every
|
|
770
|
+
// reference once, record its target and rewrite it to its canonical spelling.
|
|
771
|
+
resolveReferences(root);
|
|
748
772
|
}
|
|
749
773
|
|
|
750
774
|
// If nothing parsed successfully, synthesize an empty root so callers
|