@cap-js/change-tracking 2.0.0-beta.4 → 2.0.0-beta.6

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.
@@ -166,6 +166,12 @@ function extractTrackedColumns(entity, model = cds.context?.model ?? cds.model,
166
166
  const entry = { name: name, type: col.type };
167
167
 
168
168
  if (isAssociation) {
169
+ // Check if association target has a table
170
+ const targetEntity = model.definitions[col.target];
171
+ if (!targetEntity || targetEntity['@cds.persistence.skip'] === true) {
172
+ LOG.warn(`Skipped @changelog for ${name} on entity ${entity.name}: Association target "${col.target}" is annotated with @cds.persistence.skip!`);
173
+ continue;
174
+ }
169
175
  entry.target = col.target;
170
176
  // Use the resolved changelog annotation (which could be from override)
171
177
  if (Array.isArray(changelogAnnotation) && changelogAnnotation.length > 0) {
@@ -173,7 +179,9 @@ function extractTrackedColumns(entity, model = cds.context?.model ?? cds.model,
173
179
  const changelogPaths = changelogAnnotation.map((c) => c['=']);
174
180
  for (const path of changelogPaths) {
175
181
  const p = validateChangelogPath(entity, path, model);
176
- if (p) alt.push(p);
182
+ if (!p) continue;
183
+ if (p.includes('.')) alt.push({ path: p, source: 'assoc' });
184
+ else alt.push({ path: p, source: 'local' });
177
185
  }
178
186
  if (alt.length > 0) entry.alt = alt;
179
187
  }
@@ -352,6 +360,7 @@ function getCompositionParentBinding(targetEntity, rootEntity) {
352
360
  }
353
361
 
354
362
  function getLocalizedLookupInfo(targetEntityName, altFields, model = cds.context?.model ?? cds.model) {
363
+ if (!altFields || altFields.length === 0) return null;
355
364
  const targetEntity = model.definitions[targetEntityName];
356
365
  if (!targetEntity) return null;
357
366
 
@@ -227,6 +227,25 @@ function getBaseEntity(entity, model) {
227
227
  }
228
228
  }
229
229
 
230
+ function getBaseElement(element, entity, model) {
231
+ const cqn = entity.projection ?? entity.query?.SELECT;
232
+ if (!cqn) return null;
233
+ element = cqn.columns?.find((c) => c.as === element && c.ref)?.ref?.[0] ?? element;
234
+
235
+ const baseRef = cqn.from?.ref?.[0];
236
+ if (!baseRef || !model) return null;
237
+
238
+ const baseEntity = model.definitions[baseRef];
239
+ if (!baseEntity) return null;
240
+ const baseCQN = baseEntity.projection ?? baseEntity.query?.SELECT ?? baseEntity.query?.SET;
241
+ // If base entity is also a projection, recurse
242
+ if (baseCQN) {
243
+ return getBaseElement(element, baseEntity, model);
244
+ } else {
245
+ return { baseRef, baseElement: element };
246
+ }
247
+ }
248
+
230
249
  // Analyze composition hierarchy in CSN
231
250
  function analyzeCompositions(csn) {
232
251
  // First pass: build child -> { parent, compositionField } map
@@ -318,5 +337,6 @@ module.exports = {
318
337
  getBaseEntity,
319
338
  analyzeCompositions,
320
339
  getService,
321
- collectEntities
340
+ collectEntities,
341
+ getBaseElement
322
342
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cap-js/change-tracking",
3
- "version": "2.0.0-beta.4",
3
+ "version": "2.0.0-beta.6",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "tag": "beta"
@@ -45,7 +45,8 @@
45
45
  "change-tracking": {
46
46
  "model": "@cap-js/change-tracking",
47
47
  "maxDisplayHierarchyDepth": 3,
48
- "preserveDeletes": false
48
+ "preserveDeletes": false,
49
+ "procedureForRestoringBacklinks": true
49
50
  }
50
51
  }
51
52
  },