@metaobjectsdev/metadata 1.0.3 → 1.0.4-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.
Files changed (62) hide show
  1. package/dist/core/relationship/derive-m2m-fields.d.ts +3 -1
  2. package/dist/core/relationship/derive-m2m-fields.d.ts.map +1 -1
  3. package/dist/core/relationship/derive-m2m-fields.js +110 -15
  4. package/dist/core/relationship/derive-m2m-fields.js.map +1 -1
  5. package/dist/core/relationship/find-reference.d.ts +21 -5
  6. package/dist/core/relationship/find-reference.d.ts.map +1 -1
  7. package/dist/core/relationship/find-reference.js +29 -10
  8. package/dist/core/relationship/find-reference.js.map +1 -1
  9. package/dist/core/relationship/relationship-definition.embedded.js +8 -8
  10. package/dist/core/relationship/relationship-definition.embedded.js.map +1 -1
  11. package/dist/core/relationship/resolve-relationship-reference.d.ts +27 -0
  12. package/dist/core/relationship/resolve-relationship-reference.d.ts.map +1 -0
  13. package/dist/core/relationship/resolve-relationship-reference.js +84 -0
  14. package/dist/core/relationship/resolve-relationship-reference.js.map +1 -0
  15. package/dist/errors.d.ts +1 -1
  16. package/dist/errors.d.ts.map +1 -1
  17. package/dist/errors.js +10 -0
  18. package/dist/errors.js.map +1 -1
  19. package/dist/index.d.ts +2 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +2 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/library/embedded-library.generated.d.ts +2 -0
  24. package/dist/library/embedded-library.generated.d.ts.map +1 -1
  25. package/dist/library/embedded-library.generated.js +11 -1
  26. package/dist/library/embedded-library.generated.js.map +1 -1
  27. package/dist/library/index.d.ts +2 -0
  28. package/dist/library/index.d.ts.map +1 -0
  29. package/dist/library/index.js +24 -0
  30. package/dist/library/index.js.map +1 -0
  31. package/dist/library/library-sources.d.ts +99 -6
  32. package/dist/library/library-sources.d.ts.map +1 -1
  33. package/dist/library/library-sources.js +165 -43
  34. package/dist/library/library-sources.js.map +1 -1
  35. package/dist/loader/meta-data-loader.d.ts.map +1 -1
  36. package/dist/loader/meta-data-loader.js +6 -1
  37. package/dist/loader/meta-data-loader.js.map +1 -1
  38. package/dist/loader/validation-passes.d.ts +2 -0
  39. package/dist/loader/validation-passes.d.ts.map +1 -1
  40. package/dist/loader/validation-passes.js +162 -22
  41. package/dist/loader/validation-passes.js.map +1 -1
  42. package/dist/parser-core.d.ts.map +1 -1
  43. package/dist/parser-core.js +13 -2
  44. package/dist/parser-core.js.map +1 -1
  45. package/dist/vocabulary-rewrite-yaml.d.ts +2 -0
  46. package/dist/vocabulary-rewrite-yaml.d.ts.map +1 -0
  47. package/dist/vocabulary-rewrite-yaml.js +22 -0
  48. package/dist/vocabulary-rewrite-yaml.js.map +1 -0
  49. package/package.json +7 -7
  50. package/src/core/relationship/derive-m2m-fields.ts +115 -15
  51. package/src/core/relationship/find-reference.ts +34 -11
  52. package/src/core/relationship/relationship-definition.embedded.ts +8 -8
  53. package/src/core/relationship/resolve-relationship-reference.ts +99 -0
  54. package/src/errors.ts +10 -0
  55. package/src/index.ts +6 -1
  56. package/src/library/embedded-library.generated.ts +12 -1
  57. package/src/library/index.ts +23 -0
  58. package/src/library/library-sources.ts +197 -47
  59. package/src/loader/meta-data-loader.ts +7 -1
  60. package/src/loader/validation-passes.ts +181 -23
  61. package/src/parser-core.ts +15 -2
  62. package/src/vocabulary-rewrite-yaml.ts +21 -0
