@metaobjectsdev/metadata 1.0.13 → 1.1.1-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/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 +17 -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 +42 -7
- package/dist/naming.d.ts.map +1 -1
- package/dist/naming.js +43 -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 -3
- package/dist/persistence/source/meta-source.d.ts.map +1 -1
- package/dist/persistence/source/meta-source.js +8 -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 +17 -6
- package/src/fmt.ts +3 -1
- package/src/index.ts +72 -4
- 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 +75 -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 +8 -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
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// ADR-0059 R5 — resolve every reference once, after validation and before freeze.
|
|
2
|
+
//
|
|
3
|
+
// Sources do not interpret references (R1): YAML and canonical JSON hand the loader
|
|
4
|
+
// each reference string exactly as written. The validation passes resolve those
|
|
5
|
+
// authored strings through the shared resolver and report failures with their own
|
|
6
|
+
// codes. This pass then walks the physical tree once and, for every reference that
|
|
7
|
+
// resolves, records the target and rewrites the value to its canonical spelling (R6),
|
|
8
|
+
// keeping the authored string beside it. After the pass every consumer reads values
|
|
9
|
+
// that mean the same thing whatever package they are read from, and the serializer
|
|
10
|
+
// writes them as they are.
|
|
11
|
+
//
|
|
12
|
+
// A reference that does not resolve is left exactly as written: validation has
|
|
13
|
+
// already reported it.
|
|
14
|
+
|
|
15
|
+
import type { MetaData, AttrValue } from "../shared/meta-data.js";
|
|
16
|
+
import { MetaAttr } from "../core/attr/meta-attr.js";
|
|
17
|
+
import { TYPE_DIMENSION } from "../shared/base-types.js";
|
|
18
|
+
import { REPORTING_ATTR_OF, REPORTING_ATTR_VIA } from "../core/reporting/reporting-constants.js";
|
|
19
|
+
import {
|
|
20
|
+
OBJECT_REPORT_ATTR_FROM,
|
|
21
|
+
OBJECT_REPORT_ATTR_SPINE,
|
|
22
|
+
OBJECT_SUBTYPE_REPORT,
|
|
23
|
+
} from "../core/object/object-constants.js";
|
|
24
|
+
import { TYPE_OBJECT } from "../shared/base-types.js";
|
|
25
|
+
import {
|
|
26
|
+
REF_BEARING_ATTR_NAMES,
|
|
27
|
+
effectivePackageOf,
|
|
28
|
+
resolveObjectRef,
|
|
29
|
+
spellRef,
|
|
30
|
+
splitChildTail,
|
|
31
|
+
topLevelNodeOf,
|
|
32
|
+
} from "../naming-refs.js";
|
|
33
|
+
import { resolveSuperRef } from "../super-resolve.js";
|
|
34
|
+
import { dimensionViaTerminal } from "./reporting-validation.js";
|
|
35
|
+
|
|
36
|
+
/** One resolved reference: its owner object and the canonical spelling. */
|
|
37
|
+
interface Resolved {
|
|
38
|
+
readonly target: MetaData;
|
|
39
|
+
readonly canonical: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Resolve one reference string's owner in `refPkg`, and spell it canonically. Root-level
|
|
43
|
+
* targets are spelled `::Name` unless both the resolution package and the declaring
|
|
44
|
+
* package are root-level, so a consumer reading from either package binds the same node. */
|
|
45
|
+
function resolveOne(root: MetaData, value: string, refPkg: string, declPkg: string): Resolved | undefined {
|
|
46
|
+
const { owner, tail } = splitChildTail(value);
|
|
47
|
+
const target = resolveObjectRef(root, owner, refPkg).node;
|
|
48
|
+
if (target === undefined) return undefined;
|
|
49
|
+
return { target, canonical: spellRef(target, refPkg !== "" ? refPkg : declPkg, tail) };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** R3 — the package an own reference attribute of `node` resolves in. */
|
|
53
|
+
function referrerPackage(root: MetaData, node: MetaData, attr: string, declPkg: string): string {
|
|
54
|
+
// `@of` on a dimension that walks `@via`: the package of the entity the walk reaches.
|
|
55
|
+
if (node.type === TYPE_DIMENSION && attr === REPORTING_ATTR_OF) {
|
|
56
|
+
// ADR-0039: resolving — the @via that governs this @of may be inherited.
|
|
57
|
+
const via = node.attr(REPORTING_ATTR_VIA);
|
|
58
|
+
const declaring = node.parent;
|
|
59
|
+
if (typeof via === "string" && via !== "" && declaring !== undefined) {
|
|
60
|
+
const terminal = dimensionViaTerminal(root, declaring, via);
|
|
61
|
+
return terminal !== undefined ? effectivePackageOf(terminal) : declPkg;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// `@spine` on a report: the package of the `@from` entity.
|
|
65
|
+
if (node.type === TYPE_OBJECT && node.subType === OBJECT_SUBTYPE_REPORT && attr === OBJECT_REPORT_ATTR_SPINE) {
|
|
66
|
+
// ADR-0039: resolving — @from may be inherited.
|
|
67
|
+
const from = node.attr(OBJECT_REPORT_ATTR_FROM);
|
|
68
|
+
if (typeof from === "string" && from !== "") {
|
|
69
|
+
const fromNode = resolveObjectRef(root, from, declPkg).node;
|
|
70
|
+
if (fromNode !== undefined) return effectivePackageOf(fromNode);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return declPkg;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function resolveAttr(root: MetaData, node: MetaData, attr: MetaAttr, declPkg: string): void {
|
|
77
|
+
const value = attr.value;
|
|
78
|
+
const refPkg = referrerPackage(root, node, attr.name, declPkg);
|
|
79
|
+
if (typeof value === "string") {
|
|
80
|
+
if (value === "") return;
|
|
81
|
+
const r = resolveOne(root, value, refPkg, declPkg);
|
|
82
|
+
if (r === undefined) return;
|
|
83
|
+
attr.resolvedTarget = r.target;
|
|
84
|
+
if (r.canonical !== value) {
|
|
85
|
+
attr.authoredValue ??= value;
|
|
86
|
+
node.setAttr(attr.name, r.canonical);
|
|
87
|
+
}
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (Array.isArray(value) && value.every((v) => typeof v === "string")) {
|
|
91
|
+
const items = value as readonly string[];
|
|
92
|
+
const resolved = items.map((v) => (v === "" ? undefined : resolveOne(root, v, refPkg, declPkg)));
|
|
93
|
+
if (resolved.every((r) => r === undefined)) return;
|
|
94
|
+
attr.resolvedTarget = resolved.map((r) => r?.target);
|
|
95
|
+
const canonical: AttrValue = items.map((v, i) => resolved[i]?.canonical ?? v);
|
|
96
|
+
if (canonical.some((v, i) => v !== items[i])) {
|
|
97
|
+
attr.authoredValue ??= [...items];
|
|
98
|
+
node.setAttr(attr.name, canonical);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Canonical `extends`: the owner spelled from the declaring node's package, tail kept. */
|
|
104
|
+
function resolveExtends(root: MetaData, node: MetaData): void {
|
|
105
|
+
const ref = node.superRef;
|
|
106
|
+
if (ref === undefined || node.superResolved === undefined) return;
|
|
107
|
+
const pkg = effectivePackageOf(node);
|
|
108
|
+
const { owner, tail } = splitChildTail(ref);
|
|
109
|
+
let ownerNode: MetaData | undefined;
|
|
110
|
+
try {
|
|
111
|
+
ownerNode = resolveSuperRef(owner, pkg, root);
|
|
112
|
+
} catch {
|
|
113
|
+
return; // an over-drop never resolved, so superResolved would be unset
|
|
114
|
+
}
|
|
115
|
+
if (ownerNode === undefined) return;
|
|
116
|
+
const canonical = spellRef(ownerNode, pkg, tail);
|
|
117
|
+
if (canonical === ref) return;
|
|
118
|
+
node.authoredSuperRef ??= ref;
|
|
119
|
+
node.setSuper(canonical);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Resolve every own reference attribute (ADR-0059 R4) and every `extends` in the
|
|
124
|
+
* tree, record the targets, and rewrite resolved values to their canonical spelling.
|
|
125
|
+
* Must run after the last validation pass and before `freeze()`.
|
|
126
|
+
*/
|
|
127
|
+
export function resolveReferences(root: MetaData): void {
|
|
128
|
+
const visit = (node: MetaData): void => {
|
|
129
|
+
if (node !== root) {
|
|
130
|
+
resolveExtends(root, node);
|
|
131
|
+
// R3 default: the effective package of the top-level node that physically
|
|
132
|
+
// declares the attribute. Own attributes are declared here, by definition.
|
|
133
|
+
const declPkg = effectivePackageOf(topLevelNodeOf(node));
|
|
134
|
+
// ADR-0039: own — this pass rewrites the declared-here layer; an inherited
|
|
135
|
+
// attribute is resolved once, on the node that declares it.
|
|
136
|
+
for (const attr of node.ownMetaAttrs()) {
|
|
137
|
+
if (REF_BEARING_ATTR_NAMES.has(attr.name)) resolveAttr(root, node, attr, declPkg);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// ADR-0039: own — structural walk over the physical declaration tree.
|
|
141
|
+
for (const child of node.ownChildren()) visit(child);
|
|
142
|
+
};
|
|
143
|
+
visit(root);
|
|
144
|
+
}
|
|
@@ -15,7 +15,7 @@ import type { MetaObject } from "../core/object/meta-object.js";
|
|
|
15
15
|
import type { MetaReferenceIdentity } from "../core/identity/meta-identity.js";
|
|
16
16
|
import { contradictionHint, contradictionsFor } from "../attr-contradictions.js";
|
|
17
17
|
import { ParseError, type ErrorCode } from "../errors.js";
|
|
18
|
-
import { resolveObjectRef, didYouMeanHint } from "../naming-refs.js";
|
|
18
|
+
import { resolveObjectRef, didYouMeanHint, refTarget } from "../naming-refs.js";
|
|
19
19
|
import { PACKAGE_SEPARATOR, CHILD_REF_SEPARATOR } from "../shared/structural.js";
|
|
20
20
|
import { resolvedSource, type ErrorSource } from "../source.js";
|
|
21
21
|
import {
|
|
@@ -138,7 +138,6 @@ import type { MetaRelationship } from "../core/relationship/meta-relationship.js
|
|
|
138
138
|
// Rule (f) runs the REAL M:N derivation so the loader and codegen cannot drift.
|
|
139
139
|
import { deriveM2MFields, M2MDerivationError } from "../core/relationship/derive-m2m-fields.js";
|
|
140
140
|
import { isReadOnlySource, isWritableSource } from "../shared/node-guards.js";
|
|
141
|
-
import { stripPackage } from "../naming.js";
|
|
142
141
|
import {
|
|
143
142
|
FILTER_COMPOSE_OR,
|
|
144
143
|
FILTER_COMPOSE_AND,
|
|
@@ -957,8 +956,8 @@ function _inferViaSingleHop(
|
|
|
957
956
|
.filter((c) => c.type === TYPE_RELATIONSHIP)
|
|
958
957
|
.filter((rel) => {
|
|
959
958
|
// ADR-0039: resolving — a relationship may inherit @objectRef via extends.
|
|
960
|
-
|
|
961
|
-
return
|
|
959
|
+
// ADR-0059 R7: compare the bound target, never a short name.
|
|
960
|
+
return refTarget(rel, RELATIONSHIP_ATTR_OBJECT_REF) === targetEntity;
|
|
962
961
|
});
|
|
963
962
|
// FR5d — referrer is `<host-FQN>::<fieldName>`, target is the from/of ref
|
|
964
963
|
// whose implicit path could not be resolved.
|
|
@@ -2207,7 +2206,11 @@ export function validateOneSideReferenceResolution(root: MetaRoot): ParseError[]
|
|
|
2207
2206
|
const objectRef = rel.attr(RELATIONSHIP_ATTR_OBJECT_REF);
|
|
2208
2207
|
if (typeof objectRef !== "string" || objectRef === "") continue;
|
|
2209
2208
|
|
|
2210
|
-
|
|
2209
|
+
// ADR-0059 R7: match references by the bound target node. An unresolved
|
|
2210
|
+
// @objectRef is reported by its own pass.
|
|
2211
|
+
const targetNode = refTarget(rel, RELATIONSHIP_ATTR_OBJECT_REF);
|
|
2212
|
+
if (targetNode === undefined) continue;
|
|
2213
|
+
const candidates = referenceCandidatesFor(obj, targetNode);
|
|
2211
2214
|
|
|
2212
2215
|
const sourceRefField = rel.attr(RELATIONSHIP_ATTR_SOURCE_REF_FIELD);
|
|
2213
2216
|
const declared = typeof sourceRefField === "string" && sourceRefField !== ""
|
|
@@ -2237,7 +2240,7 @@ export function validateOneSideReferenceResolution(root: MetaRoot): ParseError[]
|
|
|
2237
2240
|
// No @sourceRefField declared: ambiguity only exists with 2+ candidates —
|
|
2238
2241
|
// resolveRelationshipReference's name-pairing step (ladder step 3) decides.
|
|
2239
2242
|
if (candidates.length <= 1) continue;
|
|
2240
|
-
const resolved = resolveRelationshipReference(obj, rel.name,
|
|
2243
|
+
const resolved = resolveRelationshipReference(obj, rel.name, targetNode);
|
|
2241
2244
|
if (resolved) continue;
|
|
2242
2245
|
|
|
2243
2246
|
errors.push(
|
|
@@ -2706,9 +2709,10 @@ function checkProjectionFilterRefs(
|
|
|
2706
2709
|
// Resolution of the reference itself is `verify`'s job (it owns every other
|
|
2707
2710
|
// @implementedBy-style resolution) — the loader owns the shape.
|
|
2708
2711
|
//
|
|
2709
|
-
// Runs in every port.
|
|
2710
|
-
//
|
|
2711
|
-
//
|
|
2712
|
+
// Runs in every port. The requirement gate runs in every port's `verify` since
|
|
2713
|
+
// ADR-0057 (when this rule was written it ran only in the TS CLI), yet the rule
|
|
2714
|
+
// stays in the loader: a shape the loader refuses is unreachable in every port
|
|
2715
|
+
// and in every program that loads the model, whether or not anyone runs `verify`.
|
|
2712
2716
|
//
|
|
2713
2717
|
// ADR-0039: children()/attr() throughout — never own* — so a requirement that
|
|
2714
2718
|
// inherits its status through `extends` is judged on its EFFECTIVE status.
|
|
@@ -8,9 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
import type { MetaData } from "../shared/meta-data.js";
|
|
10
10
|
import { ParseError } from "../errors.js";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
didYouMeanHint,
|
|
13
|
+
ownerCandidateKeys,
|
|
14
|
+
referrerPackageFor,
|
|
15
|
+
RefOverDropError,
|
|
16
|
+
} from "../naming-refs.js";
|
|
12
17
|
import { TYPE_OBJECT } from "../shared/base-types.js";
|
|
13
|
-
import { PACKAGE_SEPARATOR } from "../shared/structural.js";
|
|
14
18
|
import type { TypeRegistry } from "../registry.js";
|
|
15
19
|
import type { LoaderCode, SymbolTable, ValidationContext } from "../validation-types.js";
|
|
16
20
|
|
|
@@ -38,15 +42,25 @@ class SymbolTableImpl implements SymbolTable {
|
|
|
38
42
|
return t;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
/** ADR-
|
|
42
|
-
*
|
|
43
|
-
*
|
|
45
|
+
/** ADR-0059 R2 resolution within the `type` bucket: `::Rest` root-absolute,
|
|
46
|
+
* `..::Rest` parent-relative, `pkg::Name` exact, bare `Name` in the referrer's own
|
|
47
|
+
* package then root-level. Exact keys only. An over-dropping `..::` resolves to
|
|
48
|
+
* nothing here; the walk reports it as ERR_BAD_ATTR_VALUE. */
|
|
44
49
|
resolve(type: string, ref: string, referrerPkg: string): MetaData | undefined {
|
|
45
50
|
const bucket = this.byType.get(type);
|
|
46
51
|
if (bucket === undefined) return undefined;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
let keys: readonly string[];
|
|
53
|
+
try {
|
|
54
|
+
keys = ownerCandidateKeys(ref, referrerPkg);
|
|
55
|
+
} catch (e) {
|
|
56
|
+
if (e instanceof RefOverDropError) return undefined;
|
|
57
|
+
throw e;
|
|
58
|
+
}
|
|
59
|
+
for (const key of keys) {
|
|
60
|
+
const hit = bucket.get(key);
|
|
61
|
+
if (hit !== undefined) return hit;
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
50
64
|
}
|
|
51
65
|
|
|
52
66
|
resolveObject(ref: string, referrerPkg: string): MetaData | undefined {
|
|
@@ -94,7 +108,21 @@ export function runRegisteredValidation(root: MetaData, registry: TypeRegistry):
|
|
|
94
108
|
const raw = node.attr(desc.attr);
|
|
95
109
|
if (typeof raw !== "string" || raw === "") continue; // absence is the required-attr pass's job
|
|
96
110
|
const entityRef = desc.dottedFieldPath ? (raw.split(".")[0] ?? raw) : raw;
|
|
97
|
-
|
|
111
|
+
// ADR-0059 R3: an inherited reference resolves in the package of the
|
|
112
|
+
// top-level node that physically declares it, not the inheritor's.
|
|
113
|
+
const refPkg = referrerPackageFor(node, desc.attr);
|
|
114
|
+
try {
|
|
115
|
+
ownerCandidateKeys(entityRef, refPkg);
|
|
116
|
+
} catch (e) {
|
|
117
|
+
if (!(e instanceof RefOverDropError)) throw e;
|
|
118
|
+
ctx.error(
|
|
119
|
+
"ERR_BAD_ATTR_VALUE",
|
|
120
|
+
node,
|
|
121
|
+
`${node.type}.${node.subType} "${node.name}" @${desc.attr} "${raw}" climbs above the root package — each '..::' drops one segment of the declaring package.`,
|
|
122
|
+
);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const target = ctx.symbols.resolve(desc.targetType, entityRef, refPkg);
|
|
98
126
|
// Qualify the node name with its owning entity (e.g. "Order.items") so the error is
|
|
99
127
|
// locatable from the message alone, not just the source envelope.
|
|
100
128
|
const qname = node.parent?.name ? `${node.parent.name}.${node.name}` : node.name;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// FR-033 S3 — metamodel doc-gen public surface.
|
|
2
2
|
//
|
|
3
3
|
// Documents the METAMODEL ITSELF (the type/subtype/attr vocabulary of the strict
|
|
4
|
-
// registry) as tiered, LLM-readable markdown — distinct from `
|
|
4
|
+
// registry) as tiered, LLM-readable markdown — distinct from the `docs` generator
|
|
5
5
|
// (which documents a user's entities). The renderer is a pure, deterministic
|
|
6
|
-
// function over the composed registry + a provenance lens;
|
|
7
|
-
//
|
|
6
|
+
// function over the composed registry + a provenance lens; the `metamodel-docs`
|
|
7
|
+
// generator in codegen-ts writes its pages.
|
|
8
8
|
|
|
9
9
|
import type { TypeRegistry } from "../registry.js";
|
|
10
10
|
import { coreProviders } from "../core-types.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// FR-033 S3 — the metamodel doc renderer (pure, deterministic, byte-stable).
|
|
2
2
|
//
|
|
3
3
|
// Documents the METAMODEL ITSELF — the type/subtype/attr vocabulary of the
|
|
4
|
-
// strict registry — for an LLM (and humans). This is distinct from `
|
|
5
|
-
//
|
|
4
|
+
// strict registry — for an LLM (and humans). This is distinct from the `docs`
|
|
5
|
+
// generator (`docsFile()`), which documents a USER's entities. The output is a tiered markdown
|
|
6
6
|
// tree:
|
|
7
7
|
//
|
|
8
8
|
// INDEX.md every type.subType + one-liner + link (always-on map)
|
|
@@ -24,7 +24,7 @@ import { CHILD_RULE_WILDCARD } from "../shared/structural.js";
|
|
|
24
24
|
import { SUBTYPE_BASE } from "../shared/base-types.js";
|
|
25
25
|
|
|
26
26
|
/** The regeneration command, named in every file's DO-NOT-EDIT header. */
|
|
27
|
-
const REGEN_COMMAND = "meta docs
|
|
27
|
+
const REGEN_COMMAND = "meta gen (the metamodel-docs generator, metamodelDocsFile())";
|
|
28
28
|
|
|
29
29
|
/** ASCII codepoint compare — locale-independent, byte-stable. */
|
|
30
30
|
function compare(a: string, b: string): number {
|
|
@@ -196,7 +196,7 @@ function renderIndex(defs: readonly TypeDefinition[]): string {
|
|
|
196
196
|
"# MetaObjects Metamodel — Index\n",
|
|
197
197
|
"This documents the **metamodel itself** — the type / subtype / attribute",
|
|
198
198
|
"vocabulary the loader accepts — generated from the strict registry. It is",
|
|
199
|
-
"NOT documentation of a user's entities (that is `
|
|
199
|
+
"NOT documentation of a user's entities (that is the `docs` generator, `docsFile()`).\n",
|
|
200
200
|
"Follow a link into `types/<family>.md` for the full attribute table, allowed",
|
|
201
201
|
"children, and cardinality of a subtype. Universal documentation attributes",
|
|
202
202
|
"(`@description`/`@title`/…) apply to every node and are listed once in",
|