@cap-js/change-tracking 1.1.4 → 2.0.0-beta.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/CHANGELOG.md +29 -1
- package/README.md +45 -71
- package/_i18n/i18n.properties +12 -20
- package/_i18n/i18n_ar.properties +3 -3
- package/_i18n/i18n_bg.properties +3 -3
- package/_i18n/i18n_cs.properties +3 -3
- package/_i18n/i18n_da.properties +3 -3
- package/_i18n/i18n_de.properties +3 -3
- package/_i18n/i18n_el.properties +3 -3
- package/_i18n/i18n_en.properties +3 -3
- package/_i18n/i18n_en_US_saptrc.properties +3 -32
- package/_i18n/i18n_es.properties +3 -3
- package/_i18n/i18n_es_MX.properties +3 -3
- package/_i18n/i18n_fi.properties +3 -3
- package/_i18n/i18n_fr.properties +3 -3
- package/_i18n/i18n_he.properties +3 -3
- package/_i18n/i18n_hr.properties +3 -3
- package/_i18n/i18n_hu.properties +3 -3
- package/_i18n/i18n_it.properties +3 -3
- package/_i18n/i18n_ja.properties +3 -3
- package/_i18n/i18n_kk.properties +3 -3
- package/_i18n/i18n_ko.properties +3 -3
- package/_i18n/i18n_ms.properties +3 -3
- package/_i18n/i18n_nl.properties +3 -3
- package/_i18n/i18n_no.properties +3 -3
- package/_i18n/i18n_pl.properties +3 -3
- package/_i18n/i18n_pt.properties +3 -3
- package/_i18n/i18n_ro.properties +3 -3
- package/_i18n/i18n_ru.properties +3 -3
- package/_i18n/i18n_sh.properties +3 -3
- package/_i18n/i18n_sk.properties +3 -3
- package/_i18n/i18n_sl.properties +3 -3
- package/_i18n/i18n_sv.properties +3 -3
- package/_i18n/i18n_th.properties +3 -3
- package/_i18n/i18n_tr.properties +3 -3
- package/_i18n/i18n_uk.properties +3 -3
- package/_i18n/i18n_vi.properties +3 -3
- package/_i18n/i18n_zh_CN.properties +3 -3
- package/_i18n/i18n_zh_TW.properties +3 -3
- package/cds-plugin.js +15 -264
- package/index.cds +199 -75
- package/lib/TriggerCQN2SQL.js +42 -0
- package/lib/h2/java-codegen.js +843 -0
- package/lib/h2/register.js +27 -0
- package/lib/h2/triggers.js +42 -0
- package/lib/hana/composition.js +250 -0
- package/lib/hana/register.js +28 -0
- package/lib/hana/sql-expressions.js +224 -0
- package/lib/hana/triggers.js +254 -0
- package/lib/localization.js +53 -117
- package/lib/model-enhancer.js +266 -0
- package/lib/postgres/composition.js +191 -0
- package/lib/postgres/register.js +44 -0
- package/lib/postgres/sql-expressions.js +271 -0
- package/lib/postgres/triggers.js +115 -0
- package/lib/skipHandlers.js +34 -0
- package/lib/sqlite/composition.js +235 -0
- package/lib/sqlite/register.js +28 -0
- package/lib/sqlite/sql-expressions.js +238 -0
- package/lib/sqlite/triggers.js +164 -0
- package/lib/utils/change-tracking.js +394 -0
- package/lib/utils/composition-helpers.js +67 -0
- package/lib/utils/entity-collector.js +297 -0
- package/lib/utils/session-variables.js +278 -0
- package/lib/utils/trigger-utils.js +94 -0
- package/package.json +17 -7
- package/lib/change-log.js +0 -538
- package/lib/entity-helper.js +0 -217
- package/lib/format-options.js +0 -66
- package/lib/template-processor.js +0 -115
package/_i18n/i18n_ms.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=Entiti Perkhidmatan
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=Cipta
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=Kemas kini
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=Padam
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=Diubah pada
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_nl.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=Service-entiteit
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=Cre\u00EBren
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=Actualiseren
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=Verwijderen
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=Gewijzigd om
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_no.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=Tjenesteentitet
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=Opprett
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=Oppdater
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=Slett
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=Endret kl.
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_pl.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=Encja us\u0142ugi
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=Utw\u00F3rz
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=Aktualizuj
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=Usu\u0144
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=Zmieniono o
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_pt.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=Entidade de servi\u00E7o
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=Criar
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=Atualizar
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=Excluir
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=Modificado em
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_ro.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=Entitate serviciu
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=Creare
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=Actualizare
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=\u0218tergere
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=Modificat la
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_ru.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=\u0421\u0443\u0449\u043D\u043E\u0441\u0442\u044C \u0441\
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=\u0421\u043E\u0437\u0434\u0430\u0442\u044C
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=\u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=\u0423\u0434\u0430\u043B\u0438\u0442\u044C
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=\u0412\u0440\u0435\u043C\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_sh.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=Entitet usluga
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=Kreiraj
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=A\u017Euriraj
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=Izbri\u0161i
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=Promenjeno
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_sk.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=Servisn\u00E1 entita
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=Vytvori\u0165
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=Aktualiz\u00E1cia
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=Odstr\u00E1ni\u0165
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=Zmenen\u00E9 o
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_sl.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=Entiteta storitve
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=Ustvari
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=Posodobi
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=Izbri\u0161i
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=Spremenjeno ob
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_sv.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=Tj\u00E4nstentitet
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=Skapa
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=Uppdatera
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=Radera
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=\u00C4ndring kl.
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_th.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=\u0E40\u0E2D\u0E19\u0E17\u0E34\u0E15\u0E35\u0E49\u0E01\u
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=\u0E2A\u0E23\u0E49\u0E32\u0E07
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=\u0E2D\u0E31\u0E1E\u0E40\u0E14\u0E17
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=\u0E25\u0E1A
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E40\u0E21\u0E37\u0E48\u0E2D
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_tr.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=Servis birimi
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=Olu\u015Ftur
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=G\u00FCncelle
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=Sil
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=De\u011Fi\u015Fiklik saati
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_uk.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=\u0421\u0443\u0442\u043D\u0456\u0441\u0442\u044C \u0441\
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=\u041E\u043D\u043E\u0432\u0438\u0442\u0438
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=\u0427\u0430\u0441 \u0437\u043C\u0456\u043D\u0438
|
|
50
50
|
#XFLD: Field label
|
package/_i18n/i18n_vi.properties
CHANGED
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=Th\u1EF1c th\u1EC3 d\u1ECBch v\u1EE5
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=Ta\u0323o
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=C\u00E2\u0323p nh\u00E2\u0323t
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=Xo\u0301a
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=Thay \u0111\u00F4\u0309i lu\u0301c
|
|
50
50
|
#XFLD: Field label
|
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=\u670D\u52A1\u5B9E\u4F53
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=\u521B\u5EFA
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=\u66F4\u65B0
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=\u5220\u9664
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=\u66F4\u6539\u65F6\u95F4
|
|
50
50
|
#XFLD: Field label
|
|
@@ -40,11 +40,11 @@ ChangeLog.serviceEntity=\u670D\u52D9\u5BE6\u9AD4
|
|
|
40
40
|
## Change Log Modifications##
|
|
41
41
|
########################################
|
|
42
42
|
#XFLD: Field label
|
|
43
|
-
|
|
43
|
+
Changes.modification.create=\u5EFA\u7ACB
|
|
44
44
|
#XFLD: Field label
|
|
45
|
-
|
|
45
|
+
Changes.modification.update=\u66F4\u65B0
|
|
46
46
|
#XFLD: Field label
|
|
47
|
-
|
|
47
|
+
Changes.modification.delete=\u522A\u9664
|
|
48
48
|
#XFLD: Field label
|
|
49
49
|
ChangeLog.createdAt=\u66F4\u6539\u6642\u9593
|
|
50
50
|
#XFLD: Field label
|
package/cds-plugin.js
CHANGED
|
@@ -1,266 +1,17 @@
|
|
|
1
1
|
const cds = require('@sap/cds');
|
|
2
|
-
const DEBUG = cds.debug('changelog');
|
|
3
2
|
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
for (const se of Object.values(actions)) {
|
|
21
|
-
const target = flag ? 'TargetProperties' : 'TargetEntities';
|
|
22
|
-
const sideEffectAttr = se[`@Common.SideEffects.${target}`];
|
|
23
|
-
const property = flag ? 'changes' : { '=': `${element}.changes` };
|
|
24
|
-
if (sideEffectAttr?.length >= 0) {
|
|
25
|
-
sideEffectAttr.findIndex((item) => (item['='] ? item['='] : item) === (property['='] ? property['='] : property)) === -1 && sideEffectAttr.push(property);
|
|
26
|
-
} else {
|
|
27
|
-
se[`@Common.SideEffects.${target}`] = [property];
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
function setChangeTrackingIsRootEntity(entity, csn, val = true) {
|
|
33
|
-
if (csn.definitions?.[entity.name]) {
|
|
34
|
-
csn.definitions[entity.name][isRoot] = val;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function checkAndSetRootEntity(parentEntity, entity, csn) {
|
|
39
|
-
if (entity[isRoot] === false) {
|
|
40
|
-
return entity;
|
|
41
|
-
}
|
|
42
|
-
if (parentEntity) {
|
|
43
|
-
return compositionRoot(parentEntity, csn);
|
|
44
|
-
} else {
|
|
45
|
-
setChangeTrackingIsRootEntity(entity, csn);
|
|
46
|
-
return { ...csn.definitions?.[entity.name], name: entity.name };
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function processEntities(m) {
|
|
51
|
-
for (let name in m.definitions) {
|
|
52
|
-
compositionRoot({ ...m.definitions[name], name }, m);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function compositionRoot(entity, csn) {
|
|
57
|
-
if (!entity || entity.kind !== 'entity') {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
const parentEntity = compositionParent(entity, csn);
|
|
61
|
-
return checkAndSetRootEntity(parentEntity, entity, csn);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function compositionParent(entity, csn) {
|
|
65
|
-
if (!entity || entity.kind !== 'entity') {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
const parentAssociation = compositionParentAssociation(entity, csn);
|
|
69
|
-
return parentAssociation ?? null;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function compositionParentAssociation(entity, csn) {
|
|
73
|
-
if (!entity || entity.kind !== 'entity') {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
const elements = entity.elements ?? {};
|
|
77
|
-
|
|
78
|
-
// Add the change-tracking-isRootEntity attribute of the child entity
|
|
79
|
-
processCompositionElements(entity, csn, elements);
|
|
80
|
-
|
|
81
|
-
const hasChildFlag = entity[isRoot] !== false;
|
|
82
|
-
const hasParentEntity = entity[hasParent];
|
|
83
|
-
|
|
84
|
-
if (hasChildFlag || !hasParentEntity) {
|
|
85
|
-
// Find parent association of the entity
|
|
86
|
-
const parentAssociation = findParentAssociation(entity, csn, elements);
|
|
87
|
-
if (parentAssociation) {
|
|
88
|
-
const parentAssociationTarget = elements[parentAssociation]?.target;
|
|
89
|
-
if (hasChildFlag) setChangeTrackingIsRootEntity(entity, csn, false);
|
|
90
|
-
return {
|
|
91
|
-
...csn.definitions?.[parentAssociationTarget],
|
|
92
|
-
name: parentAssociationTarget
|
|
93
|
-
};
|
|
94
|
-
} else return;
|
|
95
|
-
}
|
|
96
|
-
return { ...csn.definitions?.[entity.name], name: entity.name };
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function processCompositionElements(entity, csn, elements) {
|
|
100
|
-
for (const name in elements) {
|
|
101
|
-
const element = elements[name];
|
|
102
|
-
const target = element?.target;
|
|
103
|
-
const definition = csn.definitions?.[target];
|
|
104
|
-
if (element.type !== 'cds.Composition' || target === entity.name || !definition || definition[isRoot] === false) {
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
setChangeTrackingIsRootEntity({ ...definition, name: target }, csn, false);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function findParentAssociation(entity, csn, elements) {
|
|
112
|
-
return Object.keys(elements).find((name) => {
|
|
113
|
-
const element = elements[name];
|
|
114
|
-
const target = element?.target;
|
|
115
|
-
if (element.type === 'cds.Association' && target !== entity.name) {
|
|
116
|
-
const parentDefinition = csn.definitions?.[target] ?? {};
|
|
117
|
-
const parentElements = parentDefinition?.elements ?? {};
|
|
118
|
-
return !!Object.keys(parentElements).find((parentEntityName) => {
|
|
119
|
-
const parentElement = parentElements?.[parentEntityName] ?? {};
|
|
120
|
-
if (parentElement.type === 'cds.Composition') {
|
|
121
|
-
const isCompositionEntity = parentElement.target === entity.name;
|
|
122
|
-
// add parent information in the current entity
|
|
123
|
-
if (isCompositionEntity) {
|
|
124
|
-
csn.definitions[entity.name][hasParent] = {
|
|
125
|
-
associationName: name,
|
|
126
|
-
entityName: target
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
return isCompositionEntity;
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Returns an expression for the key of the given entity, which we can use as the right-hand-side of an ON condition.
|
|
138
|
-
*/
|
|
139
|
-
function entityKey4(entity) {
|
|
140
|
-
const xpr = [];
|
|
141
|
-
for (let k in entity.elements) {
|
|
142
|
-
const e = entity.elements[k];
|
|
143
|
-
if (!e.key) continue;
|
|
144
|
-
if (xpr.length) xpr.push('||');
|
|
145
|
-
if (e.type === 'cds.Association') xpr.push({ ref: [k, e.keys?.[0]?.ref?.[0]] });
|
|
146
|
-
else xpr.push({ ref: [k] });
|
|
147
|
-
}
|
|
148
|
-
return xpr;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Unfold @changelog annotations in loaded model
|
|
152
|
-
function enhanceModel(m) {
|
|
153
|
-
if (m.meta?.flavor !== 'inferred') {
|
|
154
|
-
// In MTX scenarios with extensibility the runtime model for deployed apps is not
|
|
155
|
-
// inferred but xtended and the logic requires inferred.
|
|
156
|
-
DEBUG?.(`Skipping model enhancement because model flavour is '${m.meta?.flavor}' and not 'inferred'`);
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
const _enhanced = 'sap.changelog.enhanced';
|
|
160
|
-
if (m.meta?.[_enhanced]) return; // already enhanced
|
|
161
|
-
|
|
162
|
-
// Get definitions from Dummy entity in our models
|
|
163
|
-
const { 'sap.changelog.aspect': aspect } = m.definitions;
|
|
164
|
-
if (!aspect) return; // some other model
|
|
165
|
-
const {
|
|
166
|
-
'@UI.Facets': [facet],
|
|
167
|
-
elements: { changes }
|
|
168
|
-
} = aspect;
|
|
169
|
-
if (changes.on.length > 2) changes.on.pop(); // remove ID -> filled in below
|
|
170
|
-
|
|
171
|
-
processEntities(m); // REVISIT: why is that required ?!?
|
|
172
|
-
|
|
173
|
-
for (let name in m.definitions) {
|
|
174
|
-
const entity = m.definitions[name];
|
|
175
|
-
if (entity.kind === 'entity' && !entity['@cds.autoexposed'] && isChangeTracked(entity)) {
|
|
176
|
-
if (!entity['@changelog.disable_assoc']) {
|
|
177
|
-
// Add association to ChangeView...
|
|
178
|
-
const keys = entityKey4(entity);
|
|
179
|
-
if (!keys.length) continue; // If no key attribute is defined for the entity, the logic to add association to ChangeView should be skipped.
|
|
180
|
-
const assoc = new cds.builtin.classes.Association({ ...changes, on: [...changes.on, ...keys] });
|
|
181
|
-
|
|
182
|
-
// --------------------------------------------------------------------
|
|
183
|
-
// PARKED: Add auto-exposed projection on ChangeView to service if applicable
|
|
184
|
-
// const namespace = name.match(/^(.*)\.[^.]+$/)[1]
|
|
185
|
-
// const service = m.definitions[namespace]
|
|
186
|
-
// if (service) {
|
|
187
|
-
// const projection = {from:{ref:[assoc.target]}}
|
|
188
|
-
// m.definitions[assoc.target = namespace + '.' + Changes] = {
|
|
189
|
-
// '@cds.autoexposed':true, kind:'entity', projection
|
|
190
|
-
// }
|
|
191
|
-
// DEBUG?.(`\n
|
|
192
|
-
// extend service ${namespace} with {
|
|
193
|
-
// entity ${Changes} as projection on ${projection.from.ref[0]};
|
|
194
|
-
// }
|
|
195
|
-
// `.replace(/ {10}/g,''))
|
|
196
|
-
// }
|
|
197
|
-
// --------------------------------------------------------------------
|
|
198
|
-
|
|
199
|
-
DEBUG?.(
|
|
200
|
-
`\n
|
|
201
|
-
extend ${name} with {
|
|
202
|
-
changes : Association to many ${assoc.target} on ${assoc.on.map((x) => x.ref?.join('.') || x).join(' ')};
|
|
203
|
-
}
|
|
204
|
-
`.replace(/ {8}/g, '')
|
|
205
|
-
);
|
|
206
|
-
const query = entity.projection || entity.query?.SELECT;
|
|
207
|
-
if (query) (query.columns ??= ['*']).push({ as: 'changes', cast: assoc });
|
|
208
|
-
else if (entity.elements) entity.elements.changes = assoc;
|
|
209
|
-
|
|
210
|
-
// Add UI.Facet for Change History List
|
|
211
|
-
if (!entity['@changelog.disable_facet']) entity['@UI.Facets']?.push(facet);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
if (entity.actions) {
|
|
215
|
-
const hasParentInfo = entity[hasParent];
|
|
216
|
-
const entityName = hasParentInfo?.entityName;
|
|
217
|
-
const parentEntity = entityName ? m.definitions[entityName] : null;
|
|
218
|
-
const isParentRootAndHasFacets = parentEntity?.[isRoot] && parentEntity?.['@UI.Facets'];
|
|
219
|
-
if (entity[isRoot] && entity['@UI.Facets']) {
|
|
220
|
-
// Add side effects for root entity
|
|
221
|
-
addSideEffects(entity.actions, true);
|
|
222
|
-
} else if (isParentRootAndHasFacets) {
|
|
223
|
-
// Add side effects for child entity
|
|
224
|
-
addSideEffects(entity.actions, false, hasParentInfo?.associationName);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
(m.meta ??= {})[_enhanced] = true;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Add generic change tracking handlers
|
|
233
|
-
function addGenericHandlers() {
|
|
234
|
-
const { track_changes, _afterReadChangeView } = require('./lib/change-log');
|
|
235
|
-
for (const srv of cds.services) {
|
|
236
|
-
if (srv instanceof cds.ApplicationService) {
|
|
237
|
-
let any = false;
|
|
238
|
-
for (const entity of Object.values(srv.entities)) {
|
|
239
|
-
if (isChangeTracked(entity)) {
|
|
240
|
-
cds.db.before('CREATE', entity, track_changes);
|
|
241
|
-
cds.db.before('UPDATE', entity, track_changes);
|
|
242
|
-
cds.db.before('DELETE', entity, track_changes);
|
|
243
|
-
any = true;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
if (any && srv.entities.ChangeView) {
|
|
247
|
-
srv.after('READ', srv.entities.ChangeView, _afterReadChangeView);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Register plugin hooks
|
|
254
|
-
cds.on('compile.for.runtime', (csn) => {
|
|
255
|
-
DEBUG?.('on', 'compile.for.runtime');
|
|
256
|
-
enhanceModel(csn);
|
|
257
|
-
});
|
|
258
|
-
cds.on('compile.to.edmx', (csn) => {
|
|
259
|
-
DEBUG?.('on', 'compile.to.edmx');
|
|
260
|
-
enhanceModel(csn);
|
|
261
|
-
});
|
|
262
|
-
cds.on('compile.to.dbx', (csn) => {
|
|
263
|
-
DEBUG?.('on', 'compile.to.dbx');
|
|
264
|
-
enhanceModel(csn);
|
|
265
|
-
});
|
|
266
|
-
cds.on('served', addGenericHandlers);
|
|
3
|
+
const { enhanceModel } = require('./lib/model-enhancer.js');
|
|
4
|
+
const { registerSessionVariableHandlers } = require('./lib/skipHandlers.js');
|
|
5
|
+
const { deploySQLiteTriggers } = require('./lib/sqlite/register.js');
|
|
6
|
+
const { registerPostgresCompilerHook, deployPostgresLabels } = require('./lib/postgres/register.js');
|
|
7
|
+
const { registerH2CompilerHook } = require('./lib/h2/register.js');
|
|
8
|
+
const { registerHDICompilerHook } = require('./lib/hana/register.js');
|
|
9
|
+
|
|
10
|
+
cds.on('loaded', enhanceModel);
|
|
11
|
+
cds.on('listening', registerSessionVariableHandlers);
|
|
12
|
+
cds.once('served', deploySQLiteTriggers);
|
|
13
|
+
cds.once('served', deployPostgresLabels);
|
|
14
|
+
|
|
15
|
+
registerH2CompilerHook();
|
|
16
|
+
registerPostgresCompilerHook();
|
|
17
|
+
registerHDICompilerHook();
|