@@ -17,7 +17,9 @@ export interface M2MFields {
17
17
  *
18
18
  * @param rel the M:N relationship (carries @objectRef + @through + optional
19
19
  * @sourceRefField / @symmetric)
20
- * @param source the entity declaring `rel`
20
+ * @param source the entity the caller is navigating from. Accepted alongside
21
+ * `rel.parent` as a name for the relationship's subject, and used
22
+ * as the declaring entity when `rel` has no entity parent.
21
23
  * @param root the loaded model root (to find the junction entity)
22
24
  * @throws M2MDerivationError when the junction is missing/malformed or the
23
25
  * self-join is ambiguous.
@@ -1 +1 @@
1
- {"version":3,"file":"derive-m2m-fields.d.ts","sourceRoot":"","sources":["../../../src/core/relationship/derive-m2m-fields.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAI/D,6EAA6E;AAC7E,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,8BAA8B;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,SAAS;IACxB,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAOD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,gBAAgB,EACrB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,QAAQ,GACb,SAAS,CA0FX"}
1
+ {"version":3,"file":"derive-m2m-fields.d.ts","sourceRoot":"","sources":["../../../src/core/relationship/derive-m2m-fields.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAM/D,6EAA6E;AAC7E,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,8BAA8B;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,SAAS;IACxB,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AA6BD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,gBAAgB,EACrB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,QAAQ,GACb,SAAS,CA+IX"}
@@ -17,7 +17,30 @@
17
17
  // two references are taken in declaration order (sourceField = first,
18
18
  // targetField = second). Resolution unions both at read time.
19
19
  // Ambiguous (source == target, neither @sourceRefField nor @symmetric) → throw.
20
+ //
21
+ // "source" above means the relationship's SUBJECT, and under `extends` there are two
22
+ // legitimate names for it. Every caller walks the RESOLVING `obj.relationships()`
23
+ // (codegen-ts's relation-resolver, runtime-ts's n2m-resolver, docs-site's link-graph)
24
+ // and passes the entity it is ITERATING, which for an inherited relationship is not
25
+ // the one that declared it. So the DECLARING entity is resolved here from `rel.parent`
26
+ // (same shape as the #368 loader fix, validation-passes' `declaringEntity = rel.parent
27
+ // ?? obj`), and the passed `source` is kept alongside it rather than discarded: a
28
+ // junction FK usually references the CONCRETE entity, because the abstract base has no
29
+ // table, while @objectRef on an inherited self-join names the base. Both are accepted,
30
+ // for the self-join classification and the hetero reference match alike. `source` is
31
+ // also the fallback when `rel` has no entity parent, which keeps the exported signature
32
+ // unchanged. Not covered: a junction reference naming an entity strictly BETWEEN the
33
+ // base and the navigating entity in a deeper hierarchy.
34
+ //
35
+ // The subject comparison is made on RESOLVED OBJECT IDENTITY, not on stripped
36
+ // short names, matching the Java reference (M2MFields.java). Bare-name equality
37
+ // cannot tell `a::NodeBase` from `b::NodeBase`, so once the subject set held two
38
+ // names a genuine CROSS-PACKAGE hetero M:N whose target shares a short name with
39
+ // the subject read as a self-join and refused to derive. Scoped deliberately to
40
+ // this one predicate — every other name comparison in this file is untouched.
20
41
  import { stripPackage } from "../../naming.js";
42
+ import { TYPE_OBJECT } from "../../shared/base-types.js";
43
+ import { PACKAGE_SEPARATOR } from "../../shared/structural.js";
21
44
  /** Thrown when a M:N relationship's junction FK fields cannot be derived. */
22
45
  export class M2MDerivationError extends Error {
23
46
  code = "ERR_INVALID_RELATIONSHIP";
@@ -30,20 +53,53 @@ export class M2MDerivationError extends Error {
30
53
  function refFkField(ref) {
31
54
  return ref.fields[0];
32
55
  }
56
+ /**
57
+ * The root entity a reference name denotes, or undefined. Mirrors the Java
58
+ * reference's `M2MFields.findObject` exactly: a FULLY-QUALIFIED name (one
59
+ * containing "::") resolves EXACTLY on the object's package-folded key, never a
60
+ * bare-tail fallback; a bare name matches a short name, first match wins (the
61
+ * bare-collision case is the deferred follow-up Java records as issue #174).
62
+ *
63
+ * This exists so the SUBJECT comparison below can be made on object IDENTITY the
64
+ * way Java's already is. A bare-name compare cannot tell `a::NodeBase` from
65
+ * `b::NodeBase`, which made a genuine cross-package hetero M:N read as a
66
+ * self-join the moment the subject set held two names.
67
+ */
68
+ function findEntity(root, name) {
69
+ if (name === undefined || name === "")
70
+ return undefined;
71
+ const objects = root.objects();
72
+ if (name.includes(PACKAGE_SEPARATOR)) {
73
+ return objects.find((o) => o.resolutionKey() === name);
74
+ }
75
+ const bare = stripPackage(name);
76
+ return objects.find((o) => o.name === bare);
77
+ }
33
78
  /**
34
79
  * Derive the source/target junction FK fields for a M:N relationship.
35
80
  *
36
81
  * @param rel the M:N relationship (carries @objectRef + @through + optional
37
82
  * @sourceRefField / @symmetric)
38
- * @param source the entity declaring `rel`
83
+ * @param source the entity the caller is navigating from. Accepted alongside
84
+ * `rel.parent` as a name for the relationship's subject, and used
85
+ * as the declaring entity when `rel` has no entity parent.
39
86
  * @param root the loaded model root (to find the junction entity)
40
87
  * @throws M2MDerivationError when the junction is missing/malformed or the
41
88
  * self-join is ambiguous.
42
89
  */
43
90
  export function deriveM2MFields(rel, source, root) {
91
+ // The entity that DECLARES `rel` — see the header note. `rel.parent` is the
92
+ // owning entity for both an own declaration and an inherited one (an unmodified
93
+ // inherited child is the SAME node object, reused in place by
94
+ // MetaData._effectiveChildren; an override is a genuinely different node whose
95
+ // parent is the overriding entity, which is also correct).
96
+ const relParent = rel.parent;
97
+ const declaringEntity = relParent !== undefined && relParent.type === TYPE_OBJECT
98
+ ? relParent
99
+ : source;
44
100
  const throughName = rel.through;
45
101
  if (throughName === undefined) {
46
- throw new M2MDerivationError(`relationship "${source.name}.${rel.name}" is missing @through (required for M:N derivation)`);
102
+ throw new M2MDerivationError(`relationship "${declaringEntity.name}.${rel.name}" is missing @through (required for M:N derivation)`);
47
103
  }
48
104
  // @through may be package-qualified (FQN); findObject is keyed by bare name,
49
105
  // so fall back to the bare suffix after the last "::". Mirrors the
@@ -54,27 +110,66 @@ export function deriveM2MFields(rel, source, root) {
54
110
  ? root.findObject(throughName.slice(throughName.lastIndexOf("::") + 2))
55
111
  : undefined);
56
112
  if (junction === undefined) {
57
- throw new M2MDerivationError(`relationship "${source.name}.${rel.name}" @through "${throughName}" does not resolve to an entity`);
113
+ throw new M2MDerivationError(`relationship "${declaringEntity.name}.${rel.name}" @through "${throughName}" does not resolve to an entity`);
58
114
  }
59
115
  const targetName = rel.objectRef;
60
116
  if (targetName === undefined) {
61
- throw new M2MDerivationError(`relationship "${source.name}.${rel.name}" is missing @objectRef (the M:N target)`);
117
+ throw new M2MDerivationError(`relationship "${declaringEntity.name}.${rel.name}" is missing @objectRef (the M:N target)`);
62
118
  }
63
119
  const refs = junction.referenceIdentities();
64
120
  if (refs.length !== 2) {
65
- throw new M2MDerivationError(`junction "${throughName}" for relationship "${source.name}.${rel.name}" must declare exactly two ` +
121
+ throw new M2MDerivationError(`junction "${throughName}" for relationship "${declaringEntity.name}.${rel.name}" must declare exactly two ` +
66
122
  `identity.reference children (found ${refs.length})`);
67
123
  }
68
- const isSelfJoin = stripPackage(targetName) === source.name;
124
+ // The relationship's SUBJECT the entity the M:N hangs off. Under `extends`
125
+ // there are two legitimate names for it and BOTH occur in real models:
126
+ // * the DECLARING entity (rel.parent) — what @objectRef names for a self-join
127
+ // declared on an abstract base, and what a junction reference names when the
128
+ // author points the FK at the base type;
129
+ // * the NAVIGATING entity (`source`) — the concrete entity the caller is
130
+ // iterating, which is what a junction FK usually references, because that is
131
+ // the entity with the physical table.
132
+ // Accepting either is what makes the derivation independent of which entity's
133
+ // effective view reached the relationship. (Not covered: a junction reference
134
+ // naming an entity strictly BETWEEN the declaring base and the navigating
135
+ // entity in a deeper hierarchy — no model does that, and widening to the whole
136
+ // super chain would make the "must declare one identity.reference to ..." error
137
+ // unfalsifiable.)
138
+ const subjectNames = declaringEntity.name === source.name
139
+ ? [declaringEntity.name]
140
+ : [declaringEntity.name, source.name];
141
+ const subjectLabel = subjectNames.map((n) => `"${n}"`).join(" or ");
142
+ // Compared by resolved object IDENTITY, matching the Java reference. A
143
+ // stripPackage() compare cannot distinguish `a::NodeBase` from `b::NodeBase`,
144
+ // so with two names in the set a genuine cross-package hetero M:N read as a
145
+ // self-join and refused to derive.
146
+ const isSubject = (entity) => entity !== undefined && (entity === declaringEntity || entity === source);
147
+ const isSubjectName = (name) => name !== undefined && subjectNames.includes(stripPackage(name));
148
+ // Defensive bare fallback when @objectRef does not resolve — loader validation
149
+ // normally guarantees it does. Same carve-out the Java reference makes.
150
+ const targetEntityNode = findEntity(root, targetName);
151
+ const isSelfJoin = targetEntityNode !== undefined
152
+ ? isSubject(targetEntityNode)
153
+ : isSubjectName(targetName);
69
154
  if (!isSelfJoin) {
70
- // Hetero: match each reference by the entity it resolves to.
71
- const sourceRef = refs.find((r) => r.targetEntity !== undefined && stripPackage(r.targetEntity) === source.name);
72
- const targetRef = refs.find((r) => r.targetEntity !== undefined && stripPackage(r.targetEntity) === stripPackage(targetName));
155
+ // Hetero: match each reference by the ENTITY OBJECT it resolves to.
156
+ const sourceRef = refs.find((r) => isSubject(findEntity(root, r.targetEntity)));
157
+ // Identity here too. The two searches are INDEPENDENT nothing excludes
158
+ // sourceRef from this one, unlike the directed self-join branch below — so a
159
+ // bare compare could match the SOURCE-side reference again whenever the
160
+ // target's short name equals the source's, and silently return (srcFk, srcFk).
161
+ // Structurally unreachable while isSelfJoin was also bare (a colliding short
162
+ // name forced the self-join branch); making only isSelfJoin identity-based
163
+ // broke that invariant. Java matches identity on both sides (findRefToSubject
164
+ // + findRefToObject) and never had the hole.
165
+ const targetRef = targetEntityNode !== undefined
166
+ ? refs.find((r) => findEntity(root, r.targetEntity) === targetEntityNode)
167
+ : refs.find((r) => r.targetEntity !== undefined && stripPackage(r.targetEntity) === stripPackage(targetName));
73
168
  const sourceField = sourceRef ? refFkField(sourceRef) : undefined;
74
169
  const targetField = targetRef ? refFkField(targetRef) : undefined;
75
170
  if (sourceField === undefined || targetField === undefined) {
76
- throw new M2MDerivationError(`junction "${throughName}" for relationship "${source.name}.${rel.name}" must declare one ` +
77
- `identity.reference to "${source.name}" and one to "${stripPackage(targetName)}"`);
171
+ throw new M2MDerivationError(`junction "${throughName}" for relationship "${declaringEntity.name}.${rel.name}" must declare one ` +
172
+ `identity.reference to ${subjectLabel} and one to "${stripPackage(targetName)}"`);
78
173
  }
79
174
  return { sourceField, targetField };
80
175
  }
@@ -84,25 +179,25 @@ export function deriveM2MFields(rel, source, root) {
84
179
  const a = refFkField(refs[0]);
85
180
  const b = refFkField(refs[1]);
86
181
  if (a === undefined || b === undefined) {
87
- throw new M2MDerivationError(`symmetric junction "${throughName}" for "${source.name}.${rel.name}" has a reference with no @fields`);
182
+ throw new M2MDerivationError(`symmetric junction "${throughName}" for "${declaringEntity.name}.${rel.name}" has a reference with no @fields`);
88
183
  }
89
184
  return { sourceField: a, targetField: b };
90
185
  }
91
186
  const sourceRefField = rel.sourceRefField;
92
187
  if (sourceRefField === undefined) {
93
- throw new M2MDerivationError(`self-join relationship "${source.name}.${rel.name}" through "${throughName}" is ambiguous: ` +
188
+ throw new M2MDerivationError(`self-join relationship "${declaringEntity.name}.${rel.name}" through "${throughName}" is ambiguous: ` +
94
189
  `set @sourceRefField (directed) or @symmetric (undirected)`);
95
190
  }
96
191
  // Directed self-join: @sourceRefField names the source-side FK; the other ref is the target.
97
192
  const sourceRef = refs.find((r) => refFkField(r) === sourceRefField);
98
193
  if (sourceRef === undefined) {
99
- throw new M2MDerivationError(`@sourceRefField "${sourceRefField}" on "${source.name}.${rel.name}" does not match any ` +
194
+ throw new M2MDerivationError(`@sourceRefField "${sourceRefField}" on "${declaringEntity.name}.${rel.name}" does not match any ` +
100
195
  `identity.reference FK field on junction "${throughName}"`);
101
196
  }
102
197
  const targetRef = refs.find((r) => r !== sourceRef);
103
198
  const targetField = targetRef ? refFkField(targetRef) : undefined;
104
199
  if (targetField === undefined) {
105
- throw new M2MDerivationError(`junction "${throughName}" for "${source.name}.${rel.name}" has no distinct target-side reference`);
200
+ throw new M2MDerivationError(`junction "${throughName}" for "${declaringEntity.name}.${rel.name}" has no distinct target-side reference`);
106
201
  }
107
202
  return { sourceField: sourceRefField, targetField };
108
203
  }
@@ -1 +1 @@
1
- {"version":3,"file":"derive-m2m-fields.js","sourceRoot":"","sources":["../../../src/core/relationship/derive-m2m-fields.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"derive-m2m-fields.js","sourceRoot":"","sources":["../../../src/core/relationship/derive-m2m-fields.ts"],"names":[],"mappings":"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"}
@@ -8,15 +8,31 @@ export interface ReferenceLookup {
8
8
  /** The matching identity.reference declaration on `holder`. */
9
9
  readonly referenceIdentity: MetaReferenceIdentity;
10
10
  }
11
+ /**
12
+ * Every identity.reference on `a` or `b` whose @references targets the other
13
+ * side, `a` walked first. Comparison is package-insensitive: `@references` may
14
+ * be a bare entity name ("User") or a fully-qualified one ("pkg::User"); both
15
+ * match `other.name`.
16
+ *
17
+ * #368: an entity may legally declare more than one identity.reference onto
18
+ * the same target (e.g. Match.homeTeamRef and Match.awayTeamRef both -> Team).
19
+ * Callers that must not silently guess which one is meant enumerate here and
20
+ * report the ambiguity themselves; see also `findReferenceBetween`, which
21
+ * keeps the historical first-match contract for callers that legitimately
22
+ * expect at most one reference between the pair.
23
+ */
24
+ export declare function findReferencesBetween(a: MetaObject, b: MetaObject): ReferenceLookup[];
11
25
  /**
12
26
  * Find an identity.reference on either `a` or `b` whose @references targets the
13
27
  * other side. Returns undefined if neither side declares one.
14
28
  *
15
- * Comparison is package-insensitive: `@references` may be a bare entity name
16
- * ("User") or a fully-qualified one ("pkg::User"); both match `other.name`.
17
- *
18
- * If both sides declare references targeting each other (rare, but legal for
19
- * mutual 1:1), returns the first found, walking `a` first.
29
+ * Delegates to `findReferencesBetween` and returns its first entry — kept for
30
+ * backward compatibility (this is exported public API) and for the mutual-1:1
31
+ * case where both sides declare references targeting each other. #368: two
32
+ * references onto the SAME target are also legal and indistinguishable from
33
+ * here a caller that must not guess which one is meant should call
34
+ * `findReferencesBetween` directly and handle ambiguity explicitly rather than
35
+ * relying on this function's first-match behaviour.
20
36
  */
21
37
  export declare function findReferenceBetween(a: MetaObject, b: MetaObject): ReferenceLookup | undefined;
22
38
  //# sourceMappingURL=find-reference.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"find-reference.d.ts","sourceRoot":"","sources":["../../../src/core/relationship/find-reference.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAG1E,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;CACnD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,UAAU,EACb,CAAC,EAAE,UAAU,GACZ,eAAe,GAAG,SAAS,CAS7B"}
1
+ {"version":3,"file":"find-reference.d.ts","sourceRoot":"","sources":["../../../src/core/relationship/find-reference.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAG1E,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;CACnD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,CAAC,EAAE,UAAU,EACb,CAAC,EAAE,UAAU,GACZ,eAAe,EAAE,CAUnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,UAAU,EACb,CAAC,EAAE,UAAU,GACZ,eAAe,GAAG,SAAS,CAE7B"}
@@ -7,23 +7,42 @@
7
7
  // migration schema comparison.
8
8
  import { stripPackage } from "../../naming.js";
9
9
  /**
10
- * Find an identity.reference on either `a` or `b` whose @references targets the
11
- * other side. Returns undefined if neither side declares one.
12
- *
13
- * Comparison is package-insensitive: `@references` may be a bare entity name
14
- * ("User") or a fully-qualified one ("pkg::User"); both match `other.name`.
10
+ * Every identity.reference on `a` or `b` whose @references targets the other
11
+ * side, `a` walked first. Comparison is package-insensitive: `@references` may
12
+ * be a bare entity name ("User") or a fully-qualified one ("pkg::User"); both
13
+ * match `other.name`.
15
14
  *
16
- * If both sides declare references targeting each other (rare, but legal for
17
- * mutual 1:1), returns the first found, walking `a` first.
15
+ * #368: an entity may legally declare more than one identity.reference onto
16
+ * the same target (e.g. Match.homeTeamRef and Match.awayTeamRef both -> Team).
17
+ * Callers that must not silently guess which one is meant enumerate here and
18
+ * report the ambiguity themselves; see also `findReferenceBetween`, which
19
+ * keeps the historical first-match contract for callers that legitimately
20
+ * expect at most one reference between the pair.
18
21
  */
19
- export function findReferenceBetween(a, b) {
22
+ export function findReferencesBetween(a, b) {
23
+ const found = [];
20
24
  for (const [holder, other] of [[a, b], [b, a]]) {
21
25
  for (const ref of holder.referenceIdentities()) {
22
26
  if (stripPackage(ref.targetEntity) === other.name) {
23
- return { holder, other, referenceIdentity: ref };
27
+ found.push({ holder, other, referenceIdentity: ref });
24
28
  }
25
29
  }
26
30
  }
27
- return undefined;
31
+ return found;
32
+ }
33
+ /**
34
+ * Find an identity.reference on either `a` or `b` whose @references targets the
35
+ * other side. Returns undefined if neither side declares one.
36
+ *
37
+ * Delegates to `findReferencesBetween` and returns its first entry — kept for
38
+ * backward compatibility (this is exported public API) and for the mutual-1:1
39
+ * case where both sides declare references targeting each other. #368: two
40
+ * references onto the SAME target are also legal and indistinguishable from
41
+ * here — a caller that must not guess which one is meant should call
42
+ * `findReferencesBetween` directly and handle ambiguity explicitly rather than
43
+ * relying on this function's first-match behaviour.
44
+ */
45
+ export function findReferenceBetween(a, b) {
46
+ return findReferencesBetween(a, b)[0];
28
47
  }
29
48
  //# sourceMappingURL=find-reference.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"find-reference.js","sourceRoot":"","sources":["../../../src/core/relationship/find-reference.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,4EAA4E;AAC5E,gFAAgF;AAChF,2EAA2E;AAC3E,0EAA0E;AAC1E,+BAA+B;AAI/B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAW/C;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAClC,CAAa,EACb,CAAa;IAEb,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAU,EAAE,CAAC;QACxD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,mBAAmB,EAAE,EAAE,CAAC;YAC/C,IAAI,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;gBAClD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,CAAC;YACnD,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"find-reference.js","sourceRoot":"","sources":["../../../src/core/relationship/find-reference.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,4EAA4E;AAC5E,gFAAgF;AAChF,2EAA2E;AAC3E,0EAA0E;AAC1E,+BAA+B;AAI/B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAW/C;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CACnC,CAAa,EACb,CAAa;IAEb,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAU,EAAE,CAAC;QACxD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,mBAAmB,EAAE,EAAE,CAAC;YAC/C,IAAI,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;gBAClD,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAClC,CAAa,EACb,CAAa;IAEb,OAAO,qBAAqB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACxC,CAAC"}
@@ -5,7 +5,7 @@ export const RELATIONSHIP_DEFINITION = {
5
5
  "type": "relationship",
6
6
  "subType": "base",
7
7
  "description": "Abstract relationship base — shared shape for the concrete association/aggregation/composition subtypes; not authored directly. A `relationship.base` node fails to load (ERR_ABSTRACT_SUBTYPE_AUTHORED): this subtype is a registry anchor concrete subtypes inherit from, never a node in a document.",
8
- "rules": "@cardinality is an open string at the metamodel level ('one'/'many', and Java-canonical composite forms such as 'many-to-one'); @objectRef names the target entity. M:N is expressed by @cardinality:'many' + @objectRef + @through: @through names a junction entity that MUST declare two identity.reference children (one per FK side), and the relationship's FK fields are DERIVED from those references — never restated. @sourceRefField disambiguates a DIRECTED self-join by naming the source-side FK field on the junction; @symmetric marks an UNDIRECTED self-join (union-on-read) valid only when @objectRef == the declaring entity; the two are mutually exclusive. @onDelete/@onUpdate carry referential actions (cascade/set-null/restrict/no-action).",
8
+ "rules": "@cardinality is an open string at the metamodel level ('one'/'many', and Java-canonical composite forms such as 'many-to-one'); @objectRef names the target entity. M:N is expressed by @cardinality:'many' + @objectRef + @through: @through names a junction entity that MUST declare two identity.reference children (one per FK side), and the relationship's FK fields are DERIVED from those references — never restated. @sourceRefField disambiguates a DIRECTED self-join by naming the source-side FK field on the junction, or on a @cardinality:'one' relationship names which of several identity.reference nodes onto the same target it navigates when name-pairing does not resolve it uniquely; @symmetric marks an UNDIRECTED self-join (union-on-read) valid only when @objectRef == the declaring entity; the two are mutually exclusive. @onDelete/@onUpdate carry referential actions (cascade/set-null/restrict/no-action).",
9
9
  "children": [
10
10
  {
11
11
  "type": "attr",
@@ -37,7 +37,7 @@ export const RELATIONSHIP_DEFINITION = {
37
37
  "name": "sourceRefField",
38
38
  "min": 0,
39
39
  "max": 1,
40
- "description": "Directed self-join disambiguator: names the source-side FK field on the junction (the other reference is the target side). Required only for directed/ambiguous self-join M:N. Mutually exclusive with @symmetric."
40
+ "description": "Disambiguates which reference/FK field a relationship uses when more than one candidate exists: on a directed self-join M:N it names the junction's source-side reference (mutually exclusive with @symmetric), and on a @cardinality:'one' relationship it names which of several identity.reference nodes onto the same target the relationship navigates when name-pairing does not resolve it uniquely."
41
41
  },
42
42
  {
43
43
  "type": "attr",
@@ -82,7 +82,7 @@ export const RELATIONSHIP_DEFINITION = {
82
82
  "subType": "association",
83
83
  "description": "A plain reference to another entity — no ownership; the target has an independent lifecycle (default @onDelete restrict).",
84
84
  "whenToUse": "A plain directed reference to another entity, no ownership or cascade. The lightest link — when you just need to point at another entity.",
85
- "rules": "M:N is expressed by @cardinality:'many' + @objectRef + @through: @through names a junction entity that MUST declare two identity.reference children (one per FK side), and the relationship's FK fields are DERIVED from those references — never restated. @sourceRefField disambiguates a DIRECTED self-join by naming the source-side FK field on the junction; @symmetric marks an UNDIRECTED self-join (union-on-read) valid only when @objectRef == the declaring entity; the two are mutually exclusive. Association is a plain reference — the target's lifecycle is independent (default @onDelete restrict).",
85
+ "rules": "M:N is expressed by @cardinality:'many' + @objectRef + @through: @through names a junction entity that MUST declare two identity.reference children (one per FK side), and the relationship's FK fields are DERIVED from those references — never restated. @sourceRefField disambiguates a DIRECTED self-join by naming the source-side FK field on the junction, or on a @cardinality:'one' relationship names which of several identity.reference nodes onto the same target it navigates when name-pairing does not resolve it uniquely; @symmetric marks an UNDIRECTED self-join (union-on-read) valid only when @objectRef == the declaring entity; the two are mutually exclusive. Association is a plain reference — the target's lifecycle is independent (default @onDelete restrict).",
86
86
  "children": [
87
87
  {
88
88
  "type": "attr",
@@ -114,7 +114,7 @@ export const RELATIONSHIP_DEFINITION = {
114
114
  "name": "sourceRefField",
115
115
  "min": 0,
116
116
  "max": 1,
117
- "description": "Directed self-join disambiguator: names the source-side FK field on the junction (the other reference is the target side). Required only for directed/ambiguous self-join M:N. Mutually exclusive with @symmetric."
117
+ "description": "Disambiguates which reference/FK field a relationship uses when more than one candidate exists: on a directed self-join M:N it names the junction's source-side reference (mutually exclusive with @symmetric), and on a @cardinality:'one' relationship it names which of several identity.reference nodes onto the same target the relationship navigates when name-pairing does not resolve it uniquely."
118
118
  },
119
119
  {
120
120
  "type": "attr",
@@ -159,7 +159,7 @@ export const RELATIONSHIP_DEFINITION = {
159
159
  "subType": "aggregation",
160
160
  "description": "A shared/independent containment — the parent groups the target but does not own its lifecycle (default @onDelete set-null).",
161
161
  "whenToUse": "One entity groups others it does NOT own (children outlive the parent; delete sets the FK null). Use instead of composition when there is no ownership.",
162
- "rules": "M:N is expressed by @cardinality:'many' + @objectRef + @through: @through names a junction entity that MUST declare two identity.reference children (one per FK side), and the relationship's FK fields are DERIVED from those references — never restated. @sourceRefField disambiguates a DIRECTED self-join by naming the source-side FK field on the junction; @symmetric marks an UNDIRECTED self-join (union-on-read) valid only when @objectRef == the declaring entity; the two are mutually exclusive. Aggregation is shared/independent — the target outlives the parent (default @onDelete set-null).",
162
+ "rules": "M:N is expressed by @cardinality:'many' + @objectRef + @through: @through names a junction entity that MUST declare two identity.reference children (one per FK side), and the relationship's FK fields are DERIVED from those references — never restated. @sourceRefField disambiguates a DIRECTED self-join by naming the source-side FK field on the junction, or on a @cardinality:'one' relationship names which of several identity.reference nodes onto the same target it navigates when name-pairing does not resolve it uniquely; @symmetric marks an UNDIRECTED self-join (union-on-read) valid only when @objectRef == the declaring entity; the two are mutually exclusive. Aggregation is shared/independent — the target outlives the parent (default @onDelete set-null).",
163
163
  "children": [
164
164
  {
165
165
  "type": "attr",
@@ -191,7 +191,7 @@ export const RELATIONSHIP_DEFINITION = {
191
191
  "name": "sourceRefField",
192
192
  "min": 0,
193
193
  "max": 1,
194
- "description": "Directed self-join disambiguator: names the source-side FK field on the junction (the other reference is the target side). Required only for directed/ambiguous self-join M:N. Mutually exclusive with @symmetric."
194
+ "description": "Disambiguates which reference/FK field a relationship uses when more than one candidate exists: on a directed self-join M:N it names the junction's source-side reference (mutually exclusive with @symmetric), and on a @cardinality:'one' relationship it names which of several identity.reference nodes onto the same target the relationship navigates when name-pairing does not resolve it uniquely."
195
195
  },
196
196
  {
197
197
  "type": "attr",
@@ -236,7 +236,7 @@ export const RELATIONSHIP_DEFINITION = {
236
236
  "subType": "composition",
237
237
  "description": "An owned containment — the parent owns the target's lifecycle; deleting the parent deletes the children (default @onDelete cascade).",
238
238
  "whenToUse": "You need a parent that OWNS a child collection (one-to-many, cascade on delete). Declare it to generate the FK + typed navigation instead of a bare FK field + hand-written joins.",
239
- "rules": "M:N is expressed by @cardinality:'many' + @objectRef + @through: @through names a junction entity that MUST declare two identity.reference children (one per FK side), and the relationship's FK fields are DERIVED from those references — never restated. @sourceRefField disambiguates a DIRECTED self-join by naming the source-side FK field on the junction; @symmetric marks an UNDIRECTED self-join (union-on-read) valid only when @objectRef == the declaring entity; the two are mutually exclusive. Composition is owned lifecycle — the children do not outlive the parent (default @onDelete cascade).",
239
+ "rules": "M:N is expressed by @cardinality:'many' + @objectRef + @through: @through names a junction entity that MUST declare two identity.reference children (one per FK side), and the relationship's FK fields are DERIVED from those references — never restated. @sourceRefField disambiguates a DIRECTED self-join by naming the source-side FK field on the junction, or on a @cardinality:'one' relationship names which of several identity.reference nodes onto the same target it navigates when name-pairing does not resolve it uniquely; @symmetric marks an UNDIRECTED self-join (union-on-read) valid only when @objectRef == the declaring entity; the two are mutually exclusive. Composition is owned lifecycle — the children do not outlive the parent (default @onDelete cascade).",
240
240
  "children": [
241
241
  {
242
242
  "type": "attr",
@@ -268,7 +268,7 @@ export const RELATIONSHIP_DEFINITION = {
268
268
  "name": "sourceRefField",
269
269
  "min": 0,
270
270
  "max": 1,
271
- "description": "Directed self-join disambiguator: names the source-side FK field on the junction (the other reference is the target side). Required only for directed/ambiguous self-join M:N. Mutually exclusive with @symmetric."
271
+ "description": "Disambiguates which reference/FK field a relationship uses when more than one candidate exists: on a directed self-join M:N it names the junction's source-side reference (mutually exclusive with @symmetric), and on a @cardinality:'one' relationship it names which of several identity.reference nodes onto the same target the relationship navigates when name-pairing does not resolve it uniquely."
272
272
  },
273
273
  {
274
274
  "type": "attr",
@@ -1 +1 @@
1
- {"version":3,"file":"relationship-definition.embedded.js","sourceRoot":"","sources":["../../../src/core/relationship/relationship-definition.embedded.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relationship-definition.embedded.js","sourceRoot":"","sources":["../../../src/core/relationship/relationship-definition.embedded.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { MetaObject } from "../object/meta-object.js";
2
+ import type { MetaReferenceIdentity } from "../identity/meta-identity.js";
3
+ /**
4
+ * The set of lowercased names a candidate reference answers to: its own name
5
+ * and its FK field, each with and without one stripped suffix.
6
+ */
7
+ export declare function referencePairingKeys(ref: MetaReferenceIdentity): Set<string>;
8
+ /**
9
+ * Every identity.reference on `holder` whose @references targets `targetEntity`.
10
+ * Package-insensitive on both sides: @references and @objectRef may each be bare
11
+ * or fully qualified.
12
+ */
13
+ export declare function referenceCandidatesFor(holder: MetaObject, targetEntity: string): MetaReferenceIdentity[];
14
+ /**
15
+ * Which identity.reference does this `@cardinality: one` relationship navigate
16
+ * through? The ladder, in order:
17
+ *
18
+ * 1. exactly one candidate -> that one (the common case; unchanged behaviour)
19
+ * 2. `@sourceRefField` declared -> the candidate whose FK field it names
20
+ * 3. exactly one candidate name-pairs -> that one
21
+ * 4. otherwise -> undefined (caller reports the ambiguity)
22
+ *
23
+ * Returns undefined for "no candidate" and "cannot choose" alike; callers that
24
+ * need to tell them apart use referenceCandidatesFor().
25
+ */
26
+ export declare function resolveRelationshipReference(holder: MetaObject, relationshipName: string, targetEntity: string, sourceRefField?: string): MetaReferenceIdentity | undefined;
27
+ //# sourceMappingURL=resolve-relationship-reference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-relationship-reference.d.ts","sourceRoot":"","sources":["../../../src/core/relationship/resolve-relationship-reference.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAwB1E;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,qBAAqB,GAAG,GAAG,CAAC,MAAM,CAAC,CAW5E;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,MAAM,GACnB,qBAAqB,EAAE,CAOzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,UAAU,EAClB,gBAAgB,EAAE,MAAM,EACxB,YAAY,EAAE,MAAM,EACpB,cAAc,CAAC,EAAE,MAAM,GACtB,qBAAqB,GAAG,SAAS,CAYnC"}
@@ -0,0 +1,84 @@
1
+ // Association -> identity.reference resolution (issue #368).
2
+ //
3
+ // An entity may declare more than one identity.reference onto the SAME target
4
+ // entity (Match.homeTeamRef and Match.awayTeamRef both -> Team). A
5
+ // `@cardinality: one` relationship names only its target, so when two
6
+ // references match, the target alone cannot say which FK the navigation uses.
7
+ // Taking the first match emits a join on the wrong column that typechecks, has
8
+ // correct DDL and passes verify — so the ladder below resolves it explicitly or
9
+ // not at all. ADR-0029 §5: ambiguity is a load error naming the candidates.
10
+ import { stripPackage } from "../../naming.js";
11
+ /**
12
+ * Trailing suffixes stripped from a CANDIDATE's name/FK field when building its
13
+ * pairing keys. Ordered — first match wins, so "reference" is tested before
14
+ * "ref". Never applied to the relationship name (see referencePairingKeys).
15
+ */
16
+ const PAIRING_SUFFIXES = ["reference", "ref", "id", "key"];
17
+ function stripOneSuffix(value) {
18
+ for (const suffix of PAIRING_SUFFIXES) {
19
+ if (value.length > suffix.length && value.endsWith(suffix)) {
20
+ return value.slice(0, value.length - suffix.length);
21
+ }
22
+ }
23
+ return value;
24
+ }
25
+ /** The FK field a reference is anchored on (first field; composite FKs pair on their first column). */
26
+ function refFkField(ref) {
27
+ return ref.fields.length > 0 ? ref.fields[0] : undefined;
28
+ }
29
+ /**
30
+ * The set of lowercased names a candidate reference answers to: its own name
31
+ * and its FK field, each with and without one stripped suffix.
32
+ */
33
+ export function referencePairingKeys(ref) {
34
+ const keys = new Set();
35
+ const add = (value) => {
36
+ if (!value)
37
+ return;
38
+ const lower = value.toLowerCase();
39
+ keys.add(lower);
40
+ keys.add(stripOneSuffix(lower));
41
+ };
42
+ add(ref.name);
43
+ add(refFkField(ref));
44
+ return keys;
45
+ }
46
+ /**
47
+ * Every identity.reference on `holder` whose @references targets `targetEntity`.
48
+ * Package-insensitive on both sides: @references and @objectRef may each be bare
49
+ * or fully qualified.
50
+ */
51
+ export function referenceCandidatesFor(holder, targetEntity) {
52
+ const target = stripPackage(targetEntity);
53
+ // ADR-0039: resolving — referenceIdentities() honors references inherited via extends.
54
+ return holder
55
+ .referenceIdentities()
56
+ .filter((ref) => stripPackage(ref.targetEntity ?? "") === target)
57
+ .filter((ref) => refFkField(ref) !== undefined);
58
+ }
59
+ /**
60
+ * Which identity.reference does this `@cardinality: one` relationship navigate
61
+ * through? The ladder, in order:
62
+ *
63
+ * 1. exactly one candidate -> that one (the common case; unchanged behaviour)
64
+ * 2. `@sourceRefField` declared -> the candidate whose FK field it names
65
+ * 3. exactly one candidate name-pairs -> that one
66
+ * 4. otherwise -> undefined (caller reports the ambiguity)
67
+ *
68
+ * Returns undefined for "no candidate" and "cannot choose" alike; callers that
69
+ * need to tell them apart use referenceCandidatesFor().
70
+ */
71
+ export function resolveRelationshipReference(holder, relationshipName, targetEntity, sourceRefField) {
72
+ const candidates = referenceCandidatesFor(holder, targetEntity);
73
+ if (candidates.length === 0)
74
+ return undefined;
75
+ if (candidates.length === 1)
76
+ return candidates[0];
77
+ if (sourceRefField !== undefined && sourceRefField !== "") {
78
+ return candidates.find((ref) => refFkField(ref) === sourceRefField);
79
+ }
80
+ const wanted = relationshipName.toLowerCase();
81
+ const paired = candidates.filter((ref) => referencePairingKeys(ref).has(wanted));
82
+ return paired.length === 1 ? paired[0] : undefined;
83
+ }
84
+ //# sourceMappingURL=resolve-relationship-reference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-relationship-reference.js","sourceRoot":"","sources":["../../../src/core/relationship/resolve-relationship-reference.ts"],"names":[],"mappings":"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"}