@metaobjectsdev/runtime-ts 1.0.3 → 1.0.4

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.
@@ -1,4 +1,4 @@
1
- import type { FastifyInstance } from "fastify";
1
+ import type { FastifyInstance, RouteShorthandOptions } from "fastify";
2
2
  import type { FilterAllowlist, SortAllowlist } from "./filter-allowlist.js";
3
3
  type AnyView = any;
4
4
  export interface MountReadOnlyOptions {
@@ -11,6 +11,17 @@ export interface MountReadOnlyOptions {
11
11
  readonly dialect: "postgres" | "sqlite";
12
12
  /** Override default ID column name (defaults to "id"). */
13
13
  readonly idColumn?: string;
14
+ /**
15
+ * Fastify route-level hooks applied to every route this mounts — the same option
16
+ * `mountCrudRoutes` and `mountM2mRoute` take, and for the same reason:
17
+ * routeOptions: { preHandler: requireAuthHook }
18
+ *
19
+ * A projection is read-only, not public. It was the one mount helper of the three
20
+ * without this, so a generated projection route could not carry a hook the way a
21
+ * generated entity route could — an inconsistency, not a policy. (Guarding the whole
22
+ * mount from an enclosing plugin scope works here too, and needs no option at all.)
23
+ */
24
+ readonly routeOptions?: RouteShorthandOptions;
14
25
  }
15
26
  export declare function mountReadOnlyCrudRoutes(opts: MountReadOnlyOptions): void;
16
27
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"mount-read-only.d.ts","sourceRoot":"","sources":["../../src/drizzle-fastify/mount-read-only.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAI/C,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAI5E,KAAK,OAAO,GAAG,GAAG,CAAC;AAUnB,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC;IACjB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,QAAQ,CAAC;IACxC,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AA8FD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAuGxE"}
1
+ {"version":3,"file":"mount-read-only.d.ts","sourceRoot":"","sources":["../../src/drizzle-fastify/mount-read-only.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAItE,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAI5E,KAAK,OAAO,GAAG,GAAG,CAAC;AAUnB,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC;IACjB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,QAAQ,CAAC;IACxC,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,qBAAqB,CAAC;CAC/C;AA8FD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAwGxE"}
@@ -96,10 +96,11 @@ async function rawRows(db, dialect, query) {
96
96
  export function mountReadOnlyCrudRoutes(opts) {
97
97
  const { fastify, path, db, view, filterAllowlist, sortAllowlist, dialect } = opts;
98
98
  const idCol = opts.idColumn ?? "id";
99
+ const ro = opts.routeOptions ?? {};
99
100
  const viewName = resolveViewName(view);
100
101
  const useRawSql = isEmptyColumnView(view) && !!viewName;
101
102
  // ── List ──────────────────────────────────────────────────────────────────
102
- fastify.get(path, async (req, reply) => {
103
+ fastify.get(path, ro, async (req, reply) => {
103
104
  try {
104
105
  if (useRawSql) {
105
106
  // .existing() view with no column schema — use raw SQL.
@@ -171,7 +172,7 @@ export function mountReadOnlyCrudRoutes(opts) {
171
172
  }
172
173
  });
173
174
  // ── Get by ID ─────────────────────────────────────────────────────────────
174
- fastify.get(`${path}/:id`, async (req, reply) => {
175
+ fastify.get(`${path}/:id`, ro, async (req, reply) => {
175
176
  const { id } = req.params;
176
177
  if (useRawSql) {
177
178
  // biome-ignore lint/suspicious/noExplicitAny: dynamic raw result
@@ -192,8 +193,8 @@ export function mountReadOnlyCrudRoutes(opts) {
192
193
  return row ?? reply.code(404).send({ error: "not_found" });
193
194
  });
194
195
  // ── Mutations explicitly rejected (405) ───────────────────────────────────
195
- fastify.post(path, REJECT_MUTATION);
196
- fastify.patch(`${path}/:id`, REJECT_MUTATION);
197
- fastify.delete(`${path}/:id`, REJECT_MUTATION);
196
+ fastify.post(path, ro, REJECT_MUTATION);
197
+ fastify.patch(`${path}/:id`, ro, REJECT_MUTATION);
198
+ fastify.delete(`${path}/:id`, ro, REJECT_MUTATION);
198
199
  }
199
200
  //# sourceMappingURL=mount-read-only.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mount-read-only.js","sourceRoot":"","sources":["../../src/drizzle-fastify/mount-read-only.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mount-read-only.js","sourceRoot":"","sources":["../../src/drizzle-fastify/mount-read-only.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"relation-resolver.d.ts","sourceRoot":"","sources":["../src/relation-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAML,eAAe,EAAE,gBAAgB,EAElC,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAE,UAAU,EAAkB,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAE/E,MAAM,WAAW,kBAAkB;IACjC,4GAA4G;IAC5G,WAAW,EAAE,OAAO,eAAe,GAAG,OAAO,gBAAgB,CAAC;IAC9D,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,4GAA4G;IAC5G,WAAW,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAC;CACrB;AA2BD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,QAAQ,EACtB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,QAAQ,GACb,kBAAkB,CAwEpB;AAUD,uFAAuF;AACvF,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,kBAAkB,EACxB,YAAY,EAAE,GAAG,EACjB,IAAI,EAAE,QAAQ,EACd,QAAQ,GAAE,oBAAqD,GAC9D,UAAU,GAAG,IAAI,CAKnB;AAED,gGAAgG;AAChG,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,kBAAkB,EACxB,aAAa,EAAE,GAAG,EAAE,EACpB,IAAI,EAAE,QAAQ,EACd,QAAQ,GAAE,oBAAqD,GAC9D,UAAU,GAAG,IAAI,CAUnB"}
1
+ {"version":3,"file":"relation-resolver.d.ts","sourceRoot":"","sources":["../src/relation-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAc,MAAM,0BAA0B,CAAC;AAC3F,OAAO,EAIL,eAAe,EAAE,gBAAgB,EAGlC,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAE,UAAU,EAAkB,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAE/E,MAAM,WAAW,kBAAkB;IACjC,4GAA4G;IAC5G,WAAW,EAAE,OAAO,eAAe,GAAG,OAAO,gBAAgB,CAAC;IAC9D,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,4GAA4G;IAC5G,WAAW,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAC;CACrB;AAmBD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,QAAQ,EACtB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,QAAQ,GACb,kBAAkB,CA8EpB;AAUD,uFAAuF;AACvF,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,kBAAkB,EACxB,YAAY,EAAE,GAAG,EACjB,IAAI,EAAE,QAAQ,EACd,QAAQ,GAAE,oBAAqD,GAC9D,UAAU,GAAG,IAAI,CAKnB;AAED,gGAAgG;AAChG,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,kBAAkB,EACxB,aAAa,EAAE,GAAG,EAAE,EACpB,IAAI,EAAE,QAAQ,EACd,QAAQ,GAAE,oBAAqD,GAC9D,UAAU,GAAG,IAAI,CAUnB"}
@@ -1,35 +1,14 @@
1
- import { TYPE_OBJECT, TYPE_RELATIONSHIP, TYPE_IDENTITY, IDENTITY_SUBTYPE_REFERENCE, IDENTITY_ATTR_FIELDS, IDENTITY_REFERENCE_ATTR_REFERENCES, RELATIONSHIP_ATTR_CARDINALITY, RELATIONSHIP_ATTR_OBJECT_REF, CARDINALITY_ONE, CARDINALITY_MANY, DEFAULT_COLUMN_NAMING_STRATEGY, } from "@metaobjectsdev/metadata";
1
+ import { TYPE_OBJECT, TYPE_RELATIONSHIP, RELATIONSHIP_ATTR_CARDINALITY, RELATIONSHIP_ATTR_OBJECT_REF, RELATIONSHIP_ATTR_SOURCE_REF_FIELD, CARDINALITY_ONE, CARDINALITY_MANY, DEFAULT_COLUMN_NAMING_STRATEGY, resolveRelationshipReference, } from "@metaobjectsdev/metadata";
2
2
  import { MetadataError } from "./errors.js";
3
3
  import { buildSelectSpec, resolvePkFields, } from "./query-builder.js";
4
4
  /**
5
- * Find an identity.reference declared on `holder` whose @references targets `targetName`.
6
- * Returns the FK field name (first field on the identity) or undefined.
5
+ * The FK field a `@cardinality: one` relationship navigates through.
6
+ * #368: an entity may declare several identity.reference nodes onto the same
7
+ * target, so the target alone is not enough — resolve through the shared ladder.
7
8
  */
8
- function findReferenceFkField(holder, targetName) {
9
- // ADR-0039: effective children an identity.reference may be inherited via extends.
10
- for (const child of holder.children()) {
11
- if (child.type !== TYPE_IDENTITY)
12
- continue;
13
- if (child.subType !== IDENTITY_SUBTYPE_REFERENCE)
14
- continue;
15
- // ADR-0039: effective attrs — @references/@fields may be inherited.
16
- const ref = child.attr(IDENTITY_REFERENCE_ATTR_REFERENCES);
17
- if (typeof ref !== "string")
18
- continue;
19
- const dotIdx = ref.indexOf(".");
20
- const entityName = dotIdx === -1 ? ref : ref.slice(0, dotIdx);
21
- if (entityName !== targetName)
22
- continue;
23
- const fields = child.attr(IDENTITY_ATTR_FIELDS);
24
- if (Array.isArray(fields) && fields.length > 0)
25
- return String(fields[0]);
26
- if (typeof fields === "string") {
27
- const first = fields.split(",")[0]?.trim();
28
- if (first)
29
- return first;
30
- }
31
- }
32
- return undefined;
9
+ function findReferenceFkField(holder, targetName, relationshipName, sourceRefField) {
10
+ const ref = resolveRelationshipReference(holder, relationshipName, targetName, sourceRefField);
11
+ return ref?.fields[0];
33
12
  }
34
13
  /**
35
14
  * Walks one-side (relationship children of `sourceEntity`) then many-side (relationship
@@ -54,7 +33,9 @@ export function resolveRelationDescriptor(sourceEntity, relationName, root) {
54
33
  if (!targetEntityName) {
55
34
  throw new MetadataError(`Relationship '${relationName}' on '${sourceEntity.name}' missing @objectRef`, { entity: sourceEntity.name });
56
35
  }
57
- const fkField = findReferenceFkField(sourceEntity, targetEntityName);
36
+ // ADR-0039: resolving @sourceRefField may be inherited via extends.
37
+ const declaredRefField = child.attr(RELATIONSHIP_ATTR_SOURCE_REF_FIELD);
38
+ const fkField = findReferenceFkField(sourceEntity, targetEntityName, child.name, declaredRefField);
58
39
  if (!fkField) {
59
40
  throw new MetadataError(`Relationship '${relationName}' on '${sourceEntity.name}' has no identity.reference targeting '${targetEntityName}'`, { entity: sourceEntity.name });
60
41
  }
@@ -90,7 +71,11 @@ export function resolveRelationDescriptor(sourceEntity, relationName, root) {
90
71
  const inverseName = inversePluralName(other.name);
91
72
  if (inverseName !== relationName)
92
73
  continue;
93
- const fkField = findReferenceFkField(other, sourceEntity.name);
74
+ // ADR-0039: resolving @sourceRefField may be inherited via extends. This
75
+ // FK lives on `other` and belongs to `other`'s own relationship `child` —
76
+ // not to anything declared on sourceEntity (see #368 module comment).
77
+ const declaredRefField = child.attr(RELATIONSHIP_ATTR_SOURCE_REF_FIELD);
78
+ const fkField = findReferenceFkField(other, sourceEntity.name, child.name, declaredRefField);
94
79
  if (!fkField) {
95
80
  throw new MetadataError(`Inverse relationship for '${relationName}' on '${sourceEntity.name}': entity '${other.name}' has no identity.reference targeting '${sourceEntity.name}'`, { entity: sourceEntity.name });
96
81
  }
@@ -1 +1 @@
1
- {"version":3,"file":"relation-resolver.js","sourceRoot":"","sources":["../src/relation-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relation-resolver.js","sourceRoot":"","sources":["../src/relation-resolver.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaobjectsdev/runtime-ts",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Node-side runtime helpers for MetaObjects: Fastify route builders, Drizzle filter/sort integration, Kysely drivers.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -64,8 +64,8 @@
64
64
  "access": "public"
65
65
  },
66
66
  "dependencies": {
67
- "@metaobjectsdev/metadata": "1.0.3",
68
- "@metaobjectsdev/render": "1.0.3",
67
+ "@metaobjectsdev/metadata": "1.0.4",
68
+ "@metaobjectsdev/render": "1.0.4",
69
69
  "qs": "^6.13.0"
70
70
  },
71
71
  "peerDependencies": {
@@ -1,4 +1,4 @@
1
- import type { FastifyInstance } from "fastify";
1
+ import type { FastifyInstance, RouteShorthandOptions } from "fastify";
2
2
  import { sql, eq, and, count } from "drizzle-orm";
3
3
  import qs from "qs";
4
4
  import { parseFilterParams, FilterParseError } from "./filter-parser.js";
@@ -27,6 +27,17 @@ export interface MountReadOnlyOptions {
27
27
  readonly dialect: "postgres" | "sqlite";
28
28
  /** Override default ID column name (defaults to "id"). */
29
29
  readonly idColumn?: string;
30
+ /**
31
+ * Fastify route-level hooks applied to every route this mounts — the same option
32
+ * `mountCrudRoutes` and `mountM2mRoute` take, and for the same reason:
33
+ * routeOptions: { preHandler: requireAuthHook }
34
+ *
35
+ * A projection is read-only, not public. It was the one mount helper of the three
36
+ * without this, so a generated projection route could not carry a hook the way a
37
+ * generated entity route could — an inconsistency, not a policy. (Guarding the whole
38
+ * mount from an enclosing plugin scope works here too, and needs no option at all.)
39
+ */
40
+ readonly routeOptions?: RouteShorthandOptions;
30
41
  }
31
42
 
32
43
  const REJECT_MUTATION = async (
@@ -124,12 +135,13 @@ async function rawRows(db: any, dialect: string | undefined, query: unknown): Pr
124
135
  export function mountReadOnlyCrudRoutes(opts: MountReadOnlyOptions): void {
125
136
  const { fastify, path, db, view, filterAllowlist, sortAllowlist, dialect } = opts;
126
137
  const idCol = opts.idColumn ?? "id";
138
+ const ro = opts.routeOptions ?? {};
127
139
 
128
140
  const viewName = resolveViewName(view);
129
141
  const useRawSql = isEmptyColumnView(view) && !!viewName;
130
142
 
131
143
  // ── List ──────────────────────────────────────────────────────────────────
132
- fastify.get(path, async (req, reply) => {
144
+ fastify.get(path, ro, async (req, reply) => {
133
145
  try {
134
146
  if (useRawSql) {
135
147
  // .existing() view with no column schema — use raw SQL.
@@ -197,7 +209,7 @@ export function mountReadOnlyCrudRoutes(opts: MountReadOnlyOptions): void {
197
209
  });
198
210
 
199
211
  // ── Get by ID ─────────────────────────────────────────────────────────────
200
- fastify.get(`${path}/:id`, async (req, reply) => {
212
+ fastify.get(`${path}/:id`, ro, async (req, reply) => {
201
213
  const { id } = req.params as { id: string };
202
214
  if (useRawSql) {
203
215
  // biome-ignore lint/suspicious/noExplicitAny: dynamic raw result
@@ -221,7 +233,7 @@ export function mountReadOnlyCrudRoutes(opts: MountReadOnlyOptions): void {
221
233
  });
222
234
 
223
235
  // ── Mutations explicitly rejected (405) ───────────────────────────────────
224
- fastify.post(path, REJECT_MUTATION);
225
- fastify.patch(`${path}/:id`, REJECT_MUTATION);
226
- fastify.delete(`${path}/:id`, REJECT_MUTATION);
236
+ fastify.post(path, ro, REJECT_MUTATION);
237
+ fastify.patch(`${path}/:id`, ro, REJECT_MUTATION);
238
+ fastify.delete(`${path}/:id`, ro, REJECT_MUTATION);
227
239
  }
@@ -1,12 +1,11 @@
1
- import type { ColumnNamingStrategy, MetaData } from "@metaobjectsdev/metadata";
1
+ import type { ColumnNamingStrategy, MetaData, MetaObject } from "@metaobjectsdev/metadata";
2
2
  import {
3
- TYPE_OBJECT, TYPE_RELATIONSHIP, TYPE_IDENTITY,
4
- IDENTITY_SUBTYPE_REFERENCE,
5
- IDENTITY_ATTR_FIELDS,
6
- IDENTITY_REFERENCE_ATTR_REFERENCES,
3
+ TYPE_OBJECT, TYPE_RELATIONSHIP,
7
4
  RELATIONSHIP_ATTR_CARDINALITY, RELATIONSHIP_ATTR_OBJECT_REF,
5
+ RELATIONSHIP_ATTR_SOURCE_REF_FIELD,
8
6
  CARDINALITY_ONE, CARDINALITY_MANY,
9
7
  DEFAULT_COLUMN_NAMING_STRATEGY,
8
+ resolveRelationshipReference,
10
9
  } from "@metaobjectsdev/metadata";
11
10
  import { MetadataError } from "./errors.js";
12
11
  import {
@@ -26,28 +25,20 @@ export interface RelationDescriptor {
26
25
  }
27
26
 
28
27
  /**
29
- * Find an identity.reference declared on `holder` whose @references targets `targetName`.
30
- * Returns the FK field name (first field on the identity) or undefined.
28
+ * The FK field a `@cardinality: one` relationship navigates through.
29
+ * #368: an entity may declare several identity.reference nodes onto the same
30
+ * target, so the target alone is not enough — resolve through the shared ladder.
31
31
  */
32
- function findReferenceFkField(holder: MetaData, targetName: string): string | undefined {
33
- // ADR-0039: effective children — an identity.reference may be inherited via extends.
34
- for (const child of holder.children()) {
35
- if (child.type !== TYPE_IDENTITY) continue;
36
- if (child.subType !== IDENTITY_SUBTYPE_REFERENCE) continue;
37
- // ADR-0039: effective attrs @references/@fields may be inherited.
38
- const ref = child.attr(IDENTITY_REFERENCE_ATTR_REFERENCES);
39
- if (typeof ref !== "string") continue;
40
- const dotIdx = ref.indexOf(".");
41
- const entityName = dotIdx === -1 ? ref : ref.slice(0, dotIdx);
42
- if (entityName !== targetName) continue;
43
- const fields = child.attr(IDENTITY_ATTR_FIELDS);
44
- if (Array.isArray(fields) && fields.length > 0) return String(fields[0]);
45
- if (typeof fields === "string") {
46
- const first = fields.split(",")[0]?.trim();
47
- if (first) return first;
48
- }
49
- }
50
- return undefined;
32
+ function findReferenceFkField(
33
+ holder: MetaData,
34
+ targetName: string,
35
+ relationshipName: string,
36
+ sourceRefField?: string,
37
+ ): string | undefined {
38
+ const ref = resolveRelationshipReference(
39
+ holder as unknown as MetaObject, relationshipName, targetName, sourceRefField,
40
+ );
41
+ return ref?.fields[0];
51
42
  }
52
43
 
53
44
  /**
@@ -77,7 +68,9 @@ export function resolveRelationDescriptor(
77
68
  { entity: sourceEntity.name },
78
69
  );
79
70
  }
80
- const fkField = findReferenceFkField(sourceEntity, targetEntityName);
71
+ // ADR-0039: resolving @sourceRefField may be inherited via extends.
72
+ const declaredRefField = child.attr(RELATIONSHIP_ATTR_SOURCE_REF_FIELD) as string | undefined;
73
+ const fkField = findReferenceFkField(sourceEntity, targetEntityName, child.name, declaredRefField);
81
74
  if (!fkField) {
82
75
  throw new MetadataError(
83
76
  `Relationship '${relationName}' on '${sourceEntity.name}' has no identity.reference targeting '${targetEntityName}'`,
@@ -114,7 +107,11 @@ export function resolveRelationDescriptor(
114
107
  if (targetEntityName !== sourceEntity.name) continue;
115
108
  const inverseName = inversePluralName(other.name);
116
109
  if (inverseName !== relationName) continue;
117
- const fkField = findReferenceFkField(other, sourceEntity.name);
110
+ // ADR-0039: resolving @sourceRefField may be inherited via extends. This
111
+ // FK lives on `other` and belongs to `other`'s own relationship `child` —
112
+ // not to anything declared on sourceEntity (see #368 module comment).
113
+ const declaredRefField = child.attr(RELATIONSHIP_ATTR_SOURCE_REF_FIELD) as string | undefined;
114
+ const fkField = findReferenceFkField(other, sourceEntity.name, child.name, declaredRefField);
118
115
  if (!fkField) {
119
116
  throw new MetadataError(
120
117
  `Inverse relationship for '${relationName}' on '${sourceEntity.name}': entity '${other.name}' has no identity.reference targeting '${sourceEntity.name}'`,