@cap-js-community/common 0.1.6 → 0.2.0
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cap-js-community/common",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "CAP Node.js Community Common",
|
|
5
5
|
"homepage": "https://cap.cloud.sap/",
|
|
6
6
|
"engines": {
|
|
@@ -44,26 +44,26 @@
|
|
|
44
44
|
"audit": "npm audit --only=prod"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@cap-js/sqlite": "^
|
|
48
|
-
"commander": "^
|
|
49
|
-
"redis": "^4.7.
|
|
47
|
+
"@cap-js/sqlite": "^2.0.1",
|
|
48
|
+
"commander": "^14.0.0",
|
|
49
|
+
"redis": "^4.7.1",
|
|
50
50
|
"verror": "^1.10.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@cap-js-community/common": "./",
|
|
54
54
|
"@cap-js/cds-test": "^0.3.0",
|
|
55
|
-
"@sap/cds": "^
|
|
56
|
-
"@sap/cds-common-content": "^
|
|
57
|
-
"@sap/cds-dk": "^
|
|
58
|
-
"eslint": "9.
|
|
59
|
-
"eslint-config-prettier": "10.1.
|
|
60
|
-
"eslint-plugin-jest": "28.
|
|
61
|
-
"eslint-plugin-n": "^17.
|
|
55
|
+
"@sap/cds": "^9.0.2",
|
|
56
|
+
"@sap/cds-common-content": "^3.0.1",
|
|
57
|
+
"@sap/cds-dk": "^9.0.4",
|
|
58
|
+
"eslint": "9.28.0",
|
|
59
|
+
"eslint-config-prettier": "10.1.5",
|
|
60
|
+
"eslint-plugin-jest": "28.12.0",
|
|
61
|
+
"eslint-plugin-n": "^17.19.0",
|
|
62
62
|
"jest": "29.7.0",
|
|
63
63
|
"jest-html-reporters": "3.1.7",
|
|
64
64
|
"jest-junit": "16.0.0",
|
|
65
65
|
"prettier": "3.5.3",
|
|
66
|
-
"shelljs": "^0.
|
|
66
|
+
"shelljs": "^0.10.0"
|
|
67
67
|
},
|
|
68
68
|
"cds": {
|
|
69
69
|
"requires": {
|
|
@@ -8,7 +8,7 @@ const crypto = require("crypto");
|
|
|
8
8
|
const COMPONENT_NAME = "migrationCheck";
|
|
9
9
|
const STRING_DEFAULT_LENGTH = 5000;
|
|
10
10
|
|
|
11
|
-
const Checks = [releasedEntityCheck, newEntityCheck, uniqueIndexCheck];
|
|
11
|
+
const Checks = [releasedEntityCheck, newEntityCheck, uniqueIndexCheck, journalModeCheck];
|
|
12
12
|
const Messages = {
|
|
13
13
|
ReleasedEntityCannotBeRemoved: "A released entity cannot be removed",
|
|
14
14
|
ReleasedEntityDraftEnablementCannotBeChanged: "The draft enablement state of a released entity cannot be changed",
|
|
@@ -25,6 +25,8 @@ const Messages = {
|
|
|
25
25
|
ReleasedElementCardinalityCannotBeChanged: "The cardinality of a released element cannot be changed",
|
|
26
26
|
ReleasedElementOnConditionCannotBeChanged: "The ON condition of a released element cannot be changed",
|
|
27
27
|
ReleasedElementKeysConditionCannotBeChanged: "The keys condition of a released element cannot be changed",
|
|
28
|
+
ReleasedEntityJournalModeAndEntityChangeIsNotAllowed:
|
|
29
|
+
"Enabling journal mode and changing entity in same cycle is not allowed",
|
|
28
30
|
ReleasedEntityIndexChangeIsNotAllowed: "Changes to the index of a released entity are not allowed",
|
|
29
31
|
ReleasedEntityIndexChangeIsNotWhitelisted: "Changes to the index of a released entity must be whitelisted",
|
|
30
32
|
ReleasedElementTypeExtensionIsNotWhitelisted: "Extending the type of a released element requires whitelisting",
|
|
@@ -310,200 +312,255 @@ class MigrationCheck {
|
|
|
310
312
|
|
|
311
313
|
function releasedEntityCheck(csnBuild, csnProd, whitelist, options) {
|
|
312
314
|
const messages = [];
|
|
313
|
-
visitPersistenceEntities(
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
report(messages, MessagesCodes.ReleasedEntityDraftEnablementCannotBeChanged, definitionProd.name);
|
|
325
|
-
}
|
|
326
|
-
const definitionWhitelist = whitelist.definitions && whitelist.definitions[definitionProd.name];
|
|
327
|
-
Object.keys(definitionProd.elements || {}).forEach((elementProdName) => {
|
|
328
|
-
const elementProd = definitionProd.elements[elementProdName];
|
|
329
|
-
const elementBuild = definitionBuild.elements[elementProdName];
|
|
330
|
-
const elementWhitelist =
|
|
331
|
-
definitionWhitelist && definitionWhitelist.elements && definitionWhitelist.elements[elementProdName];
|
|
332
|
-
if (elementBuild) {
|
|
333
|
-
if (["cds.Association", "cds.Composition"].includes(elementProd.type)) {
|
|
334
|
-
if (!((elementProd.on && elementBuild.on) || (elementProd.keys && elementBuild.keys))) {
|
|
335
|
-
report(
|
|
336
|
-
messages,
|
|
337
|
-
MessagesCodes.ReleasedElementManagedUnmanagedCannotBeChanged,
|
|
338
|
-
definitionProd.name,
|
|
339
|
-
elementProdName,
|
|
340
|
-
);
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
}
|
|
315
|
+
visitPersistenceEntities(
|
|
316
|
+
csnProd,
|
|
317
|
+
(definitionProd) => {
|
|
318
|
+
let lookupName = definitionProd.name;
|
|
319
|
+
if (lookupName.startsWith("cds.xt.") && !options.checkMtx) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const definitionBuild = csnBuild.definitions[lookupName];
|
|
323
|
+
if (!definitionBuild) {
|
|
324
|
+
report(messages, MessagesCodes.ReleasedEntityCannotBeRemoved, definitionProd.name);
|
|
325
|
+
return;
|
|
344
326
|
}
|
|
345
|
-
if (
|
|
346
|
-
|
|
327
|
+
if (definitionProd["@odata.draft.enabled"] !== definitionBuild["@odata.draft.enabled"]) {
|
|
328
|
+
report(messages, MessagesCodes.ReleasedEntityDraftEnablementCannotBeChanged, definitionProd.name);
|
|
347
329
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
330
|
+
const definitionWhitelist = whitelist.definitions && whitelist.definitions[definitionProd.name];
|
|
331
|
+
Object.keys(definitionProd.elements || {}).forEach((elementProdName) => {
|
|
332
|
+
const elementProd = definitionProd.elements[elementProdName];
|
|
333
|
+
const elementBuild = definitionBuild.elements[elementProdName];
|
|
334
|
+
const elementWhitelist =
|
|
335
|
+
definitionWhitelist && definitionWhitelist.elements && definitionWhitelist.elements[elementProdName];
|
|
336
|
+
if (elementBuild) {
|
|
337
|
+
if (["cds.Association", "cds.Composition"].includes(elementProd.type)) {
|
|
338
|
+
if (!((elementProd.on && elementBuild.on) || (elementProd.keys && elementBuild.keys))) {
|
|
339
|
+
report(
|
|
340
|
+
messages,
|
|
341
|
+
MessagesCodes.ReleasedElementManagedUnmanagedCannotBeChanged,
|
|
342
|
+
definitionProd.name,
|
|
343
|
+
elementProdName,
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
351
347
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
} else if (elementProd.virtual !== elementBuild.virtual) {
|
|
355
|
-
report(messages, MessagesCodes.ReleasedElementVirtualCannotBeChanged, definitionProd.name, elementProdName);
|
|
356
|
-
} else if (elementProd.localized && !elementBuild.localized) {
|
|
357
|
-
report(
|
|
358
|
-
messages,
|
|
359
|
-
MessagesCodes.ReleasedElementLocalizationCannotBeChanged,
|
|
360
|
-
definitionProd.name,
|
|
361
|
-
elementProdName,
|
|
362
|
-
);
|
|
363
|
-
} else if (!elementProd.notNull && elementBuild.notNull) {
|
|
364
|
-
report(messages, MessagesCodes.ReleasedElementNullableCannotBeChanged, definitionProd.name, elementProdName);
|
|
365
|
-
} else if (normalizeType(csnProd, elementProd.type) !== normalizeType(csnBuild, elementBuild.type)) {
|
|
366
|
-
report(messages, MessagesCodes.ReleasedElementTypeCannotBeChanged, definitionProd.name, elementProdName);
|
|
367
|
-
} else if ((elementProd.length || STRING_DEFAULT_LENGTH) > (elementBuild.length || STRING_DEFAULT_LENGTH)) {
|
|
368
|
-
report(messages, MessagesCodes.ReleasedElementTypeCannotBeShortened, definitionProd.name, elementProdName);
|
|
369
|
-
} else if ((elementProd.length || STRING_DEFAULT_LENGTH) < (elementBuild.length || STRING_DEFAULT_LENGTH)) {
|
|
370
|
-
if (!elementWhitelist && options.whitelist) {
|
|
371
|
-
report(
|
|
372
|
-
messages,
|
|
373
|
-
MessagesCodes.ReleasedElementTypeExtensionIsNotWhitelisted,
|
|
374
|
-
definitionProd.name,
|
|
375
|
-
elementProdName,
|
|
376
|
-
);
|
|
348
|
+
if (elementProd.on) {
|
|
349
|
+
return; // Skip unmanaged association / composition
|
|
377
350
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
elementProdName
|
|
384
|
-
)
|
|
385
|
-
|
|
386
|
-
if (
|
|
351
|
+
if (!elementBuild) {
|
|
352
|
+
if (!elementProd.virtual) {
|
|
353
|
+
report(messages, MessagesCodes.ReleasedElementCannotBeRemoved, definitionProd.name, elementProdName);
|
|
354
|
+
}
|
|
355
|
+
} else if (elementProd.key !== elementBuild.key) {
|
|
356
|
+
report(messages, MessagesCodes.ReleasedElementKeyCannotBeChanged, definitionProd.name, elementProdName);
|
|
357
|
+
} else if (elementProd.virtual !== elementBuild.virtual) {
|
|
358
|
+
report(messages, MessagesCodes.ReleasedElementVirtualCannotBeChanged, definitionProd.name, elementProdName);
|
|
359
|
+
} else if (elementProd.localized && !elementBuild.localized) {
|
|
387
360
|
report(
|
|
388
361
|
messages,
|
|
389
|
-
MessagesCodes.
|
|
362
|
+
MessagesCodes.ReleasedElementLocalizationCannotBeChanged,
|
|
390
363
|
definitionProd.name,
|
|
391
364
|
elementProdName,
|
|
392
365
|
);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if (
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
if (isPersistenceEntity(csnProd, elementProd.target) || isPersistenceEntity(csnBuild, elementBuild.target)) {
|
|
366
|
+
} else if (!elementProd.notNull && elementBuild.notNull) {
|
|
367
|
+
report(messages, MessagesCodes.ReleasedElementNullableCannotBeChanged, definitionProd.name, elementProdName);
|
|
368
|
+
} else if (normalizeType(csnProd, elementProd.type) !== normalizeType(csnBuild, elementBuild.type)) {
|
|
369
|
+
report(messages, MessagesCodes.ReleasedElementTypeCannotBeChanged, definitionProd.name, elementProdName);
|
|
370
|
+
} else if ((elementProd.length || STRING_DEFAULT_LENGTH) > (elementBuild.length || STRING_DEFAULT_LENGTH)) {
|
|
371
|
+
report(messages, MessagesCodes.ReleasedElementTypeCannotBeShortened, definitionProd.name, elementProdName);
|
|
372
|
+
} else if ((elementProd.length || STRING_DEFAULT_LENGTH) < (elementBuild.length || STRING_DEFAULT_LENGTH)) {
|
|
373
|
+
if (!elementWhitelist && options.whitelist) {
|
|
374
|
+
report(
|
|
375
|
+
messages,
|
|
376
|
+
MessagesCodes.ReleasedElementTypeExtensionIsNotWhitelisted,
|
|
377
|
+
definitionProd.name,
|
|
378
|
+
elementProdName,
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
} else if (elementProd.scale > elementBuild.scale || elementProd.precision > elementBuild.precision) {
|
|
410
382
|
report(
|
|
411
383
|
messages,
|
|
412
|
-
MessagesCodes.
|
|
384
|
+
MessagesCodes.ReleasedElementScalePrecisionCannotBeLower,
|
|
413
385
|
definitionProd.name,
|
|
414
386
|
elementProdName,
|
|
415
387
|
);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
|
|
388
|
+
} else if (elementProd.scale < elementBuild.scale || elementProd.precision < elementBuild.precision) {
|
|
389
|
+
if (!elementWhitelist && options.whitelist) {
|
|
390
|
+
report(
|
|
391
|
+
messages,
|
|
392
|
+
MessagesCodes.ReleasedElementScalePrecisionExtensionIsNotWhitelisted,
|
|
393
|
+
definitionProd.name,
|
|
394
|
+
elementProdName,
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
} else if (elementProd.target !== elementBuild.target) {
|
|
398
|
+
if (
|
|
399
|
+
isPersistenceEntity(csnProd, elementProd.target) ||
|
|
400
|
+
isPersistenceEntity(csnBuild, elementBuild.target) ||
|
|
401
|
+
JSON.stringify(entityKeyInfo(csnProd, elementProd.target)) !==
|
|
402
|
+
JSON.stringify(entityKeyInfo(csnBuild, elementBuild.target))
|
|
403
|
+
) {
|
|
404
|
+
report(messages, MessagesCodes.ReleasedElementTargetCannotBeChanged, definitionProd.name, elementProdName);
|
|
405
|
+
}
|
|
406
|
+
} else if (
|
|
407
|
+
(elementProd.cardinality && elementProd.cardinality.max) !==
|
|
408
|
+
(elementBuild.cardinality && elementBuild.cardinality.max)
|
|
409
|
+
) {
|
|
419
410
|
report(
|
|
420
411
|
messages,
|
|
421
|
-
MessagesCodes.
|
|
412
|
+
MessagesCodes.ReleasedElementCardinalityCannotBeChanged,
|
|
422
413
|
definitionProd.name,
|
|
423
414
|
elementProdName,
|
|
424
415
|
);
|
|
416
|
+
} else if (JSON.stringify(elementProd.on) !== JSON.stringify(elementBuild.on)) {
|
|
417
|
+
if (isPersistenceEntity(csnProd, elementProd.target) || isPersistenceEntity(csnBuild, elementBuild.target)) {
|
|
418
|
+
report(
|
|
419
|
+
messages,
|
|
420
|
+
MessagesCodes.ReleasedElementOnConditionCannotBeChanged,
|
|
421
|
+
definitionProd.name,
|
|
422
|
+
elementProdName,
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
} else if (JSON.stringify(elementProd.keys) !== JSON.stringify(elementBuild.keys)) {
|
|
426
|
+
if (isPersistenceEntity(csnProd, elementProd.target) || isPersistenceEntity(csnBuild, elementBuild.target)) {
|
|
427
|
+
report(
|
|
428
|
+
messages,
|
|
429
|
+
MessagesCodes.ReleasedElementKeysConditionCannotBeChanged,
|
|
430
|
+
definitionProd.name,
|
|
431
|
+
elementProdName,
|
|
432
|
+
);
|
|
433
|
+
}
|
|
425
434
|
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
435
|
+
});
|
|
436
|
+
},
|
|
437
|
+
options.filter,
|
|
438
|
+
);
|
|
429
439
|
return messages;
|
|
430
440
|
}
|
|
431
441
|
|
|
432
442
|
function newEntityCheck(csnBuild, csnProd, whitelist, options) {
|
|
433
443
|
const messages = [];
|
|
434
|
-
visitPersistenceEntities(
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
const elementWhitelist =
|
|
450
|
-
definitionWhitelist && definitionWhitelist.elements && definitionWhitelist.elements[elementBuildName];
|
|
451
|
-
if (!elementProd) {
|
|
452
|
-
if (!elementWhitelist && options.whitelist) {
|
|
453
|
-
report(messages, MessagesCodes.NewEntityElementIsNotWhitelisted, definitionBuild.name, elementBuildName);
|
|
444
|
+
visitPersistenceEntities(
|
|
445
|
+
csnBuild,
|
|
446
|
+
(definitionBuild, { draft } = {}) => {
|
|
447
|
+
let lookupName = definitionBuild.name;
|
|
448
|
+
const definitionProd = csnProd.definitions[lookupName];
|
|
449
|
+
const definitionWhitelist = whitelist.definitions && whitelist.definitions[definitionBuild.name];
|
|
450
|
+
if (!definitionProd && !definitionWhitelist && options.whitelist) {
|
|
451
|
+
report(messages, MessagesCodes.NewEntityIsNotWhitelisted, definitionBuild.name);
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
if (definitionProd) {
|
|
455
|
+
Object.keys(definitionBuild.elements || {}).forEach((elementBuildName) => {
|
|
456
|
+
const elementBuild = definitionBuild.elements[elementBuildName];
|
|
457
|
+
if (elementBuild.virtual) {
|
|
458
|
+
return;
|
|
454
459
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
460
|
+
const elementProd = definitionProd.elements[elementBuildName];
|
|
461
|
+
const elementWhitelist =
|
|
462
|
+
definitionWhitelist && definitionWhitelist.elements && definitionWhitelist.elements[elementBuildName];
|
|
463
|
+
if (!elementProd) {
|
|
464
|
+
if (!elementWhitelist && options.whitelist) {
|
|
465
|
+
report(messages, MessagesCodes.NewEntityElementIsNotWhitelisted, definitionBuild.name, elementBuildName);
|
|
466
|
+
}
|
|
467
|
+
if (
|
|
468
|
+
!draft &&
|
|
469
|
+
elementBuild.notNull &&
|
|
470
|
+
(elementBuild.default === undefined || elementBuild.default?.val === null)
|
|
471
|
+
) {
|
|
472
|
+
report(
|
|
473
|
+
messages,
|
|
474
|
+
MessagesCodes.NewEntityElementNotNullableDefault,
|
|
475
|
+
definitionBuild.name,
|
|
476
|
+
elementBuildName,
|
|
477
|
+
);
|
|
478
|
+
}
|
|
461
479
|
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
},
|
|
483
|
+
options.filter,
|
|
484
|
+
);
|
|
466
485
|
return messages;
|
|
467
486
|
}
|
|
468
487
|
|
|
469
488
|
function uniqueIndexCheck(csnBuild, csnProd, whitelist, options) {
|
|
470
489
|
const messages = [];
|
|
471
|
-
visitPersistenceEntities(
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
490
|
+
visitPersistenceEntities(
|
|
491
|
+
csnBuild,
|
|
492
|
+
(definitionBuild) => {
|
|
493
|
+
const definitionWhitelist = whitelist.definitions && whitelist.definitions[definitionBuild.name];
|
|
494
|
+
const definitionProd = csnProd.definitions[definitionBuild.name];
|
|
495
|
+
if (definitionProd) {
|
|
496
|
+
Object.keys(definitionBuild).forEach((key) => {
|
|
497
|
+
if (key.startsWith("@assert.unique.")) {
|
|
498
|
+
const uniqueIndexAnnotationBuild = definitionBuild[key];
|
|
499
|
+
const uniqueIndexAnnotationProd = definitionProd[key];
|
|
500
|
+
if (uniqueIndexAnnotationBuild && !uniqueIndexAnnotationProd && !definitionWhitelist && options.whitelist) {
|
|
501
|
+
report(messages, MessagesCodes.NewEntityIndexIsNotWhitelisted, definitionBuild.name);
|
|
502
|
+
} else if (uniqueIndexAnnotationBuild && uniqueIndexAnnotationProd) {
|
|
503
|
+
const checkProd = uniqueIndexAnnotationProd.every((indexPartProd) => {
|
|
504
|
+
return uniqueIndexAnnotationBuild.find((indexPartBuild) => {
|
|
505
|
+
return (indexPartProd["="] || indexPartProd) === (indexPartBuild["="] || indexPartBuild);
|
|
506
|
+
});
|
|
485
507
|
});
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
508
|
+
if (!checkProd) {
|
|
509
|
+
report(messages, MessagesCodes.ReleasedEntityIndexChangeIsNotAllowed, definitionBuild.name);
|
|
510
|
+
}
|
|
511
|
+
const checkBuild = uniqueIndexAnnotationBuild.every((indexPartBuild) => {
|
|
512
|
+
return uniqueIndexAnnotationProd.find((indexPartProd) => {
|
|
513
|
+
return (indexPartBuild["="] || indexPartBuild) === (indexPartProd["="] || indexPartProd);
|
|
514
|
+
});
|
|
493
515
|
});
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
516
|
+
if (!checkBuild && !definitionWhitelist && options.whitelist) {
|
|
517
|
+
report(messages, MessagesCodes.ReleasedEntityIndexChangeIsNotWhitelisted, definitionBuild.name);
|
|
518
|
+
}
|
|
497
519
|
}
|
|
498
520
|
}
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
options.filter,
|
|
525
|
+
);
|
|
526
|
+
return messages;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function journalModeCheck(csnBuild, csnProd, whitelist, options) {
|
|
530
|
+
const messages = [];
|
|
531
|
+
if (options.check === "journalModeCheck") {
|
|
532
|
+
// Recursion
|
|
533
|
+
return messages;
|
|
534
|
+
}
|
|
535
|
+
visitPersistenceEntities(
|
|
536
|
+
csnBuild,
|
|
537
|
+
(definitionBuild) => {
|
|
538
|
+
const definitionProd = csnProd.definitions[definitionBuild.name];
|
|
539
|
+
if (definitionProd) {
|
|
540
|
+
if (definitionBuild["@cds.persistence.journal"] && !definitionProd["@cds.persistence.journal"]) {
|
|
541
|
+
const entityMessages = Checks.reduce((messages, check) => {
|
|
542
|
+
messages.push(
|
|
543
|
+
...check(
|
|
544
|
+
csnBuild,
|
|
545
|
+
csnProd,
|
|
546
|
+
{},
|
|
547
|
+
{ ...options, filter: [definitionBuild.name], check: "journalModeCheck" },
|
|
548
|
+
),
|
|
549
|
+
);
|
|
550
|
+
return messages;
|
|
551
|
+
}, []);
|
|
552
|
+
if (entityMessages.length > 0) {
|
|
553
|
+
report(messages, MessagesCodes.ReleasedEntityJournalModeAndEntityChangeIsNotAllowed, definitionBuild.name);
|
|
554
|
+
}
|
|
499
555
|
}
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
options.filter,
|
|
559
|
+
);
|
|
503
560
|
return messages;
|
|
504
561
|
}
|
|
505
562
|
|
|
506
|
-
function visitPersistenceEntities(csn, onEntity) {
|
|
563
|
+
function visitPersistenceEntities(csn, onEntity, filter) {
|
|
507
564
|
if (!onEntity) {
|
|
508
565
|
return;
|
|
509
566
|
}
|
|
@@ -511,6 +568,9 @@ function visitPersistenceEntities(csn, onEntity) {
|
|
|
511
568
|
return csn.definitions[name].kind === "service";
|
|
512
569
|
});
|
|
513
570
|
return Object.keys(csn.definitions).forEach((name) => {
|
|
571
|
+
if (filter && !filter.includes(name)) {
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
514
574
|
// Normal persistence entity
|
|
515
575
|
const definition = csn.definitions[name];
|
|
516
576
|
if (
|
|
@@ -490,7 +490,7 @@ class ReplicationCache {
|
|
|
490
490
|
search(query) {
|
|
491
491
|
let search = true;
|
|
492
492
|
if (query.SELECT.search?.length > 0) {
|
|
493
|
-
const ref = query.
|
|
493
|
+
const ref = query._target.name;
|
|
494
494
|
this.stats.search[ref] ??= 0;
|
|
495
495
|
this.stats.search[ref]++;
|
|
496
496
|
this.log.debug("Replication cache skipped for search", {
|
|
@@ -504,7 +504,7 @@ class ReplicationCache {
|
|
|
504
504
|
localized(query, refs) {
|
|
505
505
|
let localized = true;
|
|
506
506
|
if (query.SELECT.localized) {
|
|
507
|
-
const ref = query.
|
|
507
|
+
const ref = query._target.name;
|
|
508
508
|
this.stats.localized[ref] ??= 0;
|
|
509
509
|
this.stats.localized[ref]++;
|
|
510
510
|
this.log.debug("Replication cache not enabled for 'localized' without deploy feature", {
|
|
@@ -852,19 +852,20 @@ function fromRefs(model, query) {
|
|
|
852
852
|
return refs;
|
|
853
853
|
}, []);
|
|
854
854
|
}
|
|
855
|
-
if (query.
|
|
855
|
+
if (query._target) {
|
|
856
|
+
const target = model.definitions[query._target.name];
|
|
856
857
|
if (query.SELECT.orderBy) {
|
|
857
|
-
refs = refs.concat(expressionRefs(model,
|
|
858
|
+
refs = refs.concat(expressionRefs(model, target, query.SELECT.orderBy));
|
|
858
859
|
}
|
|
859
860
|
if (query.SELECT.columns) {
|
|
860
|
-
refs = refs.concat(expressionRefs(model,
|
|
861
|
-
refs = refs.concat(expandRefs(model,
|
|
861
|
+
refs = refs.concat(expressionRefs(model, target, query.SELECT.columns));
|
|
862
|
+
refs = refs.concat(expandRefs(model, target, query.SELECT.columns));
|
|
862
863
|
}
|
|
863
864
|
if (query.SELECT.where) {
|
|
864
|
-
refs = refs.concat(expressionRefs(model,
|
|
865
|
+
refs = refs.concat(expressionRefs(model, target, query.SELECT.where));
|
|
865
866
|
}
|
|
866
867
|
if (query.SELECT.having) {
|
|
867
|
-
refs = refs.concat(expressionRefs(model,
|
|
868
|
+
refs = refs.concat(expressionRefs(model, target, query.SELECT.having));
|
|
868
869
|
}
|
|
869
870
|
}
|
|
870
871
|
return refs;
|