@flusys/nestjs-entity-builder 9.1.2 → 9.2.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/README.md +49 -25
- package/config/entity-builder.constants.d.ts +1 -0
- package/config/message-keys.d.ts +37 -2
- package/controllers/definition-bundle.controller.d.ts +2 -2
- package/controllers/entity-definition.controller.d.ts +1 -1
- package/controllers/field-definition.controller.d.ts +1 -1
- package/controllers/flow-definition.controller.d.ts +3 -1
- package/controllers/flow-runtime.controller.d.ts +4 -3
- package/dtos/definition-bundle.dto.d.ts +1 -0
- package/dtos/entity-definition.dto.d.ts +1 -2
- package/fesm/21.js +39 -5
- package/fesm/{458.js → 28.js} +110 -63
- package/fesm/677.js +1543 -513
- package/fesm/794.js +1 -1
- package/fesm/857.js +3 -3
- package/fesm/870.js +974 -558
- package/fesm/897.js +187 -51
- package/fesm/946.js +72 -43
- package/fesm/config/index.js +10 -14
- package/fesm/docs/index.js +1 -1
- package/fesm/dtos/index.js +11 -0
- package/fesm/guards/index.js +16 -10
- package/fesm/index.js +44 -26
- package/fesm/modules/index.js +4 -3
- package/fesm/services/index.js +40 -59
- package/flow-engine/flow-code-runner.d.ts +16 -0
- package/flow-engine/flow-graph.validator.d.ts +1 -0
- package/flow-engine/flow-input.validator.d.ts +16 -1
- package/flow-engine/flow-run.types.d.ts +16 -0
- package/flow-engine/flow.types.d.ts +18 -1
- package/guards/designer-writable.interceptor.d.ts +1 -0
- package/interfaces/definition-bundle.interface.d.ts +4 -1
- package/interfaces/entity-builder-module.interface.d.ts +9 -0
- package/modules/entity-builder.module.d.ts +1 -0
- package/modules/index.d.ts +1 -0
- package/modules/tenant-context-id.strategy.d.ts +16 -0
- package/package.json +3 -4
- package/services/definition-bundle.diff.d.ts +6 -2
- package/services/definition-bundle.file.d.ts +2 -1
- package/services/definition-bundle.service.d.ts +10 -3
- package/services/entity-builder-config.service.d.ts +3 -0
- package/services/entity-builder-datasource.provider.d.ts +1 -0
- package/services/entity-flow-scaffold.d.ts +2 -1
- package/services/entity-permission.service.d.ts +1 -0
- package/services/field-value-validator.d.ts +7 -0
- package/services/flow-definition.service.d.ts +11 -3
- package/services/flow-executor.service.d.ts +3 -0
- package/services/flow-runtime.service.d.ts +7 -1
- package/services/generic-entity-service.factory.d.ts +5 -1
- package/services/generic-entity.service.d.ts +25 -2
- package/services/identifier-rules.d.ts +0 -1
- package/services/save-loaded.d.ts +2 -0
- package/services/schema-change-executor.service.d.ts +1 -0
- package/services/schema-columns.d.ts +7 -2
- package/services/schema-dialect-adapter.service.d.ts +2 -0
- package/services/schema-evolution.service.d.ts +8 -2
- package/services/schema-registry.service.d.ts +12 -0
- package/services/schema-sync.service.d.ts +3 -1
- package/flow-engine/flow-code-sandbox.d.ts +0 -5
package/fesm/870.js
CHANGED
|
@@ -383,6 +383,7 @@ _ts_decorate([
|
|
|
383
383
|
/** Form values arrive as text: `true` / `false` become booleans, anything else is left for the validator to refuse. */ const FormBoolean = ()=>(0,class_transformer__rspack_import_1.Transform)(({ value })=>value === 'true' ? true : value === 'false' ? false : value);
|
|
384
384
|
/** The form fields sent with the bundle file to plan-import / apply-import. */ class ImportBundleOptionsDto {
|
|
385
385
|
deprecateMissingFields;
|
|
386
|
+
deactivateMissingFlows;
|
|
386
387
|
confirm;
|
|
387
388
|
expectedChecksum;
|
|
388
389
|
expectedPlanChecksum;
|
|
@@ -397,6 +398,16 @@ _ts_decorate([
|
|
|
397
398
|
(0,class_validator__rspack_import_2.IsBoolean)(),
|
|
398
399
|
_ts_metadata("design:type", Boolean)
|
|
399
400
|
], ImportBundleOptionsDto.prototype, "deprecateMissingFields", void 0);
|
|
401
|
+
_ts_decorate([
|
|
402
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
403
|
+
description: 'Switch off (and publish) the live flows this environment has and the bundle does not (they are kept, not deleted)',
|
|
404
|
+
default: false
|
|
405
|
+
}),
|
|
406
|
+
(0,class_validator__rspack_import_2.IsOptional)(),
|
|
407
|
+
FormBoolean(),
|
|
408
|
+
(0,class_validator__rspack_import_2.IsBoolean)(),
|
|
409
|
+
_ts_metadata("design:type", Boolean)
|
|
410
|
+
], ImportBundleOptionsDto.prototype, "deactivateMissingFlows", void 0);
|
|
400
411
|
_ts_decorate([
|
|
401
412
|
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
402
413
|
description: 'apply-import: acknowledge steps that lose (or may lose) data',
|
|
@@ -461,9 +472,19 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
461
472
|
3801(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
462
473
|
/* import */ var _flusys_nestjs_shared_utils__rspack_import_0 = __webpack_require__(9216);
|
|
463
474
|
/* import */ var node_crypto__rspack_import_1 = __webpack_require__(2561);
|
|
464
|
-
/* import */ var
|
|
465
|
-
/* import */ var
|
|
466
|
-
/* import */ var
|
|
475
|
+
/* import */ var _config_message_keys_js__rspack_import_7 = __webpack_require__(5732);
|
|
476
|
+
/* import */ var _enums_entity_status_enum_js__rspack_import_8 = __webpack_require__(1313);
|
|
477
|
+
/* import */ var _enums_field_type_enum_js__rspack_import_9 = __webpack_require__(9614);
|
|
478
|
+
/* import */ var _flow_engine_flow_types_js__rspack_import_2 = __webpack_require__(6256);
|
|
479
|
+
/* import */ var _rule_engine_rule_permission_js__rspack_import_3 = __webpack_require__(5191);
|
|
480
|
+
/* import */ var _rule_engine_rule_interface_js__rspack_import_4 = __webpack_require__(2354);
|
|
481
|
+
/* import */ var _flow_definition_service_js__rspack_import_5 = __webpack_require__(5229);
|
|
482
|
+
/* import */ var _reference_rewrite_js__rspack_import_6 = __webpack_require__(3086);
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
|
|
467
488
|
|
|
468
489
|
|
|
469
490
|
|
|
@@ -499,22 +520,10 @@ const bundleChecksum = (bundle)=>(0,node_crypto__rspack_import_1.createHash)('sh
|
|
|
499
520
|
}
|
|
500
521
|
const VARIABLE_PATTERN = /\$\{var:([A-Za-z_][A-Za-z0-9_]*)\}/g;
|
|
501
522
|
/** Shorter values would be replaced inside unrelated text. */ const MIN_VARIABLE_VALUE_LENGTH = 4;
|
|
502
|
-
function mapStrings(value, fn) {
|
|
503
|
-
if (typeof value === 'string') return fn(value);
|
|
504
|
-
if (Array.isArray(value)) return value.map((item)=>mapStrings(item, fn));
|
|
505
|
-
if (value && typeof value === 'object') {
|
|
506
|
-
return Object.fromEntries(Object.entries(value).map(([key, item])=>[
|
|
507
|
-
key,
|
|
508
|
-
mapStrings(item, fn)
|
|
509
|
-
]));
|
|
510
|
-
}
|
|
511
|
-
return value;
|
|
512
|
-
}
|
|
513
523
|
/** Only a step's settings hold environment values: its id, type, name and position are never rewritten. */ const mapConfigStrings = (nodes, fn)=>nodes.map((node)=>node?.config ? {
|
|
514
524
|
...node,
|
|
515
|
-
config: mapStrings(node.config, fn)
|
|
525
|
+
config: (0,_reference_rewrite_js__rspack_import_6/* .mapStrings */.to)(node.config, fn)
|
|
516
526
|
} : node);
|
|
517
|
-
const escapeRegExp = (text)=>text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
518
527
|
/**
|
|
519
528
|
* Export: every occurrence of this environment's variable values in a step's settings becomes `${var:NAME}`
|
|
520
529
|
* (longest value first; one pass, so a placeholder already written is never rewritten by a shorter value).
|
|
@@ -526,7 +535,7 @@ const escapeRegExp = (text)=>text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
|
526
535
|
if (!nameOf.size) return nodes;
|
|
527
536
|
const pattern = new RegExp([
|
|
528
537
|
...nameOf.keys()
|
|
529
|
-
].map(
|
|
538
|
+
].map(_reference_rewrite_js__rspack_import_6/* .escapeRe */.NF).join('|'), 'g');
|
|
530
539
|
return mapConfigStrings(nodes, (text)=>text.replace(pattern, (value)=>`\${var:${nameOf.get(value)}}`));
|
|
531
540
|
}
|
|
532
541
|
/** Import: `${var:NAME}` in a step's settings becomes this environment's value; names it does not define are returned, not replaced. */ function applyVariables(nodes, variables) {
|
|
@@ -543,6 +552,84 @@ const escapeRegExp = (text)=>text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
|
543
552
|
].toSorted(byCode)
|
|
544
553
|
};
|
|
545
554
|
}
|
|
555
|
+
const UUID_PATTERN = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
|
|
556
|
+
/**
|
|
557
|
+
* The record, user, company and email configuration ids written into a flow's step settings (step ids
|
|
558
|
+
* are never UUIDs). Such an id belongs to the environment it was typed in: each needs a `${var:NAME}`.
|
|
559
|
+
*/ function fixedIds(nodes) {
|
|
560
|
+
const ids = new Set();
|
|
561
|
+
mapConfigStrings(nodes, (text)=>{
|
|
562
|
+
for (const [id] of text.matchAll(UUID_PATTERN))ids.add(id.toLowerCase());
|
|
563
|
+
return text;
|
|
564
|
+
});
|
|
565
|
+
return [
|
|
566
|
+
...ids
|
|
567
|
+
].toSorted(byCode);
|
|
568
|
+
}
|
|
569
|
+
/** The fixed codes of a HAS_PERMISSION / HAS_ANY_PERMISSION / HAS_ALL_PERMISSIONS call; more than a check may name is refused when the flow is validated. */ function literalPermissionCodes(value) {
|
|
570
|
+
try {
|
|
571
|
+
return (0,_rule_engine_rule_permission_js__rspack_import_3/* .parsePermissionCodes */.PS)(value);
|
|
572
|
+
} catch {
|
|
573
|
+
return [];
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Every permission code a flow checks: the rule of each `permission` URL (the execute permission when
|
|
578
|
+
* it has none), its Permission check steps, and the codes its permission functions name as literals.
|
|
579
|
+
*/ function permissionCodes(flow) {
|
|
580
|
+
const codes = new Set();
|
|
581
|
+
const add = (list)=>list.forEach((code)=>codes.add(code));
|
|
582
|
+
for (const endpoint of (0,_flow_engine_flow_types_js__rspack_import_2/* .flowEndpoints */.Xr)(flow))if (endpoint.authMode === 'permission') add((0,_flusys_nestjs_shared_utils__rspack_import_0.permissionLogicCodes)((0,_flow_definition_service_js__rspack_import_5/* .flowPermissions */.j4)(endpoint, flow.slug)));
|
|
583
|
+
const walk = (value)=>{
|
|
584
|
+
if (Array.isArray(value)) return value.forEach(walk);
|
|
585
|
+
if (!value || typeof value !== 'object') return;
|
|
586
|
+
const call = value;
|
|
587
|
+
if (call.type === 'function' && (0,_rule_engine_rule_interface_js__rspack_import_4/* .isPermissionFunction */.A8)(call.name) && call.args?.[0]?.type === 'literal') add(literalPermissionCodes(call.args[0].value));
|
|
588
|
+
Object.values(value).forEach(walk);
|
|
589
|
+
};
|
|
590
|
+
for (const node of flow.nodes){
|
|
591
|
+
if (node?.type === 'permission_check' && node.config?.['permissions']) add((0,_flusys_nestjs_shared_utils__rspack_import_0.permissionLogicCodes)(node.config['permissions']));
|
|
592
|
+
walk(node?.config);
|
|
593
|
+
}
|
|
594
|
+
return [
|
|
595
|
+
...codes
|
|
596
|
+
].toSorted(byCode);
|
|
597
|
+
}
|
|
598
|
+
const SECRET_NAME = /authorization|token|secret|api[-_]?key|password|passwd|cookie|signature|credential/i;
|
|
599
|
+
const AUTH_SCHEME = /^\s*(bearer|basic|token|digest)\s+/i;
|
|
600
|
+
/** Shorter written text is a scheme, a separator or a placeholder's leftovers, not a credential. */ const MIN_SECRET_LENGTH = 8;
|
|
601
|
+
/** The text an expression writes itself: a literal, a template or concat parts without their `{{ ... }}` and `${var:NAME}`. */ function writtenText(expression) {
|
|
602
|
+
if (typeof expression === 'string') return expression;
|
|
603
|
+
if (!expression || typeof expression !== 'object') return '';
|
|
604
|
+
const e = expression;
|
|
605
|
+
if (e.type === 'literal') return typeof e.value === 'string' ? e.value : '';
|
|
606
|
+
if (e.type === 'template') return typeof e.template === 'string' ? e.template.replace(/\{\{[^}]*\}\}/g, '') : '';
|
|
607
|
+
if (e.type === 'concat' && Array.isArray(e.parts)) return e.parts.map(writtenText).join('');
|
|
608
|
+
return '';
|
|
609
|
+
}
|
|
610
|
+
const isWrittenSecret = (text)=>text.replace(VARIABLE_PATTERN, '').replace(AUTH_SCHEME, '').trim().length >= MIN_SECRET_LENGTH;
|
|
611
|
+
/**
|
|
612
|
+
* HTTP steps that send a credential written into the step (a header such as `Authorization` or a query
|
|
613
|
+
* parameter such as `api_key`): an export puts it in git as plain text unless it is a `${var:NAME}`.
|
|
614
|
+
*/ function writtenSecrets(nodes) {
|
|
615
|
+
const found = [];
|
|
616
|
+
for (const node of nodes.filter((n)=>n?.type === 'http_request')){
|
|
617
|
+
const config = node.config ?? {};
|
|
618
|
+
for (const [name, value] of Object.entries(config.headers ?? {})){
|
|
619
|
+
if (SECRET_NAME.test(name) && isWrittenSecret(writtenText(value))) found.push({
|
|
620
|
+
step: node.name || node.id,
|
|
621
|
+
name
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
for (const [, name, value] of writtenText(config.url).matchAll(/[?&]([^=&#]+)=([^&#]*)/g)){
|
|
625
|
+
if (SECRET_NAME.test(name) && isWrittenSecret(value)) found.push({
|
|
626
|
+
step: node.name || node.id,
|
|
627
|
+
name
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
return found;
|
|
632
|
+
}
|
|
546
633
|
/** Slugs the Call flow steps of a flow run. */ function calledFlowSlugs(nodes) {
|
|
547
634
|
return nodes.filter((node)=>node?.type === 'call_flow' && typeof node.config?.['flowSlug'] === 'string').map((node)=>node.config['flowSlug']);
|
|
548
635
|
}
|
|
@@ -613,17 +700,17 @@ function changedValues(from, to, keys) {
|
|
|
613
700
|
const problems = [];
|
|
614
701
|
const codes = new Set();
|
|
615
702
|
for (const entity of entities){
|
|
616
|
-
if (codes.has(entity.code)) problems.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
703
|
+
if (codes.has(entity.code)) problems.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .BUNDLE_MESSAGES.DUPLICATE_ENTITY */.iX.DUPLICATE_ENTITY, {
|
|
617
704
|
entity: entity.code
|
|
618
705
|
}));
|
|
619
|
-
if (entity.status ===
|
|
706
|
+
if (entity.status === _enums_entity_status_enum_js__rspack_import_8/* .EntityStatus.DRAFT */.c.DRAFT) problems.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .BUNDLE_MESSAGES.ENTITY_DRAFT_IN_BUNDLE */.iX.ENTITY_DRAFT_IN_BUNDLE, {
|
|
620
707
|
entity: entity.code
|
|
621
708
|
}));
|
|
622
709
|
codes.add(entity.code);
|
|
623
710
|
const fieldCodes = new Set();
|
|
624
711
|
const fieldIds = new Set();
|
|
625
712
|
for (const field of entity.fields){
|
|
626
|
-
if (fieldCodes.has(field.code) || fieldIds.has(field.id)) problems.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
713
|
+
if (fieldCodes.has(field.code) || fieldIds.has(field.id)) problems.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .BUNDLE_MESSAGES.DUPLICATE_FIELD */.iX.DUPLICATE_FIELD, {
|
|
627
714
|
entity: entity.code,
|
|
628
715
|
field: field.code
|
|
629
716
|
}));
|
|
@@ -636,9 +723,9 @@ function changedValues(from, to, keys) {
|
|
|
636
723
|
...current.map((e)=>e.code)
|
|
637
724
|
]);
|
|
638
725
|
for (const entity of entities){
|
|
639
|
-
for (const field of entity.fields.filter((f)=>f.fieldType ===
|
|
726
|
+
for (const field of entity.fields.filter((f)=>f.fieldType === _enums_field_type_enum_js__rspack_import_9/* .FieldType.RELATION */.P.RELATION && !f.deprecated)){
|
|
640
727
|
if (!field.relationTarget || !known.has(field.relationTarget)) {
|
|
641
|
-
problems.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
728
|
+
problems.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .BUNDLE_MESSAGES.RELATION_TARGET_UNKNOWN */.iX.RELATION_TARGET_UNKNOWN, {
|
|
642
729
|
entity: entity.code,
|
|
643
730
|
field: field.code,
|
|
644
731
|
target: field.relationTarget ?? ''
|
|
@@ -696,7 +783,7 @@ function changedValues(from, to, keys) {
|
|
|
696
783
|
const first = pending[0];
|
|
697
784
|
const temporary = temporaryCode(first.targetFieldId, taken);
|
|
698
785
|
ordered.push(step(first, first.from, temporary, first.restored || first.waited, [
|
|
699
|
-
(0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
786
|
+
(0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .BUNDLE_MESSAGES.RENAME_VIA_TEMPORARY */.iX.RENAME_VIA_TEMPORARY, {
|
|
700
787
|
field: first.from,
|
|
701
788
|
temporary,
|
|
702
789
|
to: first.to
|
|
@@ -740,7 +827,7 @@ function changedValues(from, to, keys) {
|
|
|
740
827
|
for (const entity of sorted){
|
|
741
828
|
const target = pairs.get(entity);
|
|
742
829
|
if (target && target.code !== entity.code) {
|
|
743
|
-
result.blockers.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
830
|
+
result.blockers.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .BUNDLE_MESSAGES.ENTITY_CODE_CHANGED */.iX.ENTITY_CODE_CHANGED, {
|
|
744
831
|
entity: entity.code,
|
|
745
832
|
current: target.code
|
|
746
833
|
}));
|
|
@@ -752,15 +839,15 @@ function changedValues(from, to, keys) {
|
|
|
752
839
|
kind: 'create_entity',
|
|
753
840
|
entityCode: entity.code,
|
|
754
841
|
details: {
|
|
755
|
-
fields: live.filter((f)=>f.fieldType !==
|
|
842
|
+
fields: live.filter((f)=>f.fieldType !== _enums_field_type_enum_js__rspack_import_9/* .FieldType.RELATION */.P.RELATION).map((f)=>f.code)
|
|
756
843
|
},
|
|
757
844
|
dependsOnEarlierStep: false,
|
|
758
845
|
entity: {
|
|
759
846
|
...entity,
|
|
760
|
-
fields: live.filter((f)=>f.fieldType !==
|
|
847
|
+
fields: live.filter((f)=>f.fieldType !== _enums_field_type_enum_js__rspack_import_9/* .FieldType.RELATION */.P.RELATION)
|
|
761
848
|
}
|
|
762
849
|
});
|
|
763
|
-
for (const field of live.filter((f)=>f.fieldType ===
|
|
850
|
+
for (const field of live.filter((f)=>f.fieldType === _enums_field_type_enum_js__rspack_import_9/* .FieldType.RELATION */.P.RELATION)){
|
|
764
851
|
relationAdds.push({
|
|
765
852
|
kind: 'add_field',
|
|
766
853
|
entityCode: entity.code,
|
|
@@ -773,7 +860,7 @@ function changedValues(from, to, keys) {
|
|
|
773
860
|
field
|
|
774
861
|
});
|
|
775
862
|
}
|
|
776
|
-
if (entity.status ===
|
|
863
|
+
if (entity.status === _enums_entity_status_enum_js__rspack_import_8/* .EntityStatus.DEPRECATED */.c.DEPRECATED) {
|
|
777
864
|
entityUpdatesLast.push({
|
|
778
865
|
kind: 'update_entity',
|
|
779
866
|
entityCode: entity.code,
|
|
@@ -784,20 +871,20 @@ function changedValues(from, to, keys) {
|
|
|
784
871
|
},
|
|
785
872
|
dependsOnEarlierStep: true,
|
|
786
873
|
changes: {
|
|
787
|
-
status:
|
|
874
|
+
status: _enums_entity_status_enum_js__rspack_import_8/* .EntityStatus.DEPRECATED */.c.DEPRECATED
|
|
788
875
|
}
|
|
789
876
|
});
|
|
790
877
|
}
|
|
791
878
|
continue;
|
|
792
879
|
}
|
|
793
|
-
if (target.status ===
|
|
794
|
-
result.blockers.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
880
|
+
if (target.status === _enums_entity_status_enum_js__rspack_import_8/* .EntityStatus.DRAFT */.c.DRAFT) {
|
|
881
|
+
result.blockers.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .BUNDLE_MESSAGES.ENTITY_DRAFT_HERE */.iX.ENTITY_DRAFT_HERE, {
|
|
795
882
|
entity: entity.code
|
|
796
883
|
}));
|
|
797
884
|
continue;
|
|
798
885
|
}
|
|
799
886
|
const entityChanges = changedValues(target, entity, ENTITY_COMPARED_KEYS);
|
|
800
|
-
const deprecating = entityChanges['status'] ===
|
|
887
|
+
const deprecating = entityChanges['status'] === _enums_entity_status_enum_js__rspack_import_8/* .EntityStatus.DEPRECATED */.c.DEPRECATED;
|
|
801
888
|
if (Object.keys(entityChanges).length) {
|
|
802
889
|
(deprecating ? entityUpdatesLast : entityUpdatesFirst).push({
|
|
803
890
|
kind: 'update_entity',
|
|
@@ -934,18 +1021,19 @@ function changedValues(from, to, keys) {
|
|
|
934
1021
|
__webpack_require__.d(__webpack_exports__, {
|
|
935
1022
|
Og: () => (matchDefinitions),
|
|
936
1023
|
Q5: () => (calledFlowSlugs),
|
|
1024
|
+
QJ: () => (permissionCodes),
|
|
937
1025
|
dX: () => (stripApiKeys),
|
|
938
1026
|
dj: () => (canonicalJson),
|
|
1027
|
+
f7: () => (fixedIds),
|
|
939
1028
|
gT: () => (applyVariables),
|
|
1029
|
+
l6: () => (writtenSecrets),
|
|
940
1030
|
lj: () => (extractVariables),
|
|
941
1031
|
qG: () => (orderFlows),
|
|
942
1032
|
zb: () => (diffEntities)
|
|
943
1033
|
}, {
|
|
944
|
-
$I: ENTITY_COMPARED_KEYS,
|
|
945
1034
|
VU: byCode,
|
|
946
1035
|
bs: bundleSubject,
|
|
947
|
-
i9: bundleChecksum
|
|
948
|
-
mT: FIELD_COMPARED_KEYS
|
|
1036
|
+
i9: bundleChecksum
|
|
949
1037
|
});
|
|
950
1038
|
|
|
951
1039
|
|
|
@@ -953,22 +1041,34 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
953
1041
|
6412(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
954
1042
|
/* import */ var _nestjs_common__rspack_import_0 = __webpack_require__(6157);
|
|
955
1043
|
/* import */ var class_transformer__rspack_import_1 = __webpack_require__(5812);
|
|
956
|
-
/* import */ var
|
|
957
|
-
/* import */ var
|
|
958
|
-
/* import */ var
|
|
1044
|
+
/* import */ var _flusys_nestjs_shared_utils__rspack_import_2 = __webpack_require__(9216);
|
|
1045
|
+
/* import */ var class_validator__rspack_import_3 = __webpack_require__(5421);
|
|
1046
|
+
/* import */ var _config_entity_builder_constants_js__rspack_import_7 = __webpack_require__(6576);
|
|
1047
|
+
/* import */ var _config_message_keys_js__rspack_import_6 = __webpack_require__(5732);
|
|
1048
|
+
/* import */ var _dtos_definition_bundle_dto_js__rspack_import_4 = __webpack_require__(6691);
|
|
1049
|
+
/* import */ var _interfaces_definition_bundle_interface_js__rspack_import_8 = __webpack_require__(8835);
|
|
1050
|
+
/* import */ var _definition_bundle_diff_js__rspack_import_5 = __webpack_require__(3801);
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
|
|
1054
|
+
|
|
959
1055
|
|
|
960
1056
|
|
|
961
1057
|
|
|
962
1058
|
|
|
963
1059
|
|
|
964
1060
|
const MAX_REPORTED_PROBLEMS = 50;
|
|
965
|
-
/** Every failed constraint, named by its path in the bundle (`entities.0.fields.2.code`). */ function problems(errors, parent = '') {
|
|
1061
|
+
/** Every failed constraint, named by its path in the bundle (`entities.0.fields.2.code`); `constraints` are class-validator's names (`isString`, `maxLength`). */ function problems(errors, parent = '') {
|
|
966
1062
|
return errors.flatMap((error)=>{
|
|
967
1063
|
const field = parent ? `${parent}.${error.property}` : error.property;
|
|
968
1064
|
const own = error.constraints ? [
|
|
969
1065
|
{
|
|
970
1066
|
field,
|
|
971
|
-
message: Object.values(error.constraints).join('; ')
|
|
1067
|
+
message: Object.values(error.constraints).join('; '),
|
|
1068
|
+
...(0,_flusys_nestjs_shared_utils__rspack_import_2.messageRef)(_config_message_keys_js__rspack_import_6/* .BUNDLE_MESSAGES.FILE_VALUE_INVALID */.iX.FILE_VALUE_INVALID, {
|
|
1069
|
+
field,
|
|
1070
|
+
constraints: Object.keys(error.constraints).join(', ')
|
|
1071
|
+
})
|
|
972
1072
|
}
|
|
973
1073
|
] : [];
|
|
974
1074
|
return [
|
|
@@ -977,9 +1077,16 @@ const MAX_REPORTED_PROBLEMS = 50;
|
|
|
977
1077
|
];
|
|
978
1078
|
});
|
|
979
1079
|
}
|
|
1080
|
+
const fileProblem = (file, message, messageKey)=>({
|
|
1081
|
+
field: file,
|
|
1082
|
+
message,
|
|
1083
|
+
...(0,_flusys_nestjs_shared_utils__rspack_import_2.messageRef)(messageKey, {
|
|
1084
|
+
file
|
|
1085
|
+
})
|
|
1086
|
+
});
|
|
980
1087
|
const invalid = (errors = [])=>new _nestjs_common__rspack_import_0.BadRequestException({
|
|
981
1088
|
message: 'The file is not a valid entity builder bundle.',
|
|
982
|
-
messageKey:
|
|
1089
|
+
messageKey: _config_message_keys_js__rspack_import_6/* .BUNDLE_MESSAGES.FILE_INVALID */.iX.FILE_INVALID,
|
|
983
1090
|
...errors.length ? {
|
|
984
1091
|
errors: errors.slice(0, MAX_REPORTED_PROBLEMS)
|
|
985
1092
|
} : {}
|
|
@@ -987,57 +1094,94 @@ const invalid = (errors = [])=>new _nestjs_common__rspack_import_0.BadRequestExc
|
|
|
987
1094
|
/**
|
|
988
1095
|
* The uploaded bundle, parsed and checked as strictly as a request body (unknown keys refused). The
|
|
989
1096
|
* bundle travels as a file rather than as JSON so the app's JSON body limit never applies to it: the
|
|
990
|
-
* upload limit is the package's own (`ENTITY_BUNDLE_MAX_BYTES`, enforced by
|
|
991
|
-
*/ function readBundleFile(file) {
|
|
1097
|
+
* upload limit is the package's own (`ENTITY_BUNDLE_MAX_BYTES`, enforced by FilesInterceptor).
|
|
1098
|
+
*/ function readBundleFile(file, source = '') {
|
|
992
1099
|
if (!file?.buffer?.length) {
|
|
993
1100
|
throw new _nestjs_common__rspack_import_0.BadRequestException({
|
|
994
1101
|
message: 'Attach the bundle file as the "bundle" form field.',
|
|
995
|
-
messageKey:
|
|
1102
|
+
messageKey: _config_message_keys_js__rspack_import_6/* .BUNDLE_MESSAGES.FILE_REQUIRED */.iX.FILE_REQUIRED
|
|
996
1103
|
});
|
|
997
1104
|
}
|
|
1105
|
+
const unreadable = (message, messageKey)=>invalid(source ? [
|
|
1106
|
+
fileProblem(source, message, messageKey)
|
|
1107
|
+
] : []);
|
|
998
1108
|
let raw;
|
|
999
1109
|
try {
|
|
1000
1110
|
raw = JSON.parse(file.buffer.toString('utf8').replace(/^\uFEFF/, ''));
|
|
1001
1111
|
} catch {
|
|
1002
|
-
throw
|
|
1112
|
+
throw unreadable('not valid JSON', _config_message_keys_js__rspack_import_6/* .BUNDLE_MESSAGES.FILE_NOT_JSON */.iX.FILE_NOT_JSON);
|
|
1003
1113
|
}
|
|
1004
|
-
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) throw
|
|
1005
|
-
const bundle = (0,class_transformer__rspack_import_1.plainToInstance)(
|
|
1006
|
-
const errors = (0,
|
|
1114
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) throw unreadable('not a JSON object', _config_message_keys_js__rspack_import_6/* .BUNDLE_MESSAGES.FILE_NOT_OBJECT */.iX.FILE_NOT_OBJECT);
|
|
1115
|
+
const bundle = (0,class_transformer__rspack_import_1.plainToInstance)(_dtos_definition_bundle_dto_js__rspack_import_4/* .DefinitionBundleDto */.JE, raw);
|
|
1116
|
+
const errors = (0,class_validator__rspack_import_3.validateSync)(bundle, {
|
|
1007
1117
|
whitelist: true,
|
|
1008
1118
|
forbidNonWhitelisted: true
|
|
1009
1119
|
});
|
|
1010
|
-
if (errors.length) throw invalid(problems(errors));
|
|
1120
|
+
if (errors.length) throw invalid(problems(errors, source));
|
|
1011
1121
|
return bundle;
|
|
1012
1122
|
}
|
|
1123
|
+
/**
|
|
1124
|
+
* One bundle from one or more uploaded files. Every file is a complete bundle on its own - a whole export,
|
|
1125
|
+
* or one file per entity and per flow as `entity-bundle export --split` writes them - so a folder kept in git
|
|
1126
|
+
* can be cherry-picked file by file. Entities and flows are merged in code / slug order, the order an export
|
|
1127
|
+
* writes them, so a split folder and the single file of the same definitions have the same checksum.
|
|
1128
|
+
* A definition in two files is not merged here: the plan blocks it as a duplicate.
|
|
1129
|
+
*/ function readBundleFiles(files) {
|
|
1130
|
+
if (!files?.length) return readBundleFile(undefined);
|
|
1131
|
+
if (files.length === 1) return readBundleFile(files[0]);
|
|
1132
|
+
if (files.reduce((total, file)=>total + file.size, 0) > _config_entity_builder_constants_js__rspack_import_7/* .ENTITY_BUNDLE_MAX_BYTES */.EA) {
|
|
1133
|
+
throw new _nestjs_common__rspack_import_0.PayloadTooLargeException({
|
|
1134
|
+
message: 'The bundle files are larger than the upload limit together.',
|
|
1135
|
+
messageKey: _config_message_keys_js__rspack_import_6/* .BUNDLE_MESSAGES.FILES_TOO_LARGE */.iX.FILES_TOO_LARGE
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
const bundles = files.map((file, index)=>{
|
|
1139
|
+
const name = file.originalname || `#${index + 1}`;
|
|
1140
|
+
if (!file.buffer?.length) throw invalid([
|
|
1141
|
+
fileProblem(name, 'empty file', _config_message_keys_js__rspack_import_6/* .BUNDLE_MESSAGES.FILE_EMPTY */.iX.FILE_EMPTY)
|
|
1142
|
+
]);
|
|
1143
|
+
return readBundleFile(file, name);
|
|
1144
|
+
});
|
|
1145
|
+
return {
|
|
1146
|
+
format: _interfaces_definition_bundle_interface_js__rspack_import_8/* .DEFINITION_BUNDLE_FORMAT */.D,
|
|
1147
|
+
version: (/* inlined export .DEFINITION_BUNDLE_VERSION */1),
|
|
1148
|
+
entities: bundles.flatMap((b)=>b.entities).toSorted((a, b)=>(0,_definition_bundle_diff_js__rspack_import_5/* .byCode */.VU)(a.code, b.code)),
|
|
1149
|
+
flows: bundles.flatMap((b)=>b.flows).toSorted((a, b)=>(0,_definition_bundle_diff_js__rspack_import_5/* .byCode */.VU)(a.slug, b.slug))
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1013
1152
|
|
|
1014
1153
|
__webpack_require__.d(__webpack_exports__, {
|
|
1154
|
+
K: () => (readBundleFiles),
|
|
1015
1155
|
z: () => (readBundleFile)
|
|
1016
1156
|
});
|
|
1017
1157
|
|
|
1018
1158
|
|
|
1019
1159
|
},
|
|
1020
1160
|
7463(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
1021
|
-
/* import */ var
|
|
1022
|
-
/* import */ var
|
|
1023
|
-
/* import */ var
|
|
1024
|
-
/* import */ var
|
|
1025
|
-
/* import */ var
|
|
1026
|
-
/* import */ var
|
|
1027
|
-
/* import */ var
|
|
1028
|
-
/* import */ var
|
|
1029
|
-
/* import */ var
|
|
1030
|
-
/* import */ var
|
|
1031
|
-
/* import */ var
|
|
1032
|
-
/* import */ var
|
|
1033
|
-
/* import */ var
|
|
1034
|
-
/* import */ var
|
|
1035
|
-
/* import */ var
|
|
1036
|
-
/* import */ var
|
|
1037
|
-
/* import */ var
|
|
1038
|
-
/* import */ var
|
|
1039
|
-
/* import */ var
|
|
1040
|
-
/* import */ var
|
|
1161
|
+
/* import */ var _flusys_nestjs_shared_interfaces__rspack_import_0 = __webpack_require__(5103);
|
|
1162
|
+
/* import */ var _flusys_nestjs_shared_utils__rspack_import_1 = __webpack_require__(9216);
|
|
1163
|
+
/* import */ var _nestjs_common__rspack_import_2 = __webpack_require__(6157);
|
|
1164
|
+
/* import */ var node_crypto__rspack_import_3 = __webpack_require__(2561);
|
|
1165
|
+
/* import */ var typeorm__rspack_import_4 = __webpack_require__(7158);
|
|
1166
|
+
/* import */ var _config_message_keys_js__rspack_import_20 = __webpack_require__(5732);
|
|
1167
|
+
/* import */ var _dtos_schema_change_dto_js__rspack_import_5 = __webpack_require__(4945);
|
|
1168
|
+
/* import */ var _entities_entity_definition_entity_js__rspack_import_6 = __webpack_require__(3189);
|
|
1169
|
+
/* import */ var _enums_entity_status_enum_js__rspack_import_19 = __webpack_require__(1313);
|
|
1170
|
+
/* import */ var _enums_field_type_enum_js__rspack_import_22 = __webpack_require__(9614);
|
|
1171
|
+
/* import */ var _entities_field_definition_entity_js__rspack_import_7 = __webpack_require__(2206);
|
|
1172
|
+
/* import */ var _entities_flow_definition_entity_js__rspack_import_8 = __webpack_require__(3770);
|
|
1173
|
+
/* import */ var _flow_engine_flow_errors_js__rspack_import_9 = __webpack_require__(8542);
|
|
1174
|
+
/* import */ var _flow_engine_flow_types_js__rspack_import_10 = __webpack_require__(6256);
|
|
1175
|
+
/* import */ var _interfaces_definition_bundle_interface_js__rspack_import_21 = __webpack_require__(8835);
|
|
1176
|
+
/* import */ var _interfaces_flow_definition_interface_js__rspack_import_23 = __webpack_require__(9609);
|
|
1177
|
+
/* import */ var _definition_bundle_diff_js__rspack_import_11 = __webpack_require__(3801);
|
|
1178
|
+
/* import */ var _entity_builder_config_service_js__rspack_import_12 = __webpack_require__(4281);
|
|
1179
|
+
/* import */ var _entity_builder_datasource_provider_js__rspack_import_13 = __webpack_require__(424);
|
|
1180
|
+
/* import */ var _entity_permission_service_js__rspack_import_14 = __webpack_require__(1462);
|
|
1181
|
+
/* import */ var _flow_definition_service_js__rspack_import_15 = __webpack_require__(5229);
|
|
1182
|
+
/* import */ var _schema_dialect_adapter_service_js__rspack_import_16 = __webpack_require__(7259);
|
|
1183
|
+
/* import */ var _schema_evolution_service_js__rspack_import_17 = __webpack_require__(3606);
|
|
1184
|
+
/* import */ var _schema_sync_service_js__rspack_import_18 = __webpack_require__(3474);
|
|
1041
1185
|
function _ts_decorate(decorators, target, key, desc) {
|
|
1042
1186
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1043
1187
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -1077,16 +1221,20 @@ function _ts_param(paramIndex, decorator) {
|
|
|
1077
1221
|
|
|
1078
1222
|
|
|
1079
1223
|
|
|
1224
|
+
|
|
1225
|
+
|
|
1226
|
+
|
|
1227
|
+
|
|
1080
1228
|
|
|
1081
1229
|
|
|
1082
1230
|
|
|
1083
1231
|
|
|
1084
1232
|
/** The reasons a failed step gives besides its message: a change's blockers, a flow's validation errors. */ function failureDetails(error) {
|
|
1085
|
-
if (!(error instanceof
|
|
1233
|
+
if (!(error instanceof _nestjs_common__rspack_import_2.HttpException)) return [];
|
|
1086
1234
|
const response = error.getResponse();
|
|
1087
1235
|
if (typeof response !== 'object') return [];
|
|
1088
1236
|
const details = response.blockers ?? response.errors ?? [];
|
|
1089
|
-
return details.filter((d)=>typeof d?.messageKey === 'string').map((d)=>(0,
|
|
1237
|
+
return details.filter((d)=>typeof d?.messageKey === 'string').map((d)=>(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(d.messageKey, d.messageVariables));
|
|
1090
1238
|
}
|
|
1091
1239
|
/** Structural changes that, unpreviewed, may turn out to lose data (a type conversion, a column made required or unique, audit or soft delete switched off). */ const LOSSY_FIELD_CHANGES = [
|
|
1092
1240
|
'fieldType',
|
|
@@ -1105,21 +1253,21 @@ function mayLoseData(step) {
|
|
|
1105
1253
|
/**
|
|
1106
1254
|
* What was reviewed: the bundle, the options and every step (kind, subject, changes, and whether its
|
|
1107
1255
|
* preview loses data). Not the SQL or row counts, which change with every write and would refuse each apply.
|
|
1108
|
-
*/ function planChecksum(bundle,
|
|
1256
|
+
*/ function planChecksum(bundle, options, steps) {
|
|
1109
1257
|
const reviewed = steps.map((step)=>({
|
|
1110
1258
|
kind: step.kind,
|
|
1111
|
-
subject: (0,
|
|
1259
|
+
subject: (0,_definition_bundle_diff_js__rspack_import_11/* .bundleSubject */.bs)(step),
|
|
1112
1260
|
details: step.details,
|
|
1113
1261
|
destructive: step.preview?.destructive ?? null
|
|
1114
1262
|
}));
|
|
1115
|
-
return (0,
|
|
1263
|
+
return (0,node_crypto__rspack_import_3.createHash)('sha256').update((0,_definition_bundle_diff_js__rspack_import_11/* .canonicalJson */.dj)({
|
|
1116
1264
|
bundle,
|
|
1117
|
-
|
|
1265
|
+
...options,
|
|
1118
1266
|
steps: reviewed
|
|
1119
1267
|
})).digest('hex');
|
|
1120
1268
|
}
|
|
1121
|
-
const
|
|
1122
|
-
const
|
|
1269
|
+
/** One import at a time per database: two would plan against the same state and race each other's steps. */ const IMPORT_LOCK = 'eb_bundle_import';
|
|
1270
|
+
const newApiKey = ()=>`fk_${(0,node_crypto__rspack_import_3.randomBytes)(4).toString('hex')}_${(0,node_crypto__rspack_import_3.randomBytes)(16).toString('hex')}`;
|
|
1123
1271
|
const needsApiKey = (node)=>node?.type === 'trigger' && node.config?.['authMode'] === 'api_key';
|
|
1124
1272
|
/** The stored API keys of a flow's Request steps (published and draft), by step id. */ function storedApiKeys(flow) {
|
|
1125
1273
|
const keys = new Map();
|
|
@@ -1127,7 +1275,7 @@ const needsApiKey = (node)=>node?.type === 'trigger' && node.config?.['authMode'
|
|
|
1127
1275
|
...flow?.nodes ?? [],
|
|
1128
1276
|
...flow?.draft?.nodes ?? []
|
|
1129
1277
|
]){
|
|
1130
|
-
if (node?.type === 'trigger' && (0,
|
|
1278
|
+
if (node?.type === 'trigger' && (0,_flow_engine_flow_types_js__rspack_import_10/* .isStoredApiKey */.xA)(node.config?.['apiKey']) && !keys.has(node.id)) keys.set(node.id, node.config['apiKey']);
|
|
1131
1279
|
}
|
|
1132
1280
|
return keys;
|
|
1133
1281
|
}
|
|
@@ -1137,66 +1285,94 @@ class DefinitionBundleService {
|
|
|
1137
1285
|
schemaSync;
|
|
1138
1286
|
evolution;
|
|
1139
1287
|
flows;
|
|
1140
|
-
|
|
1288
|
+
dialect;
|
|
1289
|
+
actionRegistry;
|
|
1290
|
+
constructor(provider, config, schemaSync, evolution, flows, dialect, actionRegistry){
|
|
1141
1291
|
this.provider = provider;
|
|
1142
1292
|
this.config = config;
|
|
1143
1293
|
this.schemaSync = schemaSync;
|
|
1144
1294
|
this.evolution = evolution;
|
|
1145
1295
|
this.flows = flows;
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
return this.config.getBundleVariables();
|
|
1296
|
+
this.dialect = dialect;
|
|
1297
|
+
this.actionRegistry = actionRegistry;
|
|
1149
1298
|
}
|
|
1150
1299
|
// ── export ──────────────────────────────────────────────────────────────────────────
|
|
1151
1300
|
async export(dto) {
|
|
1152
1301
|
const current = await this.loadEntities();
|
|
1153
1302
|
const selected = dto.entityCodes ? current.filter((e)=>dto.entityCodes.includes(e.code)) : current;
|
|
1154
1303
|
// A DRAFT entity has no table where it is designed, so there is nothing to promote yet.
|
|
1155
|
-
const drafts = selected.filter((e)=>e.status ===
|
|
1156
|
-
const entities = selected.filter((e)=>e.status !==
|
|
1304
|
+
const drafts = selected.filter((e)=>e.status === _enums_entity_status_enum_js__rspack_import_19/* .EntityStatus.DRAFT */.c.DRAFT).toSorted((a, b)=>(0,_definition_bundle_diff_js__rspack_import_11/* .byCode */.VU)(a.code, b.code));
|
|
1305
|
+
const entities = selected.filter((e)=>e.status !== _enums_entity_status_enum_js__rspack_import_19/* .EntityStatus.DRAFT */.c.DRAFT).toSorted((a, b)=>(0,_definition_bundle_diff_js__rspack_import_11/* .byCode */.VU)(a.code, b.code)).map((entity)=>({
|
|
1157
1306
|
...entity,
|
|
1158
|
-
fields: entity.fields.toSorted((a, b)=>a.order - b.order || (0,
|
|
1307
|
+
fields: entity.fields.toSorted((a, b)=>a.order - b.order || (0,_definition_bundle_diff_js__rspack_import_11/* .byCode */.VU)(a.code, b.code))
|
|
1159
1308
|
}));
|
|
1160
|
-
const flowRepo = await this.provider.getRepository(
|
|
1309
|
+
const flowRepo = await this.provider.getRepository(_entities_flow_definition_entity_js__rspack_import_8/* .FlowDefinition */.G);
|
|
1161
1310
|
const rows = (await flowRepo.find({
|
|
1162
1311
|
where: dto.flowSlugs ? {
|
|
1163
|
-
slug: (0,
|
|
1312
|
+
slug: (0,typeorm__rspack_import_4.In)(dto.flowSlugs)
|
|
1164
1313
|
} : {}
|
|
1165
|
-
})).toSorted((a, b)=>(0,
|
|
1314
|
+
})).toSorted((a, b)=>(0,_definition_bundle_diff_js__rspack_import_11/* .byCode */.VU)(a.slug, b.slug));
|
|
1166
1315
|
const warnings = [
|
|
1167
|
-
...drafts.map((entity)=>(0,
|
|
1316
|
+
...drafts.map((entity)=>(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.ENTITY_DRAFT_SKIPPED */.iX.ENTITY_DRAFT_SKIPPED, {
|
|
1168
1317
|
entity: entity.code
|
|
1169
1318
|
})),
|
|
1170
|
-
...rows.filter((flow)=>!(0,
|
|
1319
|
+
...rows.filter((flow)=>!(0,_flow_definition_service_js__rspack_import_15/* .isPublished */.HF)(flow)).map((flow)=>(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.FLOW_UNPUBLISHED_SKIPPED */.iX.FLOW_UNPUBLISHED_SKIPPED, {
|
|
1171
1320
|
flow: flow.slug
|
|
1172
1321
|
}))
|
|
1173
1322
|
];
|
|
1174
|
-
const variables = this.
|
|
1175
|
-
const flows = rows.filter(
|
|
1176
|
-
const snapshot = (0,
|
|
1323
|
+
const variables = this.config.getBundleVariables();
|
|
1324
|
+
const flows = rows.filter(_flow_definition_service_js__rspack_import_15/* .isPublished */.HF).map((flow)=>{
|
|
1325
|
+
const snapshot = (0,_flow_definition_service_js__rspack_import_15/* .snapshotOf */.eY)(flow);
|
|
1177
1326
|
return {
|
|
1178
1327
|
...snapshot,
|
|
1179
1328
|
description: snapshot.description ?? null,
|
|
1180
|
-
nodes: (0,
|
|
1329
|
+
nodes: (0,_definition_bundle_diff_js__rspack_import_11/* .extractVariables */.lj)((0,_definition_bundle_diff_js__rspack_import_11/* .stripApiKeys */.dX)(snapshot.nodes ?? []), variables),
|
|
1181
1330
|
edges: snapshot.edges ?? []
|
|
1182
1331
|
};
|
|
1183
1332
|
});
|
|
1333
|
+
warnings.push(...this.leftBehind(entities, flows));
|
|
1334
|
+
for (const flow of flows){
|
|
1335
|
+
for (const { step, name } of (0,_definition_bundle_diff_js__rspack_import_11/* .writtenSecrets */.l6)(flow.nodes))warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.FLOW_SECRET_WRITTEN */.iX.FLOW_SECRET_WRITTEN, {
|
|
1336
|
+
flow: flow.slug,
|
|
1337
|
+
step,
|
|
1338
|
+
name
|
|
1339
|
+
}));
|
|
1340
|
+
}
|
|
1184
1341
|
// Keys sorted at every level: PostgreSQL and MySQL hand JSON columns back in different key orders.
|
|
1185
|
-
const bundle = JSON.parse((0,
|
|
1186
|
-
format:
|
|
1342
|
+
const bundle = JSON.parse((0,_definition_bundle_diff_js__rspack_import_11/* .canonicalJson */.dj)({
|
|
1343
|
+
format: _interfaces_definition_bundle_interface_js__rspack_import_21/* .DEFINITION_BUNDLE_FORMAT */.D,
|
|
1187
1344
|
version: (/* inlined export .DEFINITION_BUNDLE_VERSION */1),
|
|
1188
1345
|
entities,
|
|
1189
1346
|
flows
|
|
1190
1347
|
}));
|
|
1191
1348
|
return {
|
|
1192
1349
|
bundle,
|
|
1193
|
-
checksum: (0,
|
|
1350
|
+
checksum: (0,_definition_bundle_diff_js__rspack_import_11/* .bundleChecksum */.i9)(bundle),
|
|
1194
1351
|
warnings
|
|
1195
1352
|
};
|
|
1196
1353
|
}
|
|
1354
|
+
/** Relations and Call flow steps that reach outside the bundle: the environment importing it must already have their targets. */ leftBehind(entities, flows) {
|
|
1355
|
+
const entityCodes = new Set(entities.map((e)=>e.code));
|
|
1356
|
+
const slugs = new Set(flows.map((f)=>f.slug));
|
|
1357
|
+
const relations = entities.flatMap((entity)=>entity.fields.filter((f)=>f.fieldType === _enums_field_type_enum_js__rspack_import_22/* .FieldType.RELATION */.P.RELATION && !f.deprecated && f.relationTarget && !entityCodes.has(f.relationTarget)).map((f)=>(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.EXPORT_RELATION_LEFT_OUT */.iX.EXPORT_RELATION_LEFT_OUT, {
|
|
1358
|
+
entity: entity.code,
|
|
1359
|
+
field: f.code,
|
|
1360
|
+
target: f.relationTarget
|
|
1361
|
+
})));
|
|
1362
|
+
const calls = flows.flatMap((flow)=>[
|
|
1363
|
+
...new Set((0,_definition_bundle_diff_js__rspack_import_11/* .calledFlowSlugs */.Q5)(flow.nodes))
|
|
1364
|
+
].filter((slug)=>!slugs.has(slug)).toSorted(_definition_bundle_diff_js__rspack_import_11/* .byCode */.VU).map((called)=>(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.EXPORT_CALLED_FLOW_LEFT_OUT */.iX.EXPORT_CALLED_FLOW_LEFT_OUT, {
|
|
1365
|
+
flow: flow.slug,
|
|
1366
|
+
called
|
|
1367
|
+
})));
|
|
1368
|
+
return [
|
|
1369
|
+
...relations,
|
|
1370
|
+
...calls
|
|
1371
|
+
];
|
|
1372
|
+
}
|
|
1197
1373
|
/** Every entity of this environment with its fields, relations named by target code. */ async loadEntities() {
|
|
1198
|
-
const definitions = await (await this.provider.getRepository(
|
|
1199
|
-
const fields = await (await this.provider.getRepository(
|
|
1374
|
+
const definitions = await (await this.provider.getRepository(_entities_entity_definition_entity_js__rspack_import_6/* .EntityDefinition */.f)).find();
|
|
1375
|
+
const fields = await (await this.provider.getRepository(_entities_field_definition_entity_js__rspack_import_7/* .FieldDefinition */.c)).find();
|
|
1200
1376
|
const codeOf = new Map(definitions.map((d)=>[
|
|
1201
1377
|
d.id,
|
|
1202
1378
|
d.code
|
|
@@ -1237,10 +1413,12 @@ class DefinitionBundleService {
|
|
|
1237
1413
|
/** The plan, with what apply-import runs: the entity operations and the flows, in order. */ async buildPlan(dto, user) {
|
|
1238
1414
|
const bundle = dto.bundle;
|
|
1239
1415
|
const current = await this.loadEntities();
|
|
1240
|
-
const entityDiff = (0,
|
|
1416
|
+
const entityDiff = (0,_definition_bundle_diff_js__rspack_import_11/* .diffEntities */.zb)(bundle.entities, current, {
|
|
1241
1417
|
deprecateMissingFields: dto.deprecateMissingFields === true
|
|
1242
1418
|
});
|
|
1243
|
-
const flowDiff = await this.diffFlows(bundle.flows
|
|
1419
|
+
const flowDiff = await this.diffFlows(bundle.flows, {
|
|
1420
|
+
deactivateMissingFlows: dto.deactivateMissingFlows === true
|
|
1421
|
+
});
|
|
1244
1422
|
const existingCodes = new Set(current.map((e)=>e.code));
|
|
1245
1423
|
const steps = [];
|
|
1246
1424
|
for (const operation of entityDiff.operations){
|
|
@@ -1256,7 +1434,7 @@ class DefinitionBundleService {
|
|
|
1256
1434
|
warnings: [
|
|
1257
1435
|
...operation.warnings ?? [],
|
|
1258
1436
|
...dependent ? [
|
|
1259
|
-
(0,
|
|
1437
|
+
(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.STEP_AFTER_EARLIER */.iX.STEP_AFTER_EARLIER)
|
|
1260
1438
|
] : []
|
|
1261
1439
|
],
|
|
1262
1440
|
blockers: []
|
|
@@ -1266,13 +1444,15 @@ class DefinitionBundleService {
|
|
|
1266
1444
|
step.preview = await this.previewEntityStep(operation, current, user);
|
|
1267
1445
|
step.blockers.push(...step.preview.blockers);
|
|
1268
1446
|
} catch (error) {
|
|
1269
|
-
step.blockers.push((0,
|
|
1447
|
+
step.blockers.push((0,_flow_engine_flow_errors_js__rspack_import_9/* .errorRef */.O$)(error));
|
|
1270
1448
|
}
|
|
1271
1449
|
}
|
|
1272
1450
|
steps.push(step);
|
|
1273
1451
|
}
|
|
1274
1452
|
const schemaChanges = entityDiff.operations.length > 0;
|
|
1275
|
-
|
|
1453
|
+
// Flows switched off run last, callers first: each is still running when the flows that call it are checked.
|
|
1454
|
+
const importedSlugs = new Set(flowDiff.planned.filter((p)=>p.kind !== 'deactivate_flow').map((p)=>p.flow.slug));
|
|
1455
|
+
const savedFlows = [];
|
|
1276
1456
|
for (const planned of flowDiff.planned){
|
|
1277
1457
|
const step = {
|
|
1278
1458
|
kind: planned.kind,
|
|
@@ -1286,22 +1466,30 @@ class DefinitionBundleService {
|
|
|
1286
1466
|
...planned.blockers
|
|
1287
1467
|
]
|
|
1288
1468
|
};
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1469
|
+
if (planned.kind !== 'deactivate_flow') savedFlows.push([
|
|
1470
|
+
step,
|
|
1471
|
+
planned.flow
|
|
1472
|
+
]);
|
|
1473
|
+
// Switching a flow off saves it too: a flow with a code step needs that permission from whoever imports it, as from whoever saves it.
|
|
1474
|
+
await this.flows.assertMayAuthor((0,_flow_definition_service_js__rspack_import_15/* .toFlowSettings */.RK)(planned.flow), user).catch((error)=>step.blockers.push((0,_flow_engine_flow_errors_js__rspack_import_9/* .errorRef */.O$)(error)));
|
|
1475
|
+
const dependsOnImport = schemaChanges || (0,_definition_bundle_diff_js__rspack_import_11/* .calledFlowSlugs */.Q5)(planned.flow.nodes).some((slug)=>importedSlugs.has(slug));
|
|
1292
1476
|
if (dependsOnImport) {
|
|
1293
|
-
step.warnings.push((0,
|
|
1477
|
+
step.warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.FLOWS_CHECKED_ON_APPLY */.iX.FLOWS_CHECKED_ON_APPLY));
|
|
1294
1478
|
} else if (!step.blockers.length) {
|
|
1295
|
-
const { errors, warnings } = await this.flows.validate((0,
|
|
1479
|
+
const { errors, warnings } = await this.flows.validate((0,_flow_definition_service_js__rspack_import_15/* .toFlowSettings */.RK)(planned.flow));
|
|
1296
1480
|
step.blockers.push(...errors);
|
|
1297
1481
|
step.warnings.push(...warnings);
|
|
1298
1482
|
}
|
|
1299
1483
|
steps.push(step);
|
|
1300
1484
|
}
|
|
1301
|
-
|
|
1485
|
+
await this.addPermissionWarnings(steps, savedFlows);
|
|
1486
|
+
const checksum = (0,_definition_bundle_diff_js__rspack_import_11/* .bundleChecksum */.i9)(bundle);
|
|
1302
1487
|
const plan = {
|
|
1303
1488
|
checksum,
|
|
1304
|
-
planChecksum: planChecksum(checksum,
|
|
1489
|
+
planChecksum: planChecksum(checksum, {
|
|
1490
|
+
deprecateMissingFields: dto.deprecateMissingFields === true,
|
|
1491
|
+
deactivateMissingFlows: dto.deactivateMissingFlows === true
|
|
1492
|
+
}, steps),
|
|
1305
1493
|
steps,
|
|
1306
1494
|
unchanged: {
|
|
1307
1495
|
entities: entityDiff.unchangedEntities,
|
|
@@ -1325,6 +1513,44 @@ class DefinitionBundleService {
|
|
|
1325
1513
|
flows: flowDiff.planned
|
|
1326
1514
|
};
|
|
1327
1515
|
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Permissions are IAM data, never promoted: an import only creates the codes of new entities and of
|
|
1518
|
+
* flows that ask for their execute permission, and no role has those here yet. A flow that checks a
|
|
1519
|
+
* code this environment does not have (and the import does not create) refuses every caller there.
|
|
1520
|
+
*/ async addPermissionWarnings(steps, savedFlows) {
|
|
1521
|
+
if (!this.actionRegistry?.findMissingCodes) return;
|
|
1522
|
+
const createdBy = new Map();
|
|
1523
|
+
for (const step of steps.filter((s)=>s.kind === 'create_entity'))for (const code of (0,_entity_permission_service_js__rspack_import_14/* .entityPermissionCodes */.Z)(step.entityCode))createdBy.set(code, step);
|
|
1524
|
+
for (const [step, flow] of savedFlows)if ((0,_flow_engine_flow_types_js__rspack_import_10/* .flowEndpoints */.Xr)(flow).some(_flow_definition_service_js__rspack_import_15/* .asksExecutePermission */.b$)) createdBy.set((0,_flow_definition_service_js__rspack_import_15/* .defaultFlowPermissionCode */.Er)(flow.slug), step);
|
|
1525
|
+
const checked = savedFlows.map(([step, flow])=>[
|
|
1526
|
+
step,
|
|
1527
|
+
(0,_definition_bundle_diff_js__rspack_import_11/* .permissionCodes */.QJ)(flow).filter((code)=>!code.includes('*'))
|
|
1528
|
+
]);
|
|
1529
|
+
const asked = [
|
|
1530
|
+
...new Set([
|
|
1531
|
+
...createdBy.keys(),
|
|
1532
|
+
...checked.flatMap(([, codes])=>codes)
|
|
1533
|
+
])
|
|
1534
|
+
];
|
|
1535
|
+
if (!asked.length) return;
|
|
1536
|
+
const missing = new Set(await this.actionRegistry.findMissingCodes(asked));
|
|
1537
|
+
const ungranted = new Map();
|
|
1538
|
+
for (const [code, step] of createdBy)if (missing.has(code)) ungranted.set(step, [
|
|
1539
|
+
...ungranted.get(step) ?? [],
|
|
1540
|
+
code
|
|
1541
|
+
]);
|
|
1542
|
+
for (const [step, codes] of ungranted)step.warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.PERMISSIONS_TO_GRANT */.iX.PERMISSIONS_TO_GRANT, {
|
|
1543
|
+
subject: (0,_definition_bundle_diff_js__rspack_import_11/* .bundleSubject */.bs)(step),
|
|
1544
|
+
codes: codes.join(', ')
|
|
1545
|
+
}));
|
|
1546
|
+
for (const [step, codes] of checked){
|
|
1547
|
+
const unknown = codes.filter((code)=>missing.has(code) && !createdBy.has(code));
|
|
1548
|
+
if (unknown.length) step.warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.FLOW_PERMISSION_UNKNOWN */.iX.FLOW_PERMISSION_UNKNOWN, {
|
|
1549
|
+
flow: step.flowSlug,
|
|
1550
|
+
codes: unknown.join(', ')
|
|
1551
|
+
}));
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1328
1554
|
/** A relation to an entity this import creates: its id is only known once the entity exists. */ relationNotYetCreated(operation, existingCodes) {
|
|
1329
1555
|
const target = operation.field?.relationTarget ?? operation.changes?.['relationTarget'];
|
|
1330
1556
|
return !!target && !existingCodes.has(target);
|
|
@@ -1333,25 +1559,15 @@ class DefinitionBundleService {
|
|
|
1333
1559
|
if (operation.kind === 'create_entity') return this.schemaSync.planCreateEntity(this.createRequest(operation.entity), user);
|
|
1334
1560
|
return this.evolution.plan(this.changeRequest(operation, current), user);
|
|
1335
1561
|
}
|
|
1336
|
-
async diffFlows(bundleFlows) {
|
|
1337
|
-
const repo = await this.provider.getRepository(
|
|
1562
|
+
async diffFlows(bundleFlows, options) {
|
|
1563
|
+
const repo = await this.provider.getRepository(_entities_flow_definition_entity_js__rspack_import_8/* .FlowDefinition */.G);
|
|
1338
1564
|
const existing = await repo.find();
|
|
1339
1565
|
const bySlug = new Map(existing.map((flow)=>[
|
|
1340
1566
|
flow.slug,
|
|
1341
1567
|
flow
|
|
1342
1568
|
]));
|
|
1343
1569
|
const slugs = bundleFlows.map((f)=>f.slug);
|
|
1344
|
-
const
|
|
1345
|
-
select: {
|
|
1346
|
-
id: true,
|
|
1347
|
-
slug: true
|
|
1348
|
-
},
|
|
1349
|
-
where: {
|
|
1350
|
-
slug: (0,typeorm__rspack_import_3.In)(slugs)
|
|
1351
|
-
},
|
|
1352
|
-
withDeleted: true
|
|
1353
|
-
})).filter((f)=>!bySlug.has(f.slug)).map((f)=>f.slug)) : new Set();
|
|
1354
|
-
const variables = this.variables();
|
|
1570
|
+
const variables = this.config.getBundleVariables();
|
|
1355
1571
|
const result = {
|
|
1356
1572
|
planned: [],
|
|
1357
1573
|
unchanged: 0,
|
|
@@ -1360,31 +1576,34 @@ class DefinitionBundleService {
|
|
|
1360
1576
|
};
|
|
1361
1577
|
const seen = new Set();
|
|
1362
1578
|
for (const slug of slugs){
|
|
1363
|
-
if (seen.has(slug)) result.blockers.push((0,
|
|
1579
|
+
if (seen.has(slug)) result.blockers.push((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.DUPLICATE_FLOW */.iX.DUPLICATE_FLOW, {
|
|
1364
1580
|
flow: slug
|
|
1365
1581
|
}));
|
|
1366
1582
|
seen.add(slug);
|
|
1367
1583
|
}
|
|
1368
|
-
for (const bundleFlow of (0,
|
|
1369
|
-
const { nodes, missing } = (0,
|
|
1584
|
+
for (const bundleFlow of (0,_definition_bundle_diff_js__rspack_import_11/* .orderFlows */.qG)(bundleFlows)){
|
|
1585
|
+
const { nodes, missing } = (0,_definition_bundle_diff_js__rspack_import_11/* .applyVariables */.gT)(bundleFlow.nodes ?? [], variables);
|
|
1370
1586
|
const flow = {
|
|
1371
1587
|
...bundleFlow,
|
|
1372
1588
|
nodes,
|
|
1373
1589
|
edges: bundleFlow.edges ?? []
|
|
1374
1590
|
};
|
|
1375
|
-
const blockers = missing.map((name)=>(0,
|
|
1591
|
+
const blockers = missing.map((name)=>(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.VARIABLE_MISSING */.iX.VARIABLE_MISSING, {
|
|
1376
1592
|
name,
|
|
1377
1593
|
flow: flow.slug
|
|
1378
1594
|
}));
|
|
1379
1595
|
const target = bySlug.get(flow.slug);
|
|
1380
|
-
if (!target && deleted.has(flow.slug)) blockers.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.FLOW_SLUG_DELETED */.iX.FLOW_SLUG_DELETED, {
|
|
1381
|
-
flow: flow.slug
|
|
1382
|
-
}));
|
|
1383
1596
|
const keys = storedApiKeys(target);
|
|
1384
|
-
const warnings = flow.nodes.filter((node)=>needsApiKey(node) && !keys.has(node.id)).map((node)=>(0,
|
|
1597
|
+
const warnings = flow.nodes.filter((node)=>needsApiKey(node) && !keys.has(node.id)).map((node)=>(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.FLOW_API_KEY_GENERATED */.iX.FLOW_API_KEY_GENERATED, {
|
|
1385
1598
|
flow: flow.slug,
|
|
1386
|
-
path: triggerPath(node) ?? ''
|
|
1599
|
+
path: (0,_flow_engine_flow_types_js__rspack_import_10/* .triggerPath */.um)(node) ?? ''
|
|
1387
1600
|
}));
|
|
1601
|
+
// Read before the variables are filled in: an id this environment provides through `${var:NAME}` is not fixed.
|
|
1602
|
+
const ids = (0,_definition_bundle_diff_js__rspack_import_11/* .fixedIds */.f7)(bundleFlow.nodes ?? []);
|
|
1603
|
+
if (ids.length) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.FLOW_FIXED_IDS */.iX.FLOW_FIXED_IDS, {
|
|
1604
|
+
flow: flow.slug,
|
|
1605
|
+
ids: ids.join(', ')
|
|
1606
|
+
}));
|
|
1388
1607
|
if (!target) {
|
|
1389
1608
|
result.planned.push({
|
|
1390
1609
|
kind: 'create_flow',
|
|
@@ -1396,13 +1615,13 @@ class DefinitionBundleService {
|
|
|
1396
1615
|
});
|
|
1397
1616
|
continue;
|
|
1398
1617
|
}
|
|
1399
|
-
const live = (0,
|
|
1400
|
-
const changed =
|
|
1401
|
-
if (!changed.length && (0,
|
|
1618
|
+
const live = (0,_flow_definition_service_js__rspack_import_15/* .snapshotOf */.eY)(target);
|
|
1619
|
+
const changed = _interfaces_flow_definition_interface_js__rspack_import_23/* .FLOW_VERSIONED_FIELDS.filter */.v.filter((key)=>key === 'nodes' ? (0,_definition_bundle_diff_js__rspack_import_11/* .canonicalJson */.dj)((0,_definition_bundle_diff_js__rspack_import_11/* .stripApiKeys */.dX)(live.nodes ?? [])) !== (0,_definition_bundle_diff_js__rspack_import_11/* .canonicalJson */.dj)((0,_definition_bundle_diff_js__rspack_import_11/* .stripApiKeys */.dX)(flow.nodes)) : (0,_definition_bundle_diff_js__rspack_import_11/* .canonicalJson */.dj)(live[key] ?? null) !== (0,_definition_bundle_diff_js__rspack_import_11/* .canonicalJson */.dj)(flow[key] ?? null));
|
|
1620
|
+
if (!changed.length && (0,_flow_definition_service_js__rspack_import_15/* .isPublished */.HF)(target) && !blockers.length) {
|
|
1402
1621
|
result.unchanged++;
|
|
1403
1622
|
continue;
|
|
1404
1623
|
}
|
|
1405
|
-
if (target.draft) warnings.push((0,
|
|
1624
|
+
if (target.draft) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.FLOW_DRAFT_REPLACED */.iX.FLOW_DRAFT_REPLACED, {
|
|
1406
1625
|
flow: flow.slug
|
|
1407
1626
|
}));
|
|
1408
1627
|
result.planned.push({
|
|
@@ -1416,10 +1635,38 @@ class DefinitionBundleService {
|
|
|
1416
1635
|
blockers
|
|
1417
1636
|
});
|
|
1418
1637
|
}
|
|
1419
|
-
|
|
1638
|
+
const missing = existing.filter((flow)=>!seen.has(flow.slug));
|
|
1639
|
+
const deactivated = options.deactivateMissingFlows ? missing.filter((flow)=>flow.isActive && (0,_flow_definition_service_js__rspack_import_15/* .isPublished */.HF)(flow)) : [];
|
|
1640
|
+
for (const extra of missing.filter((flow)=>!deactivated.includes(flow)))result.extras.push({
|
|
1420
1641
|
kind: 'flow',
|
|
1421
1642
|
flowSlug: extra.slug
|
|
1422
1643
|
});
|
|
1644
|
+
// Callers first: a flow is switched off only once the live flows that call it are.
|
|
1645
|
+
for (const live of (0,_definition_bundle_diff_js__rspack_import_11/* .orderFlows */.qG)(deactivated.map((flow)=>(0,_flow_definition_service_js__rspack_import_15/* .snapshotOf */.eY)(flow))).toReversed()){
|
|
1646
|
+
const target = bySlug.get(live.slug);
|
|
1647
|
+
const callers = bundleFlows.filter((flow)=>flow.isActive && (0,_definition_bundle_diff_js__rspack_import_11/* .calledFlowSlugs */.Q5)(flow.nodes ?? []).includes(live.slug)).map((flow)=>flow.slug);
|
|
1648
|
+
result.planned.push({
|
|
1649
|
+
kind: 'deactivate_flow',
|
|
1650
|
+
flow: live,
|
|
1651
|
+
existingId: target.id,
|
|
1652
|
+
details: {
|
|
1653
|
+
changes: [
|
|
1654
|
+
'isActive'
|
|
1655
|
+
]
|
|
1656
|
+
},
|
|
1657
|
+
warnings: target.draft ? [
|
|
1658
|
+
(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.FLOW_DRAFT_REPLACED */.iX.FLOW_DRAFT_REPLACED, {
|
|
1659
|
+
flow: live.slug
|
|
1660
|
+
})
|
|
1661
|
+
] : [],
|
|
1662
|
+
blockers: callers.length ? [
|
|
1663
|
+
(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.FLOW_DEACTIVATE_CALLED */.iX.FLOW_DEACTIVATE_CALLED, {
|
|
1664
|
+
flow: live.slug,
|
|
1665
|
+
callers: callers.toSorted(_definition_bundle_diff_js__rspack_import_11/* .byCode */.VU).join(', ')
|
|
1666
|
+
})
|
|
1667
|
+
] : []
|
|
1668
|
+
});
|
|
1669
|
+
}
|
|
1423
1670
|
return result;
|
|
1424
1671
|
}
|
|
1425
1672
|
// ── requests for the designer's services ────────────────────────────────────────────
|
|
@@ -1459,7 +1706,7 @@ class DefinitionBundleService {
|
|
|
1459
1706
|
switch(operation.kind){
|
|
1460
1707
|
case 'add_field':
|
|
1461
1708
|
return {
|
|
1462
|
-
action:
|
|
1709
|
+
action: _dtos_schema_change_dto_js__rspack_import_5/* .SchemaChangeAction.ADD_FIELD */.M3.ADD_FIELD,
|
|
1463
1710
|
entityDefinitionId: entity?.id,
|
|
1464
1711
|
field: this.fieldSpec(operation.field, idOf(operation.field.relationTarget))
|
|
1465
1712
|
};
|
|
@@ -1471,24 +1718,24 @@ class DefinitionBundleService {
|
|
|
1471
1718
|
relationTargetEntityId: idOf(relationTarget) ?? null
|
|
1472
1719
|
});
|
|
1473
1720
|
return {
|
|
1474
|
-
action:
|
|
1721
|
+
action: _dtos_schema_change_dto_js__rspack_import_5/* .SchemaChangeAction.UPDATE_FIELD */.M3.UPDATE_FIELD,
|
|
1475
1722
|
fieldDefinitionId: operation.targetFieldId,
|
|
1476
1723
|
changes
|
|
1477
1724
|
};
|
|
1478
1725
|
}
|
|
1479
1726
|
case 'deprecate_field':
|
|
1480
1727
|
return {
|
|
1481
|
-
action:
|
|
1728
|
+
action: _dtos_schema_change_dto_js__rspack_import_5/* .SchemaChangeAction.DEPRECATE_FIELD */.M3.DEPRECATE_FIELD,
|
|
1482
1729
|
fieldDefinitionId: operation.targetFieldId
|
|
1483
1730
|
};
|
|
1484
1731
|
case 'restore_field':
|
|
1485
1732
|
return {
|
|
1486
|
-
action:
|
|
1733
|
+
action: _dtos_schema_change_dto_js__rspack_import_5/* .SchemaChangeAction.RESTORE_FIELD */.M3.RESTORE_FIELD,
|
|
1487
1734
|
fieldDefinitionId: operation.targetFieldId
|
|
1488
1735
|
};
|
|
1489
1736
|
default:
|
|
1490
1737
|
return {
|
|
1491
|
-
action:
|
|
1738
|
+
action: _dtos_schema_change_dto_js__rspack_import_5/* .SchemaChangeAction.UPDATE_ENTITY */.M3.UPDATE_ENTITY,
|
|
1492
1739
|
entityDefinitionId: entity?.id,
|
|
1493
1740
|
changes: operation.changes
|
|
1494
1741
|
};
|
|
@@ -1496,21 +1743,44 @@ class DefinitionBundleService {
|
|
|
1496
1743
|
}
|
|
1497
1744
|
// ── apply ───────────────────────────────────────────────────────────────────────────
|
|
1498
1745
|
async applyImport(dto, user) {
|
|
1499
|
-
const checksum = (0,
|
|
1746
|
+
const checksum = (0,_definition_bundle_diff_js__rspack_import_11/* .bundleChecksum */.i9)(dto.bundle);
|
|
1500
1747
|
if (dto.expectedChecksum && dto.expectedChecksum !== checksum) {
|
|
1501
|
-
throw new
|
|
1748
|
+
throw new _nestjs_common__rspack_import_2.ConflictException({
|
|
1502
1749
|
message: 'The bundle is not the one that was reviewed. Plan the import again.',
|
|
1503
|
-
messageKey:
|
|
1750
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.CHECKSUM_MISMATCH */.iX.CHECKSUM_MISMATCH,
|
|
1504
1751
|
messageVariables: {
|
|
1505
1752
|
checksum
|
|
1506
1753
|
}
|
|
1507
1754
|
});
|
|
1508
1755
|
}
|
|
1756
|
+
return this.withImportLock(()=>this.runImport(dto, user));
|
|
1757
|
+
}
|
|
1758
|
+
/** Held on a connection of its own for the whole import (plan and every step), released before that connection goes back to the pool. */ async withImportLock(fn) {
|
|
1759
|
+
const driver = await this.provider.getDriver();
|
|
1760
|
+
const qr = await this.provider.getQueryRunner();
|
|
1761
|
+
try {
|
|
1762
|
+
await qr.connect();
|
|
1763
|
+
if (!await this.dialect.tryAcquireSessionLock(qr, IMPORT_LOCK, driver)) {
|
|
1764
|
+
throw new _nestjs_common__rspack_import_2.ConflictException({
|
|
1765
|
+
message: 'Another import is running in this environment. Try again when it has finished.',
|
|
1766
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.IMPORT_IN_PROGRESS */.iX.IMPORT_IN_PROGRESS
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1769
|
+
try {
|
|
1770
|
+
return await fn();
|
|
1771
|
+
} finally{
|
|
1772
|
+
await this.dialect.releaseSessionLock(qr, IMPORT_LOCK, driver).catch(()=>undefined);
|
|
1773
|
+
}
|
|
1774
|
+
} finally{
|
|
1775
|
+
await qr.release().catch(()=>undefined);
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
async runImport(dto, user) {
|
|
1509
1779
|
const { plan, operations, flows } = await this.buildPlan(dto, user);
|
|
1510
1780
|
if (dto.expectedPlanChecksum && dto.expectedPlanChecksum !== plan.planChecksum) {
|
|
1511
|
-
throw new
|
|
1781
|
+
throw new _nestjs_common__rspack_import_2.ConflictException({
|
|
1512
1782
|
message: 'The plan changed since it was reviewed. Plan the import again.',
|
|
1513
|
-
messageKey:
|
|
1783
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.PLAN_CHANGED */.iX.PLAN_CHANGED,
|
|
1514
1784
|
messageVariables: {
|
|
1515
1785
|
planChecksum: plan.planChecksum
|
|
1516
1786
|
}
|
|
@@ -1523,33 +1793,33 @@ class DefinitionBundleService {
|
|
|
1523
1793
|
...b
|
|
1524
1794
|
})),
|
|
1525
1795
|
...plan.steps.flatMap((s)=>s.blockers.map((b)=>({
|
|
1526
|
-
field: (0,
|
|
1796
|
+
field: (0,_definition_bundle_diff_js__rspack_import_11/* .bundleSubject */.bs)(s),
|
|
1527
1797
|
...b
|
|
1528
1798
|
})))
|
|
1529
1799
|
];
|
|
1530
1800
|
if (blockers.length) {
|
|
1531
|
-
throw new
|
|
1801
|
+
throw new _nestjs_common__rspack_import_2.ConflictException({
|
|
1532
1802
|
message: 'The import is blocked. Plan it again to see why.',
|
|
1533
|
-
messageKey:
|
|
1803
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.APPLY_BLOCKED */.iX.APPLY_BLOCKED,
|
|
1534
1804
|
errors: blockers
|
|
1535
1805
|
});
|
|
1536
1806
|
}
|
|
1537
1807
|
if (plan.mayLoseData && dto.confirm !== true) {
|
|
1538
1808
|
const lossy = plan.steps.filter((s)=>s.preview?.destructive || !s.preview && mayLoseData(s)).map((s)=>({
|
|
1539
|
-
field: (0,
|
|
1540
|
-
messageKey:
|
|
1809
|
+
field: (0,_definition_bundle_diff_js__rspack_import_11/* .bundleSubject */.bs)(s),
|
|
1810
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.CONFIRM_REQUIRED */.iX.CONFIRM_REQUIRED
|
|
1541
1811
|
}));
|
|
1542
|
-
throw new
|
|
1812
|
+
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
1543
1813
|
message: 'The import loses data or information. Review the plan and resend with confirm: true.',
|
|
1544
|
-
messageKey:
|
|
1814
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.CONFIRM_REQUIRED */.iX.CONFIRM_REQUIRED,
|
|
1545
1815
|
errors: lossy
|
|
1546
1816
|
});
|
|
1547
1817
|
}
|
|
1548
1818
|
// A confirmation covers the steps that were reviewed, never ones the environment has grown since.
|
|
1549
1819
|
if (plan.mayLoseData && !dto.expectedPlanChecksum) {
|
|
1550
|
-
throw new
|
|
1820
|
+
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
1551
1821
|
message: 'Send the planChecksum of the reviewed plan as expectedPlanChecksum to confirm it.',
|
|
1552
|
-
messageKey:
|
|
1822
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .BUNDLE_MESSAGES.PLAN_CHECKSUM_REQUIRED */.iX.PLAN_CHECKSUM_REQUIRED
|
|
1553
1823
|
});
|
|
1554
1824
|
}
|
|
1555
1825
|
const result = {
|
|
@@ -1577,7 +1847,7 @@ class DefinitionBundleService {
|
|
|
1577
1847
|
result.steps.push({
|
|
1578
1848
|
...step,
|
|
1579
1849
|
status: 'failed',
|
|
1580
|
-
error: (0,
|
|
1850
|
+
error: (0,_flow_engine_flow_errors_js__rspack_import_9/* .errorRef */.O$)(error),
|
|
1581
1851
|
...reasons.length ? {
|
|
1582
1852
|
blockers: reasons
|
|
1583
1853
|
} : {}
|
|
@@ -1608,7 +1878,7 @@ class DefinitionBundleService {
|
|
|
1608
1878
|
if (operation.kind === 'create_entity') {
|
|
1609
1879
|
const entity = operation.entity;
|
|
1610
1880
|
await this.schemaSync.createEntity(this.createRequest(entity), user, {
|
|
1611
|
-
entityId: await this.idIsFree(
|
|
1881
|
+
entityId: await this.idIsFree(_entities_entity_definition_entity_js__rspack_import_6/* .EntityDefinition */.f, entity.id) ? entity.id : undefined,
|
|
1612
1882
|
fieldIds: Object.fromEntries(await this.freeFieldIds(entity.fields))
|
|
1613
1883
|
});
|
|
1614
1884
|
return;
|
|
@@ -1617,7 +1887,7 @@ class DefinitionBundleService {
|
|
|
1617
1887
|
...this.changeRequest(operation, current),
|
|
1618
1888
|
confirm
|
|
1619
1889
|
};
|
|
1620
|
-
const fieldId = operation.kind === 'add_field' && await this.idIsFree(
|
|
1890
|
+
const fieldId = operation.kind === 'add_field' && await this.idIsFree(_entities_field_definition_entity_js__rspack_import_7/* .FieldDefinition */.c, operation.field.id) ? operation.field.id : undefined;
|
|
1621
1891
|
await this.evolution.apply(request, user, {
|
|
1622
1892
|
fieldId
|
|
1623
1893
|
});
|
|
@@ -1632,12 +1902,12 @@ class DefinitionBundleService {
|
|
|
1632
1902
|
}
|
|
1633
1903
|
async freeFieldIds(fields) {
|
|
1634
1904
|
if (!fields.length) return [];
|
|
1635
|
-
const taken = new Set((await (await this.provider.getRepository(
|
|
1905
|
+
const taken = new Set((await (await this.provider.getRepository(_entities_field_definition_entity_js__rspack_import_7/* .FieldDefinition */.c)).find({
|
|
1636
1906
|
select: {
|
|
1637
1907
|
id: true
|
|
1638
1908
|
},
|
|
1639
1909
|
where: {
|
|
1640
|
-
id: (0,
|
|
1910
|
+
id: (0,typeorm__rspack_import_4.In)(fields.map((f)=>f.id))
|
|
1641
1911
|
},
|
|
1642
1912
|
withDeleted: true
|
|
1643
1913
|
})).map((f)=>f.id));
|
|
@@ -1647,6 +1917,7 @@ class DefinitionBundleService {
|
|
|
1647
1917
|
]);
|
|
1648
1918
|
}
|
|
1649
1919
|
/** Saves the flow (a Request step keeps this environment's API key, or gets a new one shown once) and publishes it. */ async applyFlowStep(planned, note, apiKeys, user) {
|
|
1920
|
+
if (planned.kind === 'deactivate_flow') return this.deactivateFlow(planned.existingId, note, user);
|
|
1650
1921
|
const existing = planned.existingId ? await this.flows.findOrFail(planned.existingId) : undefined;
|
|
1651
1922
|
const keys = storedApiKeys(existing);
|
|
1652
1923
|
const generated = [];
|
|
@@ -1664,7 +1935,7 @@ class DefinitionBundleService {
|
|
|
1664
1935
|
generated.push({
|
|
1665
1936
|
flowSlug: planned.flow.slug,
|
|
1666
1937
|
nodeId: node.id,
|
|
1667
|
-
path: triggerPath(node),
|
|
1938
|
+
path: (0,_flow_engine_flow_types_js__rspack_import_10/* .triggerPath */.um)(node),
|
|
1668
1939
|
key
|
|
1669
1940
|
});
|
|
1670
1941
|
return {
|
|
@@ -1688,23 +1959,38 @@ class DefinitionBundleService {
|
|
|
1688
1959
|
apiKeys.push(...generated);
|
|
1689
1960
|
await this.flows.publish(id, note, user);
|
|
1690
1961
|
}
|
|
1962
|
+
/** Publishes the live flow switched off; an unpublished draft is replaced, never published along with it. */ async deactivateFlow(id, note, user) {
|
|
1963
|
+
const live = (0,_flow_definition_service_js__rspack_import_15/* .snapshotOf */.eY)(await this.flows.findOrFail(id));
|
|
1964
|
+
await this.flows.update({
|
|
1965
|
+
...live,
|
|
1966
|
+
description: live.description ?? undefined,
|
|
1967
|
+
isActive: false,
|
|
1968
|
+
id
|
|
1969
|
+
}, user);
|
|
1970
|
+
await this.flows.publish(id, note, user);
|
|
1971
|
+
}
|
|
1691
1972
|
}
|
|
1692
1973
|
DefinitionBundleService = _ts_decorate([
|
|
1693
|
-
(0,
|
|
1694
|
-
scope:
|
|
1974
|
+
(0,_nestjs_common__rspack_import_2.Injectable)({
|
|
1975
|
+
scope: _nestjs_common__rspack_import_2.Scope.REQUEST
|
|
1695
1976
|
}),
|
|
1696
|
-
_ts_param(0, (0,
|
|
1697
|
-
_ts_param(1, (0,
|
|
1698
|
-
_ts_param(2, (0,
|
|
1699
|
-
_ts_param(3, (0,
|
|
1700
|
-
_ts_param(4, (0,
|
|
1977
|
+
_ts_param(0, (0,_nestjs_common__rspack_import_2.Inject)(_entity_builder_datasource_provider_js__rspack_import_13/* .EntityBuilderDataSourceProvider */.D)),
|
|
1978
|
+
_ts_param(1, (0,_nestjs_common__rspack_import_2.Inject)(_entity_builder_config_service_js__rspack_import_12/* .EntityBuilderConfigService */.E)),
|
|
1979
|
+
_ts_param(2, (0,_nestjs_common__rspack_import_2.Inject)(_schema_sync_service_js__rspack_import_18/* .SchemaSyncService */.W)),
|
|
1980
|
+
_ts_param(3, (0,_nestjs_common__rspack_import_2.Inject)(_schema_evolution_service_js__rspack_import_17/* .SchemaEvolutionService */._)),
|
|
1981
|
+
_ts_param(4, (0,_nestjs_common__rspack_import_2.Inject)(_flow_definition_service_js__rspack_import_15/* .FlowDefinitionService */.Tk)),
|
|
1982
|
+
_ts_param(5, (0,_nestjs_common__rspack_import_2.Inject)(_schema_dialect_adapter_service_js__rspack_import_16/* .SchemaDialectAdapterService */.I)),
|
|
1983
|
+
_ts_param(6, (0,_nestjs_common__rspack_import_2.Optional)()),
|
|
1984
|
+
_ts_param(6, (0,_nestjs_common__rspack_import_2.Inject)(_flusys_nestjs_shared_interfaces__rspack_import_0.PERMISSION_ACTION_REGISTRY)),
|
|
1701
1985
|
_ts_metadata("design:type", Function),
|
|
1702
1986
|
_ts_metadata("design:paramtypes", [
|
|
1703
|
-
typeof
|
|
1704
|
-
typeof
|
|
1705
|
-
typeof
|
|
1706
|
-
typeof
|
|
1707
|
-
typeof
|
|
1987
|
+
typeof _entity_builder_datasource_provider_js__rspack_import_13/* .EntityBuilderDataSourceProvider */.D === "undefined" ? Object : _entity_builder_datasource_provider_js__rspack_import_13/* .EntityBuilderDataSourceProvider */.D,
|
|
1988
|
+
typeof _entity_builder_config_service_js__rspack_import_12/* .EntityBuilderConfigService */.E === "undefined" ? Object : _entity_builder_config_service_js__rspack_import_12/* .EntityBuilderConfigService */.E,
|
|
1989
|
+
typeof _schema_sync_service_js__rspack_import_18/* .SchemaSyncService */.W === "undefined" ? Object : _schema_sync_service_js__rspack_import_18/* .SchemaSyncService */.W,
|
|
1990
|
+
typeof _schema_evolution_service_js__rspack_import_17/* .SchemaEvolutionService */._ === "undefined" ? Object : _schema_evolution_service_js__rspack_import_17/* .SchemaEvolutionService */._,
|
|
1991
|
+
typeof _flow_definition_service_js__rspack_import_15/* .FlowDefinitionService */.Tk === "undefined" ? Object : _flow_definition_service_js__rspack_import_15/* .FlowDefinitionService */.Tk,
|
|
1992
|
+
typeof _schema_dialect_adapter_service_js__rspack_import_16/* .SchemaDialectAdapterService */.I === "undefined" ? Object : _schema_dialect_adapter_service_js__rspack_import_16/* .SchemaDialectAdapterService */.I,
|
|
1993
|
+
typeof IPermissionActionRegistry === "undefined" ? Object : IPermissionActionRegistry
|
|
1708
1994
|
])
|
|
1709
1995
|
], DefinitionBundleService);
|
|
1710
1996
|
|
|
@@ -1746,7 +2032,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
1746
2032
|
|
|
1747
2033
|
|
|
1748
2034
|
|
|
1749
|
-
/** Every cached definition list/get. Schema changes write these rows inside a transaction, past the cached services. */ const CACHED_DEFINITIONS = [
|
|
2035
|
+
/** Every cached definition list/get. Schema changes write these rows inside a transaction, past the cached services, so they are bumped after it commits. */ const CACHED_DEFINITIONS = [
|
|
1750
2036
|
_config_event_actions_js__rspack_import_3/* .ENTITY_BUILDER_EVENT_ENTITIES.ENTITY_DEFINITION */.P.ENTITY_DEFINITION,
|
|
1751
2037
|
_config_event_actions_js__rspack_import_3/* .ENTITY_BUILDER_EVENT_ENTITIES.FIELD_DEFINITION */.P.FIELD_DEFINITION,
|
|
1752
2038
|
_config_event_actions_js__rspack_import_3/* .ENTITY_BUILDER_EVENT_ENTITIES.FLOW_DEFINITION */.P.FLOW_DEFINITION
|
|
@@ -1759,7 +2045,7 @@ class DefinitionCacheService {
|
|
|
1759
2045
|
this.utilsService = utilsService;
|
|
1760
2046
|
}
|
|
1761
2047
|
/** `tenantId` is the tenant whose definitions changed (see `cacheTenantId`); caches are keyed per tenant. */ async clearAll(tenantId) {
|
|
1762
|
-
await Promise.all(CACHED_DEFINITIONS.map((name)=>this.utilsService.clearCache(name, this.cacheManager,
|
|
2048
|
+
await Promise.all(CACHED_DEFINITIONS.map((name)=>this.utilsService.clearCache(name, this.cacheManager, tenantId)));
|
|
1763
2049
|
}
|
|
1764
2050
|
}
|
|
1765
2051
|
DefinitionCacheService = _ts_decorate([
|
|
@@ -1885,11 +2171,10 @@ const DEFAULT_ENDPOINT_NAME = {
|
|
|
1885
2171
|
delete: 'Delete'
|
|
1886
2172
|
};
|
|
1887
2173
|
const DEFAULT_INPUT_LABEL = {
|
|
1888
|
-
id: 'Id'
|
|
1889
|
-
ids: 'Ids',
|
|
1890
|
-
search: 'Search'
|
|
2174
|
+
id: 'Id'
|
|
1891
2175
|
};
|
|
1892
2176
|
const DEFAULT_NO_MATCH_MESSAGE = 'No record matches the filter.';
|
|
2177
|
+
const DEFAULT_DELETE_ONLY_MESSAGE = 'Only delete is supported: a flow cannot restore or permanently delete a record.';
|
|
1893
2178
|
const MAX_NAME_LENGTH = 255;
|
|
1894
2179
|
/** A supplied text when it has content, the English default otherwise. */ const textOr = (value, fallback)=>value?.trim() || fallback;
|
|
1895
2180
|
const INPUT_TYPE = {
|
|
@@ -1907,7 +2192,18 @@ const INPUT_TYPE = {
|
|
|
1907
2192
|
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.JSON */.P.JSON]: 'object',
|
|
1908
2193
|
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.FILE */.P.FILE]: 'uuid'
|
|
1909
2194
|
};
|
|
1910
|
-
const
|
|
2195
|
+
/** The API controller endpoint each endpoint's Request step stands in for. */ const ENDPOINT_CONTRACTS = {
|
|
2196
|
+
insert: 'insert',
|
|
2197
|
+
insertMany: 'insert_many',
|
|
2198
|
+
getById: 'get_by_id',
|
|
2199
|
+
getByIds: 'get_by_ids',
|
|
2200
|
+
getAll: 'get_all',
|
|
2201
|
+
getByFilter: 'get_by_filter',
|
|
2202
|
+
update: 'update',
|
|
2203
|
+
updateMany: 'update_many',
|
|
2204
|
+
bulkUpsert: 'bulk_upsert',
|
|
2205
|
+
delete: 'delete'
|
|
2206
|
+
};
|
|
1911
2207
|
const READ_ENDPOINTS = new Set([
|
|
1912
2208
|
'getById',
|
|
1913
2209
|
'getByIds',
|
|
@@ -1967,10 +2263,6 @@ const ref = (path)=>({
|
|
|
1967
2263
|
type: 'field_ref',
|
|
1968
2264
|
ref: path
|
|
1969
2265
|
});
|
|
1970
|
-
const lit = (value)=>({
|
|
1971
|
-
type: 'literal',
|
|
1972
|
-
value
|
|
1973
|
-
});
|
|
1974
2266
|
/** `customer_ticket` -> `customer-ticket`: an entity code always fits a flow URL name. */ const entityFlowSlug = (entityCode)=>entityCode.replace(/_/g, '-');
|
|
1975
2267
|
function optionValues(options) {
|
|
1976
2268
|
return (options ?? []).map((o)=>o && typeof o === 'object' && 'value' in o ? String(o.value) : String(o));
|
|
@@ -2041,38 +2333,38 @@ const optionalFieldInputs = (fields)=>fields.map((f)=>fieldInput(f, false));
|
|
|
2041
2333
|
const idInput = (t)=>({
|
|
2042
2334
|
name: 'id',
|
|
2043
2335
|
label: t.inputLabels.id,
|
|
2044
|
-
type: 'uuid'
|
|
2045
|
-
required: true
|
|
2046
|
-
});
|
|
2047
|
-
const idsInput = (t)=>({
|
|
2048
|
-
name: 'ids',
|
|
2049
|
-
label: t.inputLabels.ids,
|
|
2050
|
-
type: 'array',
|
|
2051
|
-
itemType: 'uuid',
|
|
2052
|
-
required: true
|
|
2336
|
+
type: 'uuid'
|
|
2053
2337
|
});
|
|
2054
|
-
const respond = (id, column, statusCode,
|
|
2338
|
+
/** An API controller envelope answer: `<entity>.<action>.success` (or the given key), like the generic controller's. */ const respond = (id, column, statusCode, format, message, messageKey, rest = {}, row)=>({
|
|
2055
2339
|
id,
|
|
2056
2340
|
type: 'respond',
|
|
2057
2341
|
column,
|
|
2058
2342
|
row,
|
|
2059
|
-
config:
|
|
2060
|
-
statusCode,
|
|
2061
|
-
bodyExpression: body
|
|
2062
|
-
} : {
|
|
2343
|
+
config: {
|
|
2063
2344
|
statusCode,
|
|
2064
|
-
|
|
2345
|
+
format,
|
|
2346
|
+
message,
|
|
2347
|
+
messageKey,
|
|
2348
|
+
...rest
|
|
2065
2349
|
}
|
|
2066
2350
|
});
|
|
2067
2351
|
/**
|
|
2068
|
-
* The steps of one endpoint
|
|
2069
|
-
* flow never share a step. A bulk body is
|
|
2070
|
-
*
|
|
2071
|
-
* answered with the saved records in order.
|
|
2352
|
+
* The steps of one endpoint, answering the generic API controller's envelope and message keys. Its step
|
|
2353
|
+
* ids are `<endpoint>_<step>` (`id()`), so the endpoints of one flow never share a step. A bulk body is
|
|
2354
|
+
* the list itself (the declared fields check each item), written by one step that walks it (`target:
|
|
2355
|
+
* many`, each item read as `loop.item`), all or nothing, and answered with the saved records in order.
|
|
2356
|
+
* getAll reads the request's filter, sort, paging, select, withDeleted and `?q=` search, getById and
|
|
2357
|
+
* getByIds their select (getByIds answers one page of every match, like the controller); delete takes a list of ids and refuses restore / permanent, which no flow step does.
|
|
2072
2358
|
*/ function endpointGraph(entity, endpoint, texts) {
|
|
2073
2359
|
const id = (step)=>`${endpoint}_${step}`;
|
|
2074
|
-
const entityCode = entity
|
|
2075
|
-
const
|
|
2360
|
+
const { code: entityCode, label } = entity;
|
|
2361
|
+
const key = (action)=>`${entityCode}.${action}.success`;
|
|
2362
|
+
const count = (step)=>({
|
|
2363
|
+
messageVariables: {
|
|
2364
|
+
count: ref(`context.${id(step)}.count`)
|
|
2365
|
+
}
|
|
2366
|
+
});
|
|
2367
|
+
const single = (inputSchema, step, message, action, statusCode = 200)=>({
|
|
2076
2368
|
inputSchema,
|
|
2077
2369
|
steps: [
|
|
2078
2370
|
{
|
|
@@ -2080,7 +2372,9 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
2080
2372
|
id: id('record'),
|
|
2081
2373
|
column: 1
|
|
2082
2374
|
},
|
|
2083
|
-
respond(id('respond'), 2, statusCode,
|
|
2375
|
+
respond(id('respond'), 2, statusCode, 'single', message, key(action), {
|
|
2376
|
+
bodyExpression: ref(`context.${id('record')}`)
|
|
2377
|
+
})
|
|
2084
2378
|
],
|
|
2085
2379
|
edges: [
|
|
2086
2380
|
[
|
|
@@ -2090,8 +2384,7 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
2090
2384
|
]
|
|
2091
2385
|
]
|
|
2092
2386
|
});
|
|
2093
|
-
const bulk = (itemSchema, step, statusCode)=>({
|
|
2094
|
-
bodyType: 'list',
|
|
2387
|
+
const bulk = (itemSchema, step, message, action, statusCode)=>({
|
|
2095
2388
|
inputSchema: itemSchema,
|
|
2096
2389
|
steps: [
|
|
2097
2390
|
{
|
|
@@ -2104,7 +2397,39 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
2104
2397
|
items: ref('input')
|
|
2105
2398
|
}
|
|
2106
2399
|
},
|
|
2107
|
-
respond(id('respond'), 2, statusCode,
|
|
2400
|
+
respond(id('respond'), 2, statusCode, 'bulk', message, key(action), {
|
|
2401
|
+
bodyExpression: ref(`context.${id('records')}.items`),
|
|
2402
|
+
...count('records')
|
|
2403
|
+
})
|
|
2404
|
+
],
|
|
2405
|
+
edges: [
|
|
2406
|
+
[
|
|
2407
|
+
id('records'),
|
|
2408
|
+
'out',
|
|
2409
|
+
id('respond')
|
|
2410
|
+
]
|
|
2411
|
+
]
|
|
2412
|
+
});
|
|
2413
|
+
const list = (query, message, action, paged = true)=>({
|
|
2414
|
+
inputSchema: [],
|
|
2415
|
+
steps: [
|
|
2416
|
+
{
|
|
2417
|
+
id: id('records'),
|
|
2418
|
+
type: 'entity_query',
|
|
2419
|
+
column: 1,
|
|
2420
|
+
config: {
|
|
2421
|
+
entityCode,
|
|
2422
|
+
...query
|
|
2423
|
+
}
|
|
2424
|
+
},
|
|
2425
|
+
respond(id('respond'), 2, 200, 'list', message, key(action), {
|
|
2426
|
+
bodyExpression: ref(`context.${id('records')}.items`),
|
|
2427
|
+
...paged ? {
|
|
2428
|
+
total: ref(`context.${id('records')}.total`),
|
|
2429
|
+
page: ref(`context.${id('records')}.page`),
|
|
2430
|
+
pageSize: ref(`context.${id('records')}.pageSize`)
|
|
2431
|
+
} : {}
|
|
2432
|
+
})
|
|
2108
2433
|
],
|
|
2109
2434
|
edges: [
|
|
2110
2435
|
[
|
|
@@ -2124,7 +2449,7 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
2124
2449
|
entityCode,
|
|
2125
2450
|
fields: fieldMap(entity.fields, 'input')
|
|
2126
2451
|
}
|
|
2127
|
-
}, 201);
|
|
2452
|
+
}, `${label} created successfully`, 'create', 201);
|
|
2128
2453
|
case 'insertMany':
|
|
2129
2454
|
return bulk(insertInputs, {
|
|
2130
2455
|
type: 'entity_insert',
|
|
@@ -2132,57 +2457,36 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
2132
2457
|
entityCode,
|
|
2133
2458
|
fields: fieldMap(entity.fields, 'loop.item')
|
|
2134
2459
|
}
|
|
2135
|
-
}, 201);
|
|
2460
|
+
}, `${label} records created successfully`, 'create.many', 201);
|
|
2136
2461
|
case 'getById':
|
|
2137
|
-
return single([
|
|
2138
|
-
idInput(texts)
|
|
2139
|
-
], {
|
|
2462
|
+
return single([], {
|
|
2140
2463
|
type: 'entity_get',
|
|
2141
2464
|
config: {
|
|
2142
2465
|
entityCode,
|
|
2143
|
-
id: ref('input.id')
|
|
2466
|
+
id: ref('input.id'),
|
|
2467
|
+
fromRequest: true
|
|
2144
2468
|
}
|
|
2145
|
-
});
|
|
2469
|
+
}, `${label} retrieved successfully`, 'get');
|
|
2146
2470
|
case 'getByIds':
|
|
2147
|
-
return
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
filter: {
|
|
2154
|
-
id: {
|
|
2155
|
-
op: 'in',
|
|
2156
|
-
value: ref('input.ids')
|
|
2157
|
-
}
|
|
2158
|
-
},
|
|
2159
|
-
limit: _flow_engine_flow_types_js__rspack_import_1/* .FLOW_LIMITS.MAX_QUERY_LIMIT */.Or.MAX_QUERY_LIMIT
|
|
2160
|
-
}
|
|
2161
|
-
});
|
|
2162
|
-
case 'getAll':
|
|
2163
|
-
return single([
|
|
2164
|
-
{
|
|
2165
|
-
name: 'search',
|
|
2166
|
-
label: texts.inputLabels.search,
|
|
2167
|
-
type: 'string'
|
|
2471
|
+
return list({
|
|
2472
|
+
filter: {
|
|
2473
|
+
id: {
|
|
2474
|
+
op: 'in',
|
|
2475
|
+
value: ref('input.ids')
|
|
2476
|
+
}
|
|
2168
2477
|
},
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
}
|
|
2178
|
-
});
|
|
2478
|
+
fromRequest: true,
|
|
2479
|
+
limit: _flow_engine_flow_types_js__rspack_import_1/* .FLOW_LIMITS.MAX_QUERY_LIMIT */.Or.MAX_QUERY_LIMIT
|
|
2480
|
+
}, `${label} records retrieved successfully`, 'get.by.ids', false);
|
|
2481
|
+
case 'getAll':
|
|
2482
|
+
return list({
|
|
2483
|
+
fromRequest: true,
|
|
2484
|
+
limit: _flow_engine_flow_types_js__rspack_import_1/* .FLOW_LIMITS.DEFAULT_QUERY_LIMIT */.Or.DEFAULT_QUERY_LIMIT
|
|
2485
|
+
}, `${label} records retrieved successfully`, 'get.all');
|
|
2179
2486
|
case 'getByFilter':
|
|
2180
2487
|
return {
|
|
2181
2488
|
inputSchema: [
|
|
2182
|
-
|
|
2183
|
-
...idInput(texts),
|
|
2184
|
-
required: false
|
|
2185
|
-
},
|
|
2489
|
+
idInput(texts),
|
|
2186
2490
|
...filterInputs(filterFields)
|
|
2187
2491
|
],
|
|
2188
2492
|
steps: [
|
|
@@ -2215,12 +2519,10 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
2215
2519
|
}
|
|
2216
2520
|
}
|
|
2217
2521
|
},
|
|
2218
|
-
respond(id('respond'), 3, 200,
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
messageKey: lit(_config_message_keys_js__rspack_import_4/* .GENERIC_RECORD_MESSAGES.NO_MATCH */.j4.NO_MATCH)
|
|
2223
|
-
}, 1)
|
|
2522
|
+
respond(id('respond'), 3, 200, 'single', `${label} retrieved successfully`, key('get.by.filter'), {
|
|
2523
|
+
bodyExpression: ref(`context.${id('records')}.items.0`)
|
|
2524
|
+
}),
|
|
2525
|
+
respond(id('not_found'), 3, 404, 'message', texts.noMatchMessage, _config_message_keys_js__rspack_import_4/* .GENERIC_RECORD_MESSAGES.NO_MATCH */.j4.NO_MATCH, {}, 1)
|
|
2224
2526
|
],
|
|
2225
2527
|
edges: [
|
|
2226
2528
|
[
|
|
@@ -2241,34 +2543,25 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
2241
2543
|
]
|
|
2242
2544
|
};
|
|
2243
2545
|
case 'update':
|
|
2244
|
-
return single(
|
|
2245
|
-
idInput(texts),
|
|
2246
|
-
...optionalFieldInputs(entity.fields)
|
|
2247
|
-
], {
|
|
2546
|
+
return single(optionalFieldInputs(entity.fields), {
|
|
2248
2547
|
type: 'entity_update',
|
|
2249
2548
|
config: {
|
|
2250
2549
|
entityCode,
|
|
2251
2550
|
id: ref('input.id'),
|
|
2252
2551
|
fields: fieldMap(entity.fields, 'input')
|
|
2253
2552
|
}
|
|
2254
|
-
});
|
|
2553
|
+
}, `${label} updated successfully`, 'update');
|
|
2255
2554
|
case 'updateMany':
|
|
2256
|
-
return bulk(
|
|
2257
|
-
idInput(texts),
|
|
2258
|
-
...optionalFieldInputs(entity.fields)
|
|
2259
|
-
], {
|
|
2555
|
+
return bulk(optionalFieldInputs(entity.fields), {
|
|
2260
2556
|
type: 'entity_update',
|
|
2261
2557
|
config: {
|
|
2262
2558
|
entityCode,
|
|
2263
2559
|
fields: fieldMap(entity.fields, 'loop.item')
|
|
2264
2560
|
}
|
|
2265
|
-
}, 200);
|
|
2561
|
+
}, `${label} records updated successfully`, 'update.many', 200);
|
|
2266
2562
|
case 'bulkUpsert':
|
|
2267
2563
|
return bulk([
|
|
2268
|
-
|
|
2269
|
-
...idInput(texts),
|
|
2270
|
-
required: false
|
|
2271
|
-
},
|
|
2564
|
+
idInput(texts),
|
|
2272
2565
|
...optionalFieldInputs(entity.fields)
|
|
2273
2566
|
], {
|
|
2274
2567
|
type: 'entity_update',
|
|
@@ -2277,17 +2570,60 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
2277
2570
|
fields: fieldMap(entity.fields, 'loop.item'),
|
|
2278
2571
|
onNotFound: 'insert'
|
|
2279
2572
|
}
|
|
2280
|
-
}, 200);
|
|
2573
|
+
}, `${label} records upserted successfully`, 'upsert.many', 200);
|
|
2281
2574
|
case 'delete':
|
|
2282
|
-
return
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2575
|
+
return {
|
|
2576
|
+
inputSchema: [],
|
|
2577
|
+
steps: [
|
|
2578
|
+
{
|
|
2579
|
+
id: id('type'),
|
|
2580
|
+
type: 'validate',
|
|
2581
|
+
column: 1,
|
|
2582
|
+
config: {
|
|
2583
|
+
checks: [
|
|
2584
|
+
{
|
|
2585
|
+
id: 'type',
|
|
2586
|
+
field: 'type',
|
|
2587
|
+
message: texts.deleteOnlyMessage,
|
|
2588
|
+
rule: {
|
|
2589
|
+
operator: 'AND',
|
|
2590
|
+
conditions: [
|
|
2591
|
+
{
|
|
2592
|
+
field: 'input.type',
|
|
2593
|
+
comparison: 'equals',
|
|
2594
|
+
value: 'delete'
|
|
2595
|
+
}
|
|
2596
|
+
]
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
]
|
|
2600
|
+
}
|
|
2601
|
+
},
|
|
2602
|
+
{
|
|
2603
|
+
id: id('records'),
|
|
2604
|
+
type: 'entity_delete',
|
|
2605
|
+
column: 2,
|
|
2606
|
+
config: {
|
|
2607
|
+
entityCode,
|
|
2608
|
+
target: 'many',
|
|
2609
|
+
items: ref('input.id')
|
|
2610
|
+
}
|
|
2611
|
+
},
|
|
2612
|
+
respond(id('respond'), 3, 200, 'message', `${label} records deleted successfully`, key('delete'), count('records'))
|
|
2613
|
+
],
|
|
2614
|
+
edges: [
|
|
2615
|
+
[
|
|
2616
|
+
id('type'),
|
|
2617
|
+
'out',
|
|
2618
|
+
id('records')
|
|
2619
|
+
],
|
|
2620
|
+
[
|
|
2621
|
+
id('records'),
|
|
2622
|
+
'out',
|
|
2623
|
+
id('respond')
|
|
2624
|
+
]
|
|
2625
|
+
]
|
|
2626
|
+
};
|
|
2291
2627
|
}
|
|
2292
2628
|
}
|
|
2293
2629
|
/**
|
|
@@ -2302,11 +2638,10 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
2302
2638
|
*/ function buildEntityFlow(entity, endpoints, texts = {}) {
|
|
2303
2639
|
const resolved = {
|
|
2304
2640
|
inputLabels: {
|
|
2305
|
-
id: textOr(texts.inputLabels?.id, DEFAULT_INPUT_LABEL.id)
|
|
2306
|
-
ids: textOr(texts.inputLabels?.ids, DEFAULT_INPUT_LABEL.ids),
|
|
2307
|
-
search: textOr(texts.inputLabels?.search, DEFAULT_INPUT_LABEL.search)
|
|
2641
|
+
id: textOr(texts.inputLabels?.id, DEFAULT_INPUT_LABEL.id)
|
|
2308
2642
|
},
|
|
2309
|
-
noMatchMessage: textOr(texts.noMatchMessage, DEFAULT_NO_MATCH_MESSAGE)
|
|
2643
|
+
noMatchMessage: textOr(texts.noMatchMessage, DEFAULT_NO_MATCH_MESSAGE),
|
|
2644
|
+
deleteOnlyMessage: textOr(texts.deleteOnlyMessage, DEFAULT_DELETE_ONLY_MESSAGE)
|
|
2310
2645
|
};
|
|
2311
2646
|
const nodes = [];
|
|
2312
2647
|
const edges = [];
|
|
@@ -2319,8 +2654,10 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
2319
2654
|
});
|
|
2320
2655
|
const config = {
|
|
2321
2656
|
path: ENTITY_FLOW_PATHS[endpoint],
|
|
2322
|
-
|
|
2323
|
-
|
|
2657
|
+
contract: ENDPOINT_CONTRACTS[endpoint],
|
|
2658
|
+
...graph.inputSchema.length ? {
|
|
2659
|
+
inputSchema: graph.inputSchema
|
|
2660
|
+
} : {},
|
|
2324
2661
|
authMode: 'permission',
|
|
2325
2662
|
permissions: endpointPermissions(entity.code, endpoint),
|
|
2326
2663
|
...READ_ENDPOINTS.has(endpoint) ? {} : {
|
|
@@ -2405,6 +2742,7 @@ const CRUD_ACTIONS = [
|
|
|
2405
2742
|
'update',
|
|
2406
2743
|
'delete'
|
|
2407
2744
|
];
|
|
2745
|
+
/** The create / read / update / delete permission codes of a dynamic entity. */ const entityPermissionCodes = (entityCode)=>CRUD_ACTIONS.map((op)=>(0,_flusys_nestjs_shared__rspack_import_0.dynamicEntityPermission)(entityCode, op));
|
|
2408
2746
|
class EntityPermissionService {
|
|
2409
2747
|
actionRegistry;
|
|
2410
2748
|
constructor(actionRegistry){
|
|
@@ -2424,7 +2762,7 @@ class EntityPermissionService {
|
|
|
2424
2762
|
if (!this.actionRegistry) return;
|
|
2425
2763
|
await this.actionRegistry.removeActionsByCodes([
|
|
2426
2764
|
(0,_flusys_nestjs_shared__rspack_import_0.dynamicEntityPermissionParent)(definition.code),
|
|
2427
|
-
...
|
|
2765
|
+
...entityPermissionCodes(definition.code)
|
|
2428
2766
|
]);
|
|
2429
2767
|
}
|
|
2430
2768
|
}
|
|
@@ -2440,6 +2778,8 @@ EntityPermissionService = _ts_decorate([
|
|
|
2440
2778
|
|
|
2441
2779
|
__webpack_require__.d(__webpack_exports__, {
|
|
2442
2780
|
u: () => (EntityPermissionService)
|
|
2781
|
+
}, {
|
|
2782
|
+
Z: entityPermissionCodes
|
|
2443
2783
|
});
|
|
2444
2784
|
|
|
2445
2785
|
|
|
@@ -2534,6 +2874,11 @@ const SCALAR_TO_TEXT = new Set([
|
|
|
2534
2874
|
_enums_field_type_enum_js__rspack_import_1/* .FieldType.DATETIME */.P.DATETIME
|
|
2535
2875
|
]);
|
|
2536
2876
|
const EMAIL_PG = `'^[^[:space:]@]+@[^[:space:]@]+\\.[^[:space:]@]+$'`;
|
|
2877
|
+
const EMAIL_MYSQL = `'^[^ @]+@[^ @]+\\\\.[^ @]+$'`;
|
|
2878
|
+
/** Rows whose value is not an email; `castToText` for a column that is not text yet. */ const notEmailCheck = (castToText)=>({
|
|
2879
|
+
description: (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_2/* .SCHEMA_PRECHECK_MESSAGES.NOT_EMAIL */.NE.NOT_EMAIL),
|
|
2880
|
+
badRowsWhere: (c, d)=>d === 'postgres' ? `${castToText ? `${c}::text` : c} !~ ${EMAIL_PG}` : `${castToText ? `CAST(${c} AS CHAR)` : c} NOT REGEXP ${EMAIL_MYSQL}`
|
|
2881
|
+
});
|
|
2537
2882
|
const regexFail = (column, driver, pattern)=>driver === 'postgres' ? `${column} !~ '${pattern}'` : `${column} NOT REGEXP '${pattern}'`;
|
|
2538
2883
|
const SELECT_KINDS = new Set([
|
|
2539
2884
|
_enums_field_type_enum_js__rspack_import_1/* .FieldType.SINGLE_SELECT */.P.SINGLE_SELECT,
|
|
@@ -2558,17 +2903,12 @@ function planTypeConversion(from, to, driver) {
|
|
|
2558
2903
|
if (driver === 'mysql' && (SELECT_KINDS.has(from) && SELECT_KINDS.has(to) || textLike && to === _enums_field_type_enum_js__rspack_import_1/* .FieldType.BOOLEAN */.P.BOOLEAN)) return unsupported(from, to);
|
|
2559
2904
|
// Same physical column (varchar(255)): only the meaning changes.
|
|
2560
2905
|
if (TEXT_LIKE.has(from) && TEXT_LIKE.has(to)) {
|
|
2561
|
-
const checks = [];
|
|
2562
|
-
if (to === _enums_field_type_enum_js__rspack_import_1/* .FieldType.EMAIL */.P.EMAIL) {
|
|
2563
|
-
checks.push({
|
|
2564
|
-
description: (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_2/* .SCHEMA_PRECHECK_MESSAGES.NOT_EMAIL */.NE.NOT_EMAIL),
|
|
2565
|
-
badRowsWhere: (c, d)=>d === 'postgres' ? `${c} !~ ${EMAIL_PG}` : `${c} NOT REGEXP '^[^ @]+@[^ @]+\\\\.[^ @]+$'`
|
|
2566
|
-
});
|
|
2567
|
-
}
|
|
2568
2906
|
return {
|
|
2569
2907
|
supported: true,
|
|
2570
2908
|
noDbChange: true,
|
|
2571
|
-
prechecks:
|
|
2909
|
+
prechecks: to === _enums_field_type_enum_js__rspack_import_1/* .FieldType.EMAIL */.P.EMAIL ? [
|
|
2910
|
+
notEmailCheck(false)
|
|
2911
|
+
] : []
|
|
2572
2912
|
};
|
|
2573
2913
|
}
|
|
2574
2914
|
if (from === _enums_field_type_enum_js__rspack_import_1/* .FieldType.RELATION */.P.RELATION && to === _enums_field_type_enum_js__rspack_import_1/* .FieldType.FILE */.P.FILE || from === _enums_field_type_enum_js__rspack_import_1/* .FieldType.FILE */.P.FILE && to === _enums_field_type_enum_js__rspack_import_1/* .FieldType.RELATION */.P.RELATION) {
|
|
@@ -2594,12 +2934,7 @@ function planTypeConversion(from, to, driver) {
|
|
|
2594
2934
|
badRowsWhere: (c, d)=>d === 'postgres' ? `char_length(${c}) > 255` : `CHAR_LENGTH(${c}) > 255`
|
|
2595
2935
|
}
|
|
2596
2936
|
];
|
|
2597
|
-
if (to === _enums_field_type_enum_js__rspack_import_1/* .FieldType.EMAIL */.P.EMAIL)
|
|
2598
|
-
checks.push({
|
|
2599
|
-
description: (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_2/* .SCHEMA_PRECHECK_MESSAGES.NOT_EMAIL */.NE.NOT_EMAIL),
|
|
2600
|
-
badRowsWhere: (c, d)=>d === 'postgres' ? `${c} !~ ${EMAIL_PG}` : `${c} NOT REGEXP '^[^ @]+@[^ @]+\\\\.[^ @]+$'`
|
|
2601
|
-
});
|
|
2602
|
-
}
|
|
2937
|
+
if (to === _enums_field_type_enum_js__rspack_import_1/* .FieldType.EMAIL */.P.EMAIL) checks.push(notEmailCheck(false));
|
|
2603
2938
|
return {
|
|
2604
2939
|
supported: true,
|
|
2605
2940
|
using: (c)=>`${c}::varchar(255)`,
|
|
@@ -2608,17 +2943,12 @@ function planTypeConversion(from, to, driver) {
|
|
|
2608
2943
|
}
|
|
2609
2944
|
// scalar -> text-like: always representable
|
|
2610
2945
|
if (SCALAR_TO_TEXT.has(from) && TEXT_LIKE.has(to)) {
|
|
2611
|
-
const checks = [];
|
|
2612
|
-
if (to === _enums_field_type_enum_js__rspack_import_1/* .FieldType.EMAIL */.P.EMAIL) {
|
|
2613
|
-
checks.push({
|
|
2614
|
-
description: (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_2/* .SCHEMA_PRECHECK_MESSAGES.NOT_EMAIL */.NE.NOT_EMAIL),
|
|
2615
|
-
badRowsWhere: (c, d)=>d === 'postgres' ? `${c}::text !~ ${EMAIL_PG}` : `CAST(${c} AS CHAR) NOT REGEXP '^[^ @]+@[^ @]+\\\\.[^ @]+$'`
|
|
2616
|
-
});
|
|
2617
|
-
}
|
|
2618
2946
|
return {
|
|
2619
2947
|
supported: true,
|
|
2620
2948
|
using: (c)=>`${c}::text`,
|
|
2621
|
-
prechecks:
|
|
2949
|
+
prechecks: to === _enums_field_type_enum_js__rspack_import_1/* .FieldType.EMAIL */.P.EMAIL ? [
|
|
2950
|
+
notEmailCheck(true)
|
|
2951
|
+
] : []
|
|
2622
2952
|
};
|
|
2623
2953
|
}
|
|
2624
2954
|
// text-like / long text -> scalar: every existing value must parse
|
|
@@ -2895,10 +3225,44 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
2895
3225
|
}
|
|
2896
3226
|
|
|
2897
3227
|
__webpack_require__.d(__webpack_exports__, {
|
|
2898
|
-
|
|
2899
|
-
|
|
3228
|
+
f: () => (assertIndexableField),
|
|
3229
|
+
k: () => (assertValidIdentifier)
|
|
3230
|
+
});
|
|
3231
|
+
|
|
3232
|
+
|
|
3233
|
+
},
|
|
3234
|
+
3086(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
3235
|
+
/** Pure JSON string helpers for finding and rewriting `<prefix>.<field>` references inside definitions. */ function mapStrings(value, fn) {
|
|
3236
|
+
if (typeof value === 'string') return fn(value);
|
|
3237
|
+
if (Array.isArray(value)) return value.map((v)=>mapStrings(v, fn));
|
|
3238
|
+
if (value && typeof value === 'object') {
|
|
3239
|
+
return Object.fromEntries(Object.entries(value).map(([k, v])=>[
|
|
3240
|
+
k,
|
|
3241
|
+
mapStrings(v, fn)
|
|
3242
|
+
]));
|
|
3243
|
+
}
|
|
3244
|
+
return value;
|
|
3245
|
+
}
|
|
3246
|
+
function anyString(value, test) {
|
|
3247
|
+
if (typeof value === 'string') return test(value);
|
|
3248
|
+
if (Array.isArray(value)) return value.some((v)=>anyString(v, test));
|
|
3249
|
+
if (value && typeof value === 'object') return Object.values(value).some((v)=>anyString(v, test));
|
|
3250
|
+
return false;
|
|
3251
|
+
}
|
|
3252
|
+
const escapeRe = (s)=>s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
3253
|
+
/**
|
|
3254
|
+
* `<prefix>.<field>`, `<prefix>.<field>.x` or `{{ <prefix>.<field> }}` inside a template - but not
|
|
3255
|
+
* `<prefix>.<field>_2`. The prefix is a regex source (e.g. `context\.find\.items\.\d+`), captured so a rewrite keeps it.
|
|
3256
|
+
*/ const referencePatternSource = (prefixSource, field, flags = '')=>new RegExp(`(^|\\{\\{\\s*)(${prefixSource})\\.${escapeRe(field)}(?!\\w)`, flags);
|
|
3257
|
+
const replaceReferenceSource = (s, prefixSource, from, to)=>s.replace(referencePatternSource(prefixSource, from, 'g'), (_match, lead, prefix)=>`${lead}${prefix}.${to}`);
|
|
3258
|
+
|
|
3259
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
3260
|
+
gp: () => (anyString),
|
|
3261
|
+
to: () => (mapStrings)
|
|
2900
3262
|
}, {
|
|
2901
|
-
|
|
3263
|
+
LV: referencePatternSource,
|
|
3264
|
+
NF: escapeRe,
|
|
3265
|
+
Ni: replaceReferenceSource
|
|
2902
3266
|
});
|
|
2903
3267
|
|
|
2904
3268
|
|
|
@@ -3094,8 +3458,13 @@ class SchemaChangeExecutor {
|
|
|
3094
3458
|
].toSorted().map((code)=>`eb_entity:${code}`);
|
|
3095
3459
|
const heldLocks = [];
|
|
3096
3460
|
const qr = await this.dataSourceProvider.getQueryRunner();
|
|
3097
|
-
|
|
3098
|
-
|
|
3461
|
+
try {
|
|
3462
|
+
await qr.connect();
|
|
3463
|
+
await qr.startTransaction();
|
|
3464
|
+
} catch (error) {
|
|
3465
|
+
await qr.release().catch(()=>undefined);
|
|
3466
|
+
throw (0,_database_error_mapper_js__rspack_import_6/* .mapSchemaError */.i)(error);
|
|
3467
|
+
}
|
|
3099
3468
|
const state = this.newState(target, options.impact ?? []);
|
|
3100
3469
|
let committed = false;
|
|
3101
3470
|
try {
|
|
@@ -3139,9 +3508,7 @@ class SchemaChangeExecutor {
|
|
|
3139
3508
|
}));
|
|
3140
3509
|
await qr.commitTransaction();
|
|
3141
3510
|
committed = true;
|
|
3142
|
-
|
|
3143
|
-
if (entityId) this.schemaRegistry.invalidate(entityId);
|
|
3144
|
-
await this.definitionCache.clearAll((0,_flusys_nestjs_shared_utils__rspack_import_0.cacheTenantId)(this.dataSourceProvider));
|
|
3511
|
+
await this.invalidateDefinitions(target, outcome.entityDefinitionId ?? target.entityDefinitionId, state.warnings);
|
|
3145
3512
|
try {
|
|
3146
3513
|
await outcome.afterCommit?.();
|
|
3147
3514
|
} catch (postCommitError) {
|
|
@@ -3158,6 +3525,8 @@ class SchemaChangeExecutor {
|
|
|
3158
3525
|
} catch (error) {
|
|
3159
3526
|
if (!committed) await qr.rollbackTransaction().catch(()=>undefined);
|
|
3160
3527
|
const undo = !committed && driver === 'mysql' && state.undo.length > 0 ? await this.compensate(qr, target, state) : null;
|
|
3528
|
+
// MySQL commits implicitly at each DDL statement, so metadata written before one may have stayed.
|
|
3529
|
+
if (undo) await this.invalidateDefinitions(target, target.entityDefinitionId, []);
|
|
3161
3530
|
await this.logFailure(target, error, state.steps, undo);
|
|
3162
3531
|
throw this.withUndo((0,_database_error_mapper_js__rspack_import_6/* .mapSchemaError */.i)(error), undo);
|
|
3163
3532
|
} finally{
|
|
@@ -3165,6 +3534,17 @@ class SchemaChangeExecutor {
|
|
|
3165
3534
|
await qr.release();
|
|
3166
3535
|
}
|
|
3167
3536
|
}
|
|
3537
|
+
/** Runs only once the change's transaction has ended: a bump inside it would let a concurrent reader re-cache the old definitions. */ async invalidateDefinitions(target, entityId, warnings) {
|
|
3538
|
+
try {
|
|
3539
|
+
if (entityId) this.schemaRegistry.invalidate(entityId);
|
|
3540
|
+
await this.definitionCache.clearAll((0,_flusys_nestjs_shared_utils__rspack_import_0.cacheTenantId)(this.dataSourceProvider));
|
|
3541
|
+
} catch (cacheError) {
|
|
3542
|
+
this.logger.error(`Clearing the definition cache failed after '${target.action}' on '${target.entityCode}': ${cacheError.message}`);
|
|
3543
|
+
warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_11/* .SCHEMA_WARNING_MESSAGES.FOLLOW_UP_FAILED */.Uu.FOLLOW_UP_FAILED, {
|
|
3544
|
+
detail: (0,_flow_engine_flow_errors_js__rspack_import_3/* .errorRef */.O$)(cacheError)
|
|
3545
|
+
}));
|
|
3546
|
+
}
|
|
3547
|
+
}
|
|
3168
3548
|
/**
|
|
3169
3549
|
* MySQL only: runs the reverse of every DDL statement that had run, newest first, still under
|
|
3170
3550
|
* the entity lock. Stops at the first undo statement that fails - running later ones against an
|
|
@@ -3449,14 +3829,14 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
3449
3829
|
/* import */ var class_transformer__rspack_import_3 = __webpack_require__(5812);
|
|
3450
3830
|
/* import */ var class_validator__rspack_import_4 = __webpack_require__(5421);
|
|
3451
3831
|
/* import */ var typeorm__rspack_import_5 = __webpack_require__(7158);
|
|
3452
|
-
/* import */ var
|
|
3832
|
+
/* import */ var _config_message_keys_js__rspack_import_20 = __webpack_require__(5732);
|
|
3453
3833
|
/* import */ var _dtos_schema_change_dto_js__rspack_import_6 = __webpack_require__(4945);
|
|
3454
3834
|
/* import */ var _entities_entity_definition_entity_js__rspack_import_7 = __webpack_require__(3189);
|
|
3455
3835
|
/* import */ var _entities_field_definition_entity_js__rspack_import_8 = __webpack_require__(2206);
|
|
3456
3836
|
/* import */ var _entities_schema_change_log_entity_js__rspack_import_9 = __webpack_require__(875);
|
|
3457
|
-
/* import */ var
|
|
3458
|
-
/* import */ var
|
|
3459
|
-
/* import */ var
|
|
3837
|
+
/* import */ var _enums_ddl_operation_enum_js__rspack_import_22 = __webpack_require__(9949);
|
|
3838
|
+
/* import */ var _enums_entity_status_enum_js__rspack_import_24 = __webpack_require__(1313);
|
|
3839
|
+
/* import */ var _enums_field_type_enum_js__rspack_import_21 = __webpack_require__(9614);
|
|
3460
3840
|
/* import */ var _entity_builder_datasource_provider_js__rspack_import_10 = __webpack_require__(424);
|
|
3461
3841
|
/* import */ var _entity_permission_service_js__rspack_import_11 = __webpack_require__(1462);
|
|
3462
3842
|
/* import */ var _field_value_validator_js__rspack_import_12 = __webpack_require__(3525);
|
|
@@ -3464,9 +3844,10 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
3464
3844
|
/* import */ var _identifier_rules_js__rspack_import_14 = __webpack_require__(413);
|
|
3465
3845
|
/* import */ var _reference_scanner_service_js__rspack_import_15 = __webpack_require__(921);
|
|
3466
3846
|
/* import */ var _schema_change_executor_service_js__rspack_import_16 = __webpack_require__(6605);
|
|
3467
|
-
/* import */ var
|
|
3847
|
+
/* import */ var _schema_change_types_js__rspack_import_23 = __webpack_require__(7827);
|
|
3468
3848
|
/* import */ var _schema_columns_js__rspack_import_17 = __webpack_require__(5313);
|
|
3469
|
-
/* import */ var
|
|
3849
|
+
/* import */ var _entity_builder_config_service_js__rspack_import_18 = __webpack_require__(4281);
|
|
3850
|
+
/* import */ var _schema_dialect_adapter_service_js__rspack_import_19 = __webpack_require__(7259);
|
|
3470
3851
|
function _ts_decorate(decorators, target, key, desc) {
|
|
3471
3852
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3472
3853
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -3512,48 +3893,59 @@ function _ts_param(paramIndex, decorator) {
|
|
|
3512
3893
|
|
|
3513
3894
|
|
|
3514
3895
|
|
|
3896
|
+
|
|
3515
3897
|
|
|
3516
3898
|
|
|
3517
3899
|
const entityNotFound = (id)=>new _nestjs_common__rspack_import_2.NotFoundException({
|
|
3518
3900
|
message: `Entity definition '${id}' not found.`,
|
|
3519
|
-
messageKey:
|
|
3901
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .ENTITY_DEFINITION_MESSAGES.NOT_FOUND */.pL.NOT_FOUND,
|
|
3520
3902
|
messageVariables: {
|
|
3521
3903
|
id
|
|
3522
3904
|
}
|
|
3523
3905
|
});
|
|
3524
3906
|
const fieldNotFound = (id)=>new _nestjs_common__rspack_import_2.NotFoundException({
|
|
3525
3907
|
message: `Field definition '${id}' not found.`,
|
|
3526
|
-
messageKey:
|
|
3908
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .FIELD_DEFINITION_MESSAGES.NOT_FOUND */.oc.NOT_FOUND,
|
|
3527
3909
|
messageVariables: {
|
|
3528
3910
|
id
|
|
3529
3911
|
}
|
|
3530
3912
|
});
|
|
3913
|
+
const HISTORY_LIMIT = 50;
|
|
3531
3914
|
const DESTRUCTIVE_ACTIONS = [
|
|
3532
3915
|
_dtos_schema_change_dto_js__rspack_import_6/* .SchemaChangeAction.DROP_ENTITY */.M3.DROP_ENTITY,
|
|
3533
3916
|
_dtos_schema_change_dto_js__rspack_import_6/* .SchemaChangeAction.PURGE_FIELD */.M3.PURGE_FIELD
|
|
3534
3917
|
];
|
|
3535
3918
|
const isDestructiveSchemaAction = (action)=>DESTRUCTIVE_ACTIONS.includes(action);
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3919
|
+
/**
|
|
3920
|
+
* Every structural change to an existing entity: add / change / rename / restore / deprecate /
|
|
3921
|
+
* purge a field, change entity settings, drop an entity, and repair drift. Each is a
|
|
3922
|
+
* `SchemaChangeRun` executed by SchemaChangeExecutor, so each can be previewed (`plan`) with
|
|
3923
|
+
* the real SQL and data checks before it is applied. The definitions loaded up front only
|
|
3924
|
+
* validate the request; every run reloads them through its own query runner, so an apply works
|
|
3925
|
+
* on what is current under the entity lock. Plans carry counts but never record values.
|
|
3926
|
+
*/ /** Metadata the runtime reads from the cached field list (SchemaRegistryService): changing it must move schemaVersion. */ const FIELD_CACHE_KEYS = new Set([
|
|
3927
|
+
'selectOptions',
|
|
3928
|
+
'validationRules',
|
|
3929
|
+
'defaultValue',
|
|
3930
|
+
'label',
|
|
3931
|
+
'relationTargetEntityId',
|
|
3932
|
+
'isSearchable',
|
|
3933
|
+
'order'
|
|
3934
|
+
]);
|
|
3545
3935
|
class SchemaEvolutionService {
|
|
3546
3936
|
dataSourceProvider;
|
|
3547
3937
|
adapter;
|
|
3548
3938
|
executor;
|
|
3549
3939
|
references;
|
|
3550
3940
|
permissions;
|
|
3551
|
-
|
|
3941
|
+
config;
|
|
3942
|
+
constructor(dataSourceProvider, adapter, executor, references, permissions, config){
|
|
3552
3943
|
this.dataSourceProvider = dataSourceProvider;
|
|
3553
3944
|
this.adapter = adapter;
|
|
3554
3945
|
this.executor = executor;
|
|
3555
3946
|
this.references = references;
|
|
3556
3947
|
this.permissions = permissions;
|
|
3948
|
+
this.config = config;
|
|
3557
3949
|
}
|
|
3558
3950
|
// ── public API ──────────────────────────────────────────────────────────────────────
|
|
3559
3951
|
async plan(request, user) {
|
|
@@ -3575,8 +3967,8 @@ class SchemaEvolutionService {
|
|
|
3575
3967
|
const { definition, fields } = await this.loadEntity(entityDefinitionId);
|
|
3576
3968
|
const driver = await this.dataSourceProvider.getDriver();
|
|
3577
3969
|
const qr = await this.dataSourceProvider.getQueryRunner();
|
|
3578
|
-
await qr.connect();
|
|
3579
3970
|
try {
|
|
3971
|
+
await qr.connect();
|
|
3580
3972
|
const table = await qr.getTable(definition.tableName);
|
|
3581
3973
|
const findings = this.diff(definition, fields, table ?? undefined, driver);
|
|
3582
3974
|
let rowCount = null;
|
|
@@ -3595,7 +3987,7 @@ class SchemaEvolutionService {
|
|
|
3595
3987
|
await qr.release();
|
|
3596
3988
|
}
|
|
3597
3989
|
}
|
|
3598
|
-
/** Newest first. Includes failed attempts, with the SQL that was about to run. */ async history(entityDefinitionId
|
|
3990
|
+
/** Newest first. Includes failed attempts, with the SQL that was about to run. */ async history(entityDefinitionId) {
|
|
3599
3991
|
const repo = await this.dataSourceProvider.getRepository(_entities_schema_change_log_entity_js__rspack_import_9/* .SchemaChangeLog */.W);
|
|
3600
3992
|
return repo.find({
|
|
3601
3993
|
select: {
|
|
@@ -3616,7 +4008,7 @@ class SchemaEvolutionService {
|
|
|
3616
4008
|
order: {
|
|
3617
4009
|
createdAt: 'DESC'
|
|
3618
4010
|
},
|
|
3619
|
-
take:
|
|
4011
|
+
take: HISTORY_LIMIT
|
|
3620
4012
|
});
|
|
3621
4013
|
}
|
|
3622
4014
|
// ── loading ─────────────────────────────────────────────────────────────────────────
|
|
@@ -3624,7 +4016,7 @@ class SchemaEvolutionService {
|
|
|
3624
4016
|
if (!entityDefinitionId) {
|
|
3625
4017
|
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
3626
4018
|
message: 'entityDefinitionId is required for this action.',
|
|
3627
|
-
messageKey:
|
|
4019
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .ENTITY_DEFINITION_MESSAGES.ID_REQUIRED */.pL.ID_REQUIRED
|
|
3628
4020
|
});
|
|
3629
4021
|
}
|
|
3630
4022
|
return this.definitions((entity)=>this.dataSourceProvider.getRepository(entity), entityDefinitionId);
|
|
@@ -3633,7 +4025,7 @@ class SchemaEvolutionService {
|
|
|
3633
4025
|
if (!fieldDefinitionId) {
|
|
3634
4026
|
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
3635
4027
|
message: 'fieldDefinitionId is required for this action.',
|
|
3636
|
-
messageKey:
|
|
4028
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .FIELD_DEFINITION_MESSAGES.ID_REQUIRED */.oc.ID_REQUIRED
|
|
3637
4029
|
});
|
|
3638
4030
|
}
|
|
3639
4031
|
const field = await (await this.dataSourceProvider.getRepository(_entities_field_definition_entity_js__rspack_import_8/* .FieldDefinition */.c)).findOne({
|
|
@@ -3675,7 +4067,7 @@ class SchemaEvolutionService {
|
|
|
3675
4067
|
if (unknown.length) {
|
|
3676
4068
|
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
3677
4069
|
message: `Cannot change ${what} property: ${unknown.join(', ')}. Allowed: ${allowed.join(', ')}.`,
|
|
3678
|
-
messageKey:
|
|
4070
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .SCHEMA_MESSAGES.UNKNOWN_CHANGE_PROPERTY */.Hu.UNKNOWN_CHANGE_PROPERTY,
|
|
3679
4071
|
messageVariables: {
|
|
3680
4072
|
what,
|
|
3681
4073
|
properties: unknown.join(', '),
|
|
@@ -3692,13 +4084,13 @@ class SchemaEvolutionService {
|
|
|
3692
4084
|
const properties = errors.map((e)=>e.property);
|
|
3693
4085
|
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
3694
4086
|
message: `Invalid value for ${properties.map((p)=>`'${p}'`).join(', ')}.`,
|
|
3695
|
-
messageKey:
|
|
4087
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .SCHEMA_MESSAGES.INVALID_CHANGE_VALUE */.Hu.INVALID_CHANGE_VALUE,
|
|
3696
4088
|
messageVariables: {
|
|
3697
4089
|
property: properties.join(', ')
|
|
3698
4090
|
},
|
|
3699
4091
|
errors: properties.map((property)=>({
|
|
3700
4092
|
field: property,
|
|
3701
|
-
messageKey:
|
|
4093
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .SCHEMA_MESSAGES.INVALID_CHANGE_VALUE */.Hu.INVALID_CHANGE_VALUE,
|
|
3702
4094
|
messageVariables: {
|
|
3703
4095
|
property
|
|
3704
4096
|
}
|
|
@@ -3726,7 +4118,7 @@ class SchemaEvolutionService {
|
|
|
3726
4118
|
if (updatedAt && updatedAt.getTime() !== new Date(expected).getTime()) {
|
|
3727
4119
|
throw new _nestjs_common__rspack_import_2.ConflictException({
|
|
3728
4120
|
message: 'Someone else changed this definition since you opened it. Reload it and make your change again.',
|
|
3729
|
-
messageKey:
|
|
4121
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .SCHEMA_MESSAGES.STALE_DEFINITION */.Hu.STALE_DEFINITION,
|
|
3730
4122
|
messageVariables: {
|
|
3731
4123
|
updatedAt: updatedAt.toISOString()
|
|
3732
4124
|
}
|
|
@@ -3735,7 +4127,7 @@ class SchemaEvolutionService {
|
|
|
3735
4127
|
}
|
|
3736
4128
|
/** The field was renamed (or deprecated) by a change that committed after this request was checked. */ changedUnderneath(ctx, before, now) {
|
|
3737
4129
|
if (now.code === before.code && !!now.deprecatedAt === !!before.deprecatedAt) return false;
|
|
3738
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4130
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.DEFINITION_CHANGED */.M3.DEFINITION_CHANGED));
|
|
3739
4131
|
return true;
|
|
3740
4132
|
}
|
|
3741
4133
|
// ── dispatch ────────────────────────────────────────────────────────────────────────
|
|
@@ -3781,7 +4173,7 @@ class SchemaEvolutionService {
|
|
|
3781
4173
|
return (0,_flusys_nestjs_shared_utils__rspack_import_1.withSavepoint)(ctx.qr, ()=>this.scalar(ctx, sql, params)).catch(()=>0);
|
|
3782
4174
|
}
|
|
3783
4175
|
paramValue(fieldType, value) {
|
|
3784
|
-
return fieldType ===
|
|
4176
|
+
return fieldType === _enums_field_type_enum_js__rspack_import_21/* .FieldType.JSON */.P.JSON || fieldType === _enums_field_type_enum_js__rspack_import_21/* .FieldType.MULTI_SELECT */.P.MULTI_SELECT ? JSON.stringify(value) : value;
|
|
3785
4177
|
}
|
|
3786
4178
|
notNullSql(ctx, table, column, fieldType, notNull) {
|
|
3787
4179
|
if (ctx.driver === 'postgres') {
|
|
@@ -3789,7 +4181,7 @@ class SchemaEvolutionService {
|
|
|
3789
4181
|
}
|
|
3790
4182
|
return `ALTER TABLE ${ctx.q(table)} MODIFY ${ctx.q(column)} ${(0,_schema_columns_js__rspack_import_17/* .sqlTypeFor */.cg)(fieldType, ctx.driver, this.adapter)} ${notNull ? 'NOT NULL' : 'NULL'}`;
|
|
3791
4183
|
}
|
|
3792
|
-
/** Makes a column NOT NULL (or nullable again), with the reverse statement for the plan. */ setRequired(ctx, table, column, fieldType, required, step = required ?
|
|
4184
|
+
/** Makes a column NOT NULL (or nullable again), with the reverse statement for the plan. */ setRequired(ctx, table, column, fieldType, required, step = required ? _config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.MAKE_REQUIRED */.EQ.MAKE_REQUIRED : _config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.MAKE_OPTIONAL */.EQ.MAKE_OPTIONAL) {
|
|
3793
4185
|
return ctx.rawDdl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(step, {
|
|
3794
4186
|
column
|
|
3795
4187
|
}), [
|
|
@@ -3800,7 +4192,7 @@ class SchemaEvolutionService {
|
|
|
3800
4192
|
}
|
|
3801
4193
|
checkValue(field, value) {
|
|
3802
4194
|
const { errors } = (0,_field_value_validator_js__rspack_import_12/* .validateRecord */.e)([
|
|
3803
|
-
|
|
4195
|
+
(0,_field_value_validator_js__rspack_import_12/* .valueRulesOf */.C)(field)
|
|
3804
4196
|
], {
|
|
3805
4197
|
[field.code]: value
|
|
3806
4198
|
}, 'insert');
|
|
@@ -3809,7 +4201,7 @@ class SchemaEvolutionService {
|
|
|
3809
4201
|
async requireTable(ctx, tableName) {
|
|
3810
4202
|
const table = await ctx.qr.getTable(tableName);
|
|
3811
4203
|
if (!table) {
|
|
3812
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4204
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.TABLE_MISSING */.M3.TABLE_MISSING, {
|
|
3813
4205
|
table: tableName
|
|
3814
4206
|
}));
|
|
3815
4207
|
}
|
|
@@ -3838,6 +4230,16 @@ class SchemaEvolutionService {
|
|
|
3838
4230
|
indexOn(table, column, unique) {
|
|
3839
4231
|
return table.indices.filter((i)=>i.columnNames.length === 1 && i.columnNames[0] === column && i.isUnique === unique);
|
|
3840
4232
|
}
|
|
4233
|
+
/** `performance.partialIndexes`: plain indexes of a soft-delete entity cover live rows only (PostgreSQL). */ liveOnly(definition, driver) {
|
|
4234
|
+
return !!this.config?.isPartialIndexesEnabled() && definition.isSoftDeleteEnabled && driver === 'postgres';
|
|
4235
|
+
}
|
|
4236
|
+
/** The plain index on `column` exists with the shape the entity wants (live rows only, or all rows). */ hasPlainIndex(table, column, liveOnly) {
|
|
4237
|
+
return this.indexOn(table, column, false).some((index)=>(0,_schema_columns_js__rspack_import_17/* .isLiveRowsIndex */.YS)(index) === liveOnly);
|
|
4238
|
+
}
|
|
4239
|
+
/** Replaces whatever plain index `column` has with one of the wanted shape. */ async rebuildPlainIndex(ctx, table, tableName, column, liveOnly) {
|
|
4240
|
+
for (const index of this.indexOn(table, column, false))await ctx.qr.dropIndex(table, index);
|
|
4241
|
+
await ctx.qr.createIndex(table, (0,_schema_columns_js__rspack_import_17/* .plainIndex */.v7)(tableName, column, ctx.driver, this.adapter, liveOnly));
|
|
4242
|
+
}
|
|
3841
4243
|
// ── add_field ───────────────────────────────────────────────────────────────────────
|
|
3842
4244
|
async prepareAddField(request, user, fieldId) {
|
|
3843
4245
|
const { definition: loaded } = await this.loadEntity(request.entityDefinitionId);
|
|
@@ -3845,11 +4247,11 @@ class SchemaEvolutionService {
|
|
|
3845
4247
|
if (!spec) {
|
|
3846
4248
|
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
3847
4249
|
message: "add_field needs a 'field' definition.",
|
|
3848
|
-
messageKey:
|
|
4250
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .FIELD_DEFINITION_MESSAGES.DEFINITION_REQUIRED */.oc.DEFINITION_REQUIRED
|
|
3849
4251
|
});
|
|
3850
4252
|
}
|
|
3851
|
-
(0,_identifier_rules_js__rspack_import_14/* .assertValidIdentifier */.
|
|
3852
|
-
(0,_identifier_rules_js__rspack_import_14/* .assertIndexableField */.
|
|
4253
|
+
(0,_identifier_rules_js__rspack_import_14/* .assertValidIdentifier */.k)(spec.code, 'field');
|
|
4254
|
+
(0,_identifier_rules_js__rspack_import_14/* .assertIndexableField */.f)(spec);
|
|
3853
4255
|
const lockCodes = await (0,_schema_change_executor_service_js__rspack_import_16/* .relationTargetCodes */.e)(this.dataSourceProvider, [
|
|
3854
4256
|
spec.relationTargetEntityId
|
|
3855
4257
|
]);
|
|
@@ -3857,16 +4259,16 @@ class SchemaEvolutionService {
|
|
|
3857
4259
|
const { definition, fields } = await this.current(ctx, request, loaded.id);
|
|
3858
4260
|
const existing = fields.find((f)=>f.code === spec.code);
|
|
3859
4261
|
if (existing) {
|
|
3860
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(existing.deprecatedAt ?
|
|
4262
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(existing.deprecatedAt ? _config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.FIELD_EXISTS_DEPRECATED */.M3.FIELD_EXISTS_DEPRECATED : _config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.FIELD_EXISTS */.M3.FIELD_EXISTS, {
|
|
3861
4263
|
code: spec.code
|
|
3862
4264
|
}));
|
|
3863
4265
|
}
|
|
3864
4266
|
const nullable = spec.nullable ?? true;
|
|
3865
4267
|
const unique = spec.unique ?? false;
|
|
3866
4268
|
const dbType = this.adapter.mapFieldType(spec.fieldType, ctx.driver);
|
|
3867
|
-
const isRelation = spec.fieldType ===
|
|
4269
|
+
const isRelation = spec.fieldType === _enums_field_type_enum_js__rspack_import_21/* .FieldType.RELATION */.P.RELATION;
|
|
3868
4270
|
if (isRelation && !spec.relationTargetEntityId) {
|
|
3869
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4271
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.RELATION_TARGET_REQUIRED */.M3.RELATION_TARGET_REQUIRED, {
|
|
3870
4272
|
field: spec.code
|
|
3871
4273
|
}));
|
|
3872
4274
|
} else if (isRelation) {
|
|
@@ -3875,18 +4277,14 @@ class SchemaEvolutionService {
|
|
|
3875
4277
|
id: spec.relationTargetEntityId
|
|
3876
4278
|
}
|
|
3877
4279
|
});
|
|
3878
|
-
if (!target) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4280
|
+
if (!target) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.RELATION_TARGET_MISSING */.M3.RELATION_TARGET_MISSING));
|
|
3879
4281
|
}
|
|
3880
|
-
if ((spec.fieldType ===
|
|
3881
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4282
|
+
if ((spec.fieldType === _enums_field_type_enum_js__rspack_import_21/* .FieldType.SINGLE_SELECT */.P.SINGLE_SELECT || spec.fieldType === _enums_field_type_enum_js__rspack_import_21/* .FieldType.MULTI_SELECT */.P.MULTI_SELECT) && !spec.selectOptions?.length) {
|
|
4283
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.NO_SELECT_OPTIONS_YET */.Uu.NO_SELECT_OPTIONS_YET));
|
|
3882
4284
|
}
|
|
3883
4285
|
if (spec.defaultValue !== undefined && spec.defaultValue !== null) {
|
|
3884
|
-
const problem = this.checkValue(
|
|
3885
|
-
|
|
3886
|
-
code: spec.code,
|
|
3887
|
-
fieldType: spec.fieldType
|
|
3888
|
-
}, spec.defaultValue);
|
|
3889
|
-
if (problem) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_19/* .SCHEMA_BLOCKER_MESSAGES.DEFAULT_INVALID */.M3.DEFAULT_INVALID, {
|
|
4286
|
+
const problem = this.checkValue(spec, spec.defaultValue);
|
|
4287
|
+
if (problem) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.DEFAULT_INVALID */.M3.DEFAULT_INVALID, {
|
|
3890
4288
|
problem
|
|
3891
4289
|
}));
|
|
3892
4290
|
}
|
|
@@ -3895,27 +4293,23 @@ class SchemaEvolutionService {
|
|
|
3895
4293
|
const backfill = request.backfillValue ?? spec.defaultValue ?? null;
|
|
3896
4294
|
if (!nullable && rows > 0) {
|
|
3897
4295
|
if (backfill === null) {
|
|
3898
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4296
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.REQUIRED_NEEDS_VALUE */.M3.REQUIRED_NEEDS_VALUE, {
|
|
3899
4297
|
count: rows
|
|
3900
4298
|
}));
|
|
3901
4299
|
} else {
|
|
3902
|
-
const problem = this.checkValue(
|
|
3903
|
-
|
|
3904
|
-
code: spec.code,
|
|
3905
|
-
fieldType: spec.fieldType
|
|
3906
|
-
}, backfill);
|
|
3907
|
-
if (problem) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_19/* .SCHEMA_BLOCKER_MESSAGES.BACKFILL_INVALID */.M3.BACKFILL_INVALID, {
|
|
4300
|
+
const problem = this.checkValue(spec, backfill);
|
|
4301
|
+
if (problem) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.BACKFILL_INVALID */.M3.BACKFILL_INVALID, {
|
|
3908
4302
|
problem
|
|
3909
4303
|
}));
|
|
3910
4304
|
}
|
|
3911
4305
|
}
|
|
3912
4306
|
// Only a required field is backfilled; every existing row gets the same value, so two rows or more would clash.
|
|
3913
4307
|
if (unique && !nullable && backfill !== null && rows > 1) {
|
|
3914
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4308
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.UNIQUE_BACKFILL_CONFLICT */.M3.UNIQUE_BACKFILL_CONFLICT));
|
|
3915
4309
|
}
|
|
3916
4310
|
if (ctx.blocked || !table) {
|
|
3917
4311
|
return {
|
|
3918
|
-
operation:
|
|
4312
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.ADD_COLUMN */.i.ADD_COLUMN,
|
|
3919
4313
|
diff: {}
|
|
3920
4314
|
};
|
|
3921
4315
|
}
|
|
@@ -3929,13 +4323,13 @@ class SchemaEvolutionService {
|
|
|
3929
4323
|
enforceNotNull: false,
|
|
3930
4324
|
withUnique: false
|
|
3931
4325
|
});
|
|
3932
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4326
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.ADD_COLUMN */.EQ.ADD_COLUMN, {
|
|
3933
4327
|
column: spec.code
|
|
3934
4328
|
}), async ()=>{
|
|
3935
4329
|
await ctx.qr.addColumn(table, column);
|
|
3936
4330
|
});
|
|
3937
4331
|
if (!nullable && rows > 0) {
|
|
3938
|
-
await ctx.data((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4332
|
+
await ctx.data((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.BACKFILL_EXISTING */.EQ.BACKFILL_EXISTING, {
|
|
3939
4333
|
count: rows
|
|
3940
4334
|
}), `UPDATE ${ctx.q(definition.tableName)} SET ${ctx.q(spec.code)} = ${this.adapter.sqlLiteral(this.paramValue(spec.fieldType, backfill), ctx.driver)}`, async ()=>{
|
|
3941
4335
|
await ctx.qr.query((0,_flusys_nestjs_shared_classes__rspack_import_0.buildQuery)(`UPDATE ${ctx.q(definition.tableName)} SET ${ctx.q(spec.code)} = ?`, ctx.driver), [
|
|
@@ -3947,17 +4341,17 @@ class SchemaEvolutionService {
|
|
|
3947
4341
|
await this.setRequired(ctx, definition.tableName, spec.code, spec.fieldType, true);
|
|
3948
4342
|
}
|
|
3949
4343
|
if (unique) {
|
|
3950
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4344
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.ADD_UNIQUE */.EQ.ADD_UNIQUE, {
|
|
3951
4345
|
column: spec.code
|
|
3952
4346
|
}), async ()=>{
|
|
3953
4347
|
await (0,_schema_columns_js__rspack_import_17/* .addUnique */.$6)(ctx.qr, table, spec.code, ctx.driver, this.adapter);
|
|
3954
4348
|
});
|
|
3955
4349
|
}
|
|
3956
|
-
if (
|
|
3957
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4350
|
+
if ((0,_schema_columns_js__rspack_import_17/* .indexedByDefault */.w5)(spec) && !unique) {
|
|
4351
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.ADD_INDEX */.EQ.ADD_INDEX, {
|
|
3958
4352
|
column: spec.code
|
|
3959
4353
|
}), async ()=>{
|
|
3960
|
-
await ctx.qr.createIndex(table, (0,_schema_columns_js__rspack_import_17/* .plainIndex */.v7)(definition.tableName, spec.code, ctx.driver, this.adapter));
|
|
4354
|
+
await ctx.qr.createIndex(table, (0,_schema_columns_js__rspack_import_17/* .plainIndex */.v7)(definition.tableName, spec.code, ctx.driver, this.adapter, this.liveOnly(definition, ctx.driver)));
|
|
3961
4355
|
});
|
|
3962
4356
|
}
|
|
3963
4357
|
let savedFieldId = null;
|
|
@@ -3974,7 +4368,7 @@ class SchemaEvolutionService {
|
|
|
3974
4368
|
dbType,
|
|
3975
4369
|
nullable,
|
|
3976
4370
|
unique,
|
|
3977
|
-
isIndexed:
|
|
4371
|
+
isIndexed: (0,_schema_columns_js__rspack_import_17/* .indexedByDefault */.w5)(spec),
|
|
3978
4372
|
defaultValue: spec.defaultValue ?? null,
|
|
3979
4373
|
validationRules: spec.validationRules ?? null,
|
|
3980
4374
|
selectOptions: spec.selectOptions ?? null,
|
|
@@ -3988,7 +4382,7 @@ class SchemaEvolutionService {
|
|
|
3988
4382
|
savedFieldId = saved.id;
|
|
3989
4383
|
});
|
|
3990
4384
|
return {
|
|
3991
|
-
operation:
|
|
4385
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.ADD_COLUMN */.i.ADD_COLUMN,
|
|
3992
4386
|
fieldDefinitionId: savedFieldId,
|
|
3993
4387
|
diff: {
|
|
3994
4388
|
field: {
|
|
@@ -4016,11 +4410,11 @@ class SchemaEvolutionService {
|
|
|
4016
4410
|
if (loadedField.deprecatedAt) {
|
|
4017
4411
|
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
4018
4412
|
message: 'A deprecated field cannot be changed. Restore it first.',
|
|
4019
|
-
messageKey:
|
|
4413
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .FIELD_DEFINITION_MESSAGES.DEPRECATED_LOCKED */.oc.DEPRECATED_LOCKED
|
|
4020
4414
|
});
|
|
4021
4415
|
}
|
|
4022
4416
|
const newCode = typeof changes.code === 'string' && changes.code !== loadedField.code ? changes.code : null;
|
|
4023
|
-
if (newCode) (0,_identifier_rules_js__rspack_import_14/* .assertValidIdentifier */.
|
|
4417
|
+
if (newCode) (0,_identifier_rules_js__rspack_import_14/* .assertValidIdentifier */.k)(newCode, 'field');
|
|
4024
4418
|
const structuralKeys = (field)=>[
|
|
4025
4419
|
'fieldType',
|
|
4026
4420
|
'nullable',
|
|
@@ -4031,7 +4425,7 @@ class SchemaEvolutionService {
|
|
|
4031
4425
|
if (newCode && requested.length) {
|
|
4032
4426
|
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
4033
4427
|
message: `Rename '${loadedField.code}' in its own change - it cannot be combined with: ${requested.join(', ')}.`,
|
|
4034
|
-
messageKey:
|
|
4428
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .FIELD_DEFINITION_MESSAGES.RENAME_ALONE */.oc.RENAME_ALONE,
|
|
4035
4429
|
messageVariables: {
|
|
4036
4430
|
field: loadedField.code,
|
|
4037
4431
|
changes: requested.join(', ')
|
|
@@ -4043,7 +4437,7 @@ class SchemaEvolutionService {
|
|
|
4043
4437
|
'unique',
|
|
4044
4438
|
'isIndexed'
|
|
4045
4439
|
].some((k)=>k in changes)) {
|
|
4046
|
-
(0,_identifier_rules_js__rspack_import_14/* .assertIndexableField */.
|
|
4440
|
+
(0,_identifier_rules_js__rspack_import_14/* .assertIndexableField */.f)({
|
|
4047
4441
|
...loadedField,
|
|
4048
4442
|
...changes,
|
|
4049
4443
|
code: loadedField.code
|
|
@@ -4051,10 +4445,10 @@ class SchemaEvolutionService {
|
|
|
4051
4445
|
}
|
|
4052
4446
|
const targetType = changes.fieldType ?? loadedField.fieldType;
|
|
4053
4447
|
const newTargetId = typeof changes.relationTargetEntityId === 'string' ? changes.relationTargetEntityId : null;
|
|
4054
|
-
if (newTargetId && targetType !==
|
|
4448
|
+
if (newTargetId && targetType !== _enums_field_type_enum_js__rspack_import_21/* .FieldType.RELATION */.P.RELATION) {
|
|
4055
4449
|
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
4056
4450
|
message: 'relationTargetEntityId can only be set on a RELATION field.',
|
|
4057
|
-
messageKey:
|
|
4451
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .SCHEMA_MESSAGES.INVALID_CHANGE_VALUE */.Hu.INVALID_CHANGE_VALUE,
|
|
4058
4452
|
messageVariables: {
|
|
4059
4453
|
property: 'relationTargetEntityId'
|
|
4060
4454
|
}
|
|
@@ -4068,7 +4462,7 @@ class SchemaEvolutionService {
|
|
|
4068
4462
|
const { definition, fields, field } = await this.current(ctx, request, loaded.id, loadedField.id);
|
|
4069
4463
|
if (this.changedUnderneath(ctx, loadedField, field)) {
|
|
4070
4464
|
return {
|
|
4071
|
-
operation:
|
|
4465
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.ALTER_FIELD */.i.ALTER_FIELD,
|
|
4072
4466
|
fieldDefinitionId: field.id,
|
|
4073
4467
|
diff: {}
|
|
4074
4468
|
};
|
|
@@ -4082,7 +4476,7 @@ class SchemaEvolutionService {
|
|
|
4082
4476
|
const table = structural.length || newCode ? await this.requireTable(ctx, definition.tableName) : undefined;
|
|
4083
4477
|
const column = table?.findColumnByName(field.code);
|
|
4084
4478
|
if ((structural.length || newCode) && table && !column) {
|
|
4085
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4479
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.COLUMN_MISSING */.M3.COLUMN_MISSING, {
|
|
4086
4480
|
column: field.code
|
|
4087
4481
|
}));
|
|
4088
4482
|
}
|
|
@@ -4097,10 +4491,10 @@ class SchemaEvolutionService {
|
|
|
4097
4491
|
}
|
|
4098
4492
|
if ('selectOptions' in changes) {
|
|
4099
4493
|
patch.selectOptions = changes.selectOptions;
|
|
4100
|
-
if (merged.fieldType ===
|
|
4494
|
+
if (merged.fieldType === _enums_field_type_enum_js__rspack_import_21/* .FieldType.SINGLE_SELECT */.P.SINGLE_SELECT && Array.isArray(changes.selectOptions) && changes.selectOptions.length && !ctx.blocked) {
|
|
4101
4495
|
const values = changes.selectOptions.map((o)=>String(o.value));
|
|
4102
4496
|
const stray = await this.advisoryScalar(ctx, (0,_flusys_nestjs_shared_classes__rspack_import_0.buildQuery)(`SELECT COUNT(*) AS c FROM ${ctx.q(definition.tableName)} WHERE ${ctx.q(field.code)} IS NOT NULL AND ${ctx.q(field.code)} NOT IN (${values.map(()=>'?').join(', ')})`, ctx.driver), values);
|
|
4103
|
-
if (stray > 0) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4497
|
+
if (stray > 0) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.STRAY_VALUES */.Uu.STRAY_VALUES, {
|
|
4104
4498
|
count: stray
|
|
4105
4499
|
}));
|
|
4106
4500
|
}
|
|
@@ -4108,31 +4502,31 @@ class SchemaEvolutionService {
|
|
|
4108
4502
|
if ('validationRules' in changes) {
|
|
4109
4503
|
patch.validationRules = changes.validationRules;
|
|
4110
4504
|
const rules = changes.validationRules ?? {};
|
|
4111
|
-
const isNumber = merged.fieldType ===
|
|
4505
|
+
const isNumber = merged.fieldType === _enums_field_type_enum_js__rspack_import_21/* .FieldType.INTEGER */.P.INTEGER || merged.fieldType === _enums_field_type_enum_js__rspack_import_21/* .FieldType.DECIMAL */.P.DECIMAL;
|
|
4112
4506
|
const violating = [];
|
|
4113
4507
|
if (isNumber && typeof rules.min === 'number') violating.push(`${ctx.q(field.code)} < ${Number(rules.min)}`);
|
|
4114
4508
|
if (isNumber && typeof rules.max === 'number') violating.push(`${ctx.q(field.code)} > ${Number(rules.max)}`);
|
|
4115
4509
|
if (!isNumber && typeof rules.minLength === 'number') violating.push(`CHAR_LENGTH(${ctx.q(field.code)}) < ${Number(rules.minLength)}`);
|
|
4116
4510
|
if (!isNumber && typeof rules.maxLength === 'number') violating.push(`CHAR_LENGTH(${ctx.q(field.code)}) > ${Number(rules.maxLength)}`);
|
|
4117
4511
|
if (violating.length && [
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4512
|
+
_enums_field_type_enum_js__rspack_import_21/* .FieldType.INTEGER */.P.INTEGER,
|
|
4513
|
+
_enums_field_type_enum_js__rspack_import_21/* .FieldType.DECIMAL */.P.DECIMAL,
|
|
4514
|
+
_enums_field_type_enum_js__rspack_import_21/* .FieldType.TEXT */.P.TEXT,
|
|
4515
|
+
_enums_field_type_enum_js__rspack_import_21/* .FieldType.LONG_TEXT */.P.LONG_TEXT,
|
|
4516
|
+
_enums_field_type_enum_js__rspack_import_21/* .FieldType.EMAIL */.P.EMAIL
|
|
4123
4517
|
].includes(merged.fieldType)) {
|
|
4124
4518
|
const bad = await this.advisoryScalar(ctx, `SELECT COUNT(*) AS c FROM ${ctx.q(definition.tableName)} WHERE ${ctx.q(field.code)} IS NOT NULL AND (${violating.join(' OR ')})`);
|
|
4125
|
-
if (bad > 0) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4519
|
+
if (bad > 0) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.RULES_VIOLATED */.Uu.RULES_VIOLATED, {
|
|
4126
4520
|
count: bad
|
|
4127
4521
|
}));
|
|
4128
4522
|
}
|
|
4129
4523
|
}
|
|
4130
4524
|
// ── relation target ──
|
|
4131
|
-
if (merged.fieldType ===
|
|
4525
|
+
if (merged.fieldType === _enums_field_type_enum_js__rspack_import_21/* .FieldType.RELATION */.P.RELATION) {
|
|
4132
4526
|
const targetId = 'relationTargetEntityId' in changes ? changes.relationTargetEntityId : field.relationTargetEntityId;
|
|
4133
|
-
const becomesRelation = field.fieldType !==
|
|
4527
|
+
const becomesRelation = field.fieldType !== _enums_field_type_enum_js__rspack_import_21/* .FieldType.RELATION */.P.RELATION;
|
|
4134
4528
|
if (!targetId && (becomesRelation || 'relationTargetEntityId' in changes)) {
|
|
4135
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4529
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.RELATION_TARGET_REQUIRED */.M3.RELATION_TARGET_REQUIRED, {
|
|
4136
4530
|
field: field.code
|
|
4137
4531
|
}));
|
|
4138
4532
|
} else if (targetId && (becomesRelation || targetId !== field.relationTargetEntityId)) {
|
|
@@ -4141,7 +4535,7 @@ class SchemaEvolutionService {
|
|
|
4141
4535
|
id: targetId
|
|
4142
4536
|
}
|
|
4143
4537
|
});
|
|
4144
|
-
if (!target) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4538
|
+
if (!target) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.RELATION_TARGET_MISSING */.M3.RELATION_TARGET_MISSING));
|
|
4145
4539
|
else if (target.id !== field.relationTargetEntityId) patch.relationTargetEntityId = target.id;
|
|
4146
4540
|
}
|
|
4147
4541
|
} else if (field.relationTargetEntityId && changes.fieldType !== undefined) {
|
|
@@ -4150,7 +4544,7 @@ class SchemaEvolutionService {
|
|
|
4150
4544
|
if ('defaultValue' in changes) {
|
|
4151
4545
|
if (changes.defaultValue !== null && changes.defaultValue !== undefined) {
|
|
4152
4546
|
const problem = this.checkValue(merged, changes.defaultValue);
|
|
4153
|
-
if (problem) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4547
|
+
if (problem) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.DEFAULT_INVALID */.M3.DEFAULT_INVALID, {
|
|
4154
4548
|
problem
|
|
4155
4549
|
}));
|
|
4156
4550
|
}
|
|
@@ -4169,7 +4563,7 @@ class SchemaEvolutionService {
|
|
|
4169
4563
|
const where = check.badRowsWhere(ctx.q(field.code), ctx.driver);
|
|
4170
4564
|
const bad = await this.scalar(ctx, `SELECT COUNT(*) AS c FROM ${ctx.q(definition.tableName)} WHERE ${ctx.q(field.code)} IS NOT NULL AND (${where})`);
|
|
4171
4565
|
if (bad > 0) {
|
|
4172
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4566
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.CONVERSION_BAD_ROWS */.M3.CONVERSION_BAD_ROWS, {
|
|
4173
4567
|
count: bad,
|
|
4174
4568
|
check: check.description,
|
|
4175
4569
|
from: field.fieldType,
|
|
@@ -4182,12 +4576,12 @@ class SchemaEvolutionService {
|
|
|
4182
4576
|
ctx.markDestructive();
|
|
4183
4577
|
}
|
|
4184
4578
|
const newDefaultProblem = merged.defaultValue !== null && merged.defaultValue !== undefined ? this.checkValue(merged, merged.defaultValue) : null;
|
|
4185
|
-
if (newDefaultProblem) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4579
|
+
if (newDefaultProblem) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.CURRENT_DEFAULT_INVALID */.M3.CURRENT_DEFAULT_INVALID, {
|
|
4186
4580
|
type: merged.fieldType,
|
|
4187
4581
|
problem: newDefaultProblem
|
|
4188
4582
|
}));
|
|
4189
|
-
if ((merged.fieldType ===
|
|
4190
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4583
|
+
if ((merged.fieldType === _enums_field_type_enum_js__rspack_import_21/* .FieldType.SINGLE_SELECT */.P.SINGLE_SELECT || merged.fieldType === _enums_field_type_enum_js__rspack_import_21/* .FieldType.MULTI_SELECT */.P.MULTI_SELECT) && !merged.selectOptions?.length) {
|
|
4584
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.NO_SELECT_OPTIONS_CONVERT */.Uu.NO_SELECT_OPTIONS_CONVERT));
|
|
4191
4585
|
}
|
|
4192
4586
|
if (!ctx.blocked) {
|
|
4193
4587
|
const newDbType = this.adapter.mapFieldType(merged.fieldType, ctx.driver);
|
|
@@ -4199,7 +4593,7 @@ class SchemaEvolutionService {
|
|
|
4199
4593
|
const nullSql = column.isNullable ? 'NULL' : 'NOT NULL';
|
|
4200
4594
|
const up = ctx.driver === 'postgres' ? `ALTER TABLE ${t} ALTER COLUMN ${c} TYPE ${to} USING ${conversion.using ? conversion.using(c) : `${c}::${to}`}` : `ALTER TABLE ${t} MODIFY ${c} ${to} ${nullSql}`;
|
|
4201
4595
|
const down = ctx.driver === 'postgres' ? `ALTER TABLE ${t} ALTER COLUMN ${c} TYPE ${from} USING ${c}::${from}` : `ALTER TABLE ${t} MODIFY ${c} ${from} ${nullSql}`;
|
|
4202
|
-
await ctx.rawDdl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4596
|
+
await ctx.rawDdl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.CONVERT_TYPE */.EQ.CONVERT_TYPE, {
|
|
4203
4597
|
column: field.code,
|
|
4204
4598
|
from: field.fieldType,
|
|
4205
4599
|
to: merged.fieldType
|
|
@@ -4220,21 +4614,21 @@ class SchemaEvolutionService {
|
|
|
4220
4614
|
const nulls = await this.scalar(ctx, `SELECT COUNT(*) AS c FROM ${ctx.q(definition.tableName)} WHERE ${ctx.q(field.code)} IS NULL`);
|
|
4221
4615
|
const value = request.backfillValue ?? merged.defaultValue ?? null;
|
|
4222
4616
|
if (nulls > 0 && value === null) {
|
|
4223
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4617
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.NULLS_NEED_VALUE */.M3.NULLS_NEED_VALUE, {
|
|
4224
4618
|
count: nulls,
|
|
4225
4619
|
field: field.code
|
|
4226
4620
|
}));
|
|
4227
4621
|
} else if (nulls > 0) {
|
|
4228
4622
|
const problem = this.checkValue(merged, value);
|
|
4229
|
-
if (problem) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4623
|
+
if (problem) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.BACKFILL_INVALID */.M3.BACKFILL_INVALID, {
|
|
4230
4624
|
problem
|
|
4231
4625
|
}));
|
|
4232
4626
|
else {
|
|
4233
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4627
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.BACKFILL_WILL_SET */.Uu.BACKFILL_WILL_SET, {
|
|
4234
4628
|
count: nulls,
|
|
4235
4629
|
value: JSON.stringify(value)
|
|
4236
4630
|
}));
|
|
4237
|
-
await ctx.data((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4631
|
+
await ctx.data((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.BACKFILL_RECORDS */.EQ.BACKFILL_RECORDS, {
|
|
4238
4632
|
count: nulls
|
|
4239
4633
|
}), `UPDATE ${ctx.q(definition.tableName)} SET ${ctx.q(field.code)} = ${this.adapter.sqlLiteral(this.paramValue(merged.fieldType, value), ctx.driver)} WHERE ${ctx.q(field.code)} IS NULL`, async ()=>{
|
|
4240
4634
|
await ctx.qr.query((0,_flusys_nestjs_shared_classes__rspack_import_0.buildQuery)(`UPDATE ${ctx.q(definition.tableName)} SET ${ctx.q(field.code)} = ? WHERE ${ctx.q(field.code)} IS NULL`, ctx.driver), [
|
|
@@ -4256,19 +4650,19 @@ class SchemaEvolutionService {
|
|
|
4256
4650
|
if (changes.unique === true) {
|
|
4257
4651
|
const dups = await this.countDuplicates(ctx, definition.tableName, field.code);
|
|
4258
4652
|
if (dups > 0) {
|
|
4259
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4653
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.DUPLICATE_VALUES */.M3.DUPLICATE_VALUES, {
|
|
4260
4654
|
count: dups,
|
|
4261
4655
|
field: field.code
|
|
4262
4656
|
}));
|
|
4263
4657
|
} else {
|
|
4264
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4658
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.ADD_UNIQUE */.EQ.ADD_UNIQUE, {
|
|
4265
4659
|
column: field.code
|
|
4266
4660
|
}), async ()=>{
|
|
4267
4661
|
await (0,_schema_columns_js__rspack_import_17/* .addUnique */.$6)(ctx.qr, table, field.code, ctx.driver, this.adapter);
|
|
4268
4662
|
});
|
|
4269
4663
|
}
|
|
4270
4664
|
} else {
|
|
4271
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4665
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.REMOVE_UNIQUE */.EQ.REMOVE_UNIQUE, {
|
|
4272
4666
|
column: field.code
|
|
4273
4667
|
}), async ()=>this.dropUniques(ctx, table, field.code));
|
|
4274
4668
|
}
|
|
@@ -4277,13 +4671,13 @@ class SchemaEvolutionService {
|
|
|
4277
4671
|
// ── index ──
|
|
4278
4672
|
if (changes.isIndexed !== undefined && changes.isIndexed !== field.isIndexed && table && column && !ctx.blocked) {
|
|
4279
4673
|
if (changes.isIndexed) {
|
|
4280
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4674
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.ADD_INDEX */.EQ.ADD_INDEX, {
|
|
4281
4675
|
column: field.code
|
|
4282
4676
|
}), async ()=>{
|
|
4283
|
-
await ctx.qr.createIndex(table, (0,_schema_columns_js__rspack_import_17/* .plainIndex */.v7)(definition.tableName, field.code, ctx.driver, this.adapter));
|
|
4677
|
+
await ctx.qr.createIndex(table, (0,_schema_columns_js__rspack_import_17/* .plainIndex */.v7)(definition.tableName, field.code, ctx.driver, this.adapter, this.liveOnly(definition, ctx.driver)));
|
|
4284
4678
|
});
|
|
4285
4679
|
} else {
|
|
4286
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4680
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.REMOVE_INDEX */.EQ.REMOVE_INDEX, {
|
|
4287
4681
|
column: field.code
|
|
4288
4682
|
}), async ()=>{
|
|
4289
4683
|
for (const idx of this.indexOn(table, field.code, false))await ctx.qr.dropIndex(table, idx);
|
|
@@ -4294,22 +4688,22 @@ class SchemaEvolutionService {
|
|
|
4294
4688
|
// ── rename ──
|
|
4295
4689
|
if (newCode && table && column) {
|
|
4296
4690
|
const taken = fields.find((f)=>f.code === newCode);
|
|
4297
|
-
if (taken) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(taken.deprecatedAt ?
|
|
4691
|
+
if (taken) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(taken.deprecatedAt ? _config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.FIELD_CODE_TAKEN_DEPRECATED */.M3.FIELD_CODE_TAKEN_DEPRECATED : _config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.FIELD_CODE_TAKEN */.M3.FIELD_CODE_TAKEN, {
|
|
4298
4692
|
code: newCode
|
|
4299
4693
|
}));
|
|
4300
4694
|
if (impact.length && request.rewriteReferences === false) {
|
|
4301
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4695
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.RENAME_IN_USE */.M3.RENAME_IN_USE, {
|
|
4302
4696
|
field: field.code,
|
|
4303
|
-
references: (0,
|
|
4697
|
+
references: (0,_schema_change_types_js__rspack_import_23/* .describeImpact */.a)(impact)
|
|
4304
4698
|
}));
|
|
4305
4699
|
} else if (impact.length) {
|
|
4306
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4700
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.REFERENCES_REWRITTEN */.Uu.REFERENCES_REWRITTEN, {
|
|
4307
4701
|
count: impact.length,
|
|
4308
4702
|
code: newCode
|
|
4309
4703
|
}));
|
|
4310
4704
|
}
|
|
4311
4705
|
if (!ctx.blocked) {
|
|
4312
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4706
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.RENAME_COLUMN */.EQ.RENAME_COLUMN, {
|
|
4313
4707
|
from: field.code,
|
|
4314
4708
|
to: newCode
|
|
4315
4709
|
}), async ()=>{
|
|
@@ -4318,15 +4712,14 @@ class SchemaEvolutionService {
|
|
|
4318
4712
|
// TypeORM moves the index/unique onto the renamed column but keeps its name, which is
|
|
4319
4713
|
// derived from the old code - recreate them so a new field with the old code can have its own.
|
|
4320
4714
|
if (field.isIndexed && !field.unique) {
|
|
4321
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4715
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.RENAME_INDEX */.EQ.RENAME_INDEX, {
|
|
4322
4716
|
column: field.code
|
|
4323
4717
|
}), async ()=>{
|
|
4324
|
-
|
|
4325
|
-
await ctx.qr.createIndex(table, (0,_schema_columns_js__rspack_import_17/* .plainIndex */.v7)(definition.tableName, newCode, ctx.driver, this.adapter));
|
|
4718
|
+
await this.rebuildPlainIndex(ctx, table, definition.tableName, newCode, this.liveOnly(definition, ctx.driver));
|
|
4326
4719
|
});
|
|
4327
4720
|
}
|
|
4328
4721
|
if (field.unique) {
|
|
4329
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4722
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.RENAME_INDEX */.EQ.RENAME_INDEX, {
|
|
4330
4723
|
column: field.code
|
|
4331
4724
|
}), async ()=>{
|
|
4332
4725
|
await this.dropUniques(ctx, table, newCode);
|
|
@@ -4337,7 +4730,7 @@ class SchemaEvolutionService {
|
|
|
4337
4730
|
}
|
|
4338
4731
|
}
|
|
4339
4732
|
if (ctx.blocked) return {
|
|
4340
|
-
operation:
|
|
4733
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.ALTER_FIELD */.i.ALTER_FIELD,
|
|
4341
4734
|
fieldDefinitionId: field.id,
|
|
4342
4735
|
diff: {}
|
|
4343
4736
|
};
|
|
@@ -4349,7 +4742,7 @@ class SchemaEvolutionService {
|
|
|
4349
4742
|
});
|
|
4350
4743
|
const metadataOnly = !structural.length && !newCode;
|
|
4351
4744
|
return {
|
|
4352
|
-
operation: newCode ?
|
|
4745
|
+
operation: newCode ? _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.RENAME_FIELD */.i.RENAME_FIELD : _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.ALTER_FIELD */.i.ALTER_FIELD,
|
|
4353
4746
|
fieldDefinitionId: field.id,
|
|
4354
4747
|
diff: {
|
|
4355
4748
|
field: field.code,
|
|
@@ -4360,13 +4753,7 @@ class SchemaEvolutionService {
|
|
|
4360
4753
|
])),
|
|
4361
4754
|
after: patch
|
|
4362
4755
|
},
|
|
4363
|
-
bumpVersion: !metadataOnly || Object.keys(patch).some((k)=>
|
|
4364
|
-
'selectOptions',
|
|
4365
|
-
'validationRules',
|
|
4366
|
-
'defaultValue',
|
|
4367
|
-
'label',
|
|
4368
|
-
'relationTargetEntityId'
|
|
4369
|
-
].includes(k))
|
|
4756
|
+
bumpVersion: !metadataOnly || Object.keys(patch).some((k)=>FIELD_CACHE_KEYS.has(k))
|
|
4370
4757
|
};
|
|
4371
4758
|
};
|
|
4372
4759
|
return {
|
|
@@ -4381,23 +4768,23 @@ class SchemaEvolutionService {
|
|
|
4381
4768
|
const impact = await this.references.forField(loaded.code, loadedField.code);
|
|
4382
4769
|
const run = async (ctx)=>{
|
|
4383
4770
|
const { definition, field } = await this.current(ctx, request, loaded.id, loadedField.id);
|
|
4384
|
-
if (field.code !== loadedField.code) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4385
|
-
if (field.deprecatedAt) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4771
|
+
if (field.code !== loadedField.code) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.DEFINITION_CHANGED */.M3.DEFINITION_CHANGED));
|
|
4772
|
+
if (field.deprecatedAt) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.ALREADY_DEPRECATED */.M3.ALREADY_DEPRECATED, {
|
|
4386
4773
|
field: field.code
|
|
4387
4774
|
}));
|
|
4388
|
-
if (impact.length) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4389
|
-
references: (0,
|
|
4775
|
+
if (impact.length) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.STILL_REFERENCED */.Uu.STILL_REFERENCED, {
|
|
4776
|
+
references: (0,_schema_change_types_js__rspack_import_23/* .describeImpact */.a)(impact)
|
|
4390
4777
|
}));
|
|
4391
4778
|
const table = await this.requireTable(ctx, definition.tableName);
|
|
4392
4779
|
const column = table?.findColumnByName(field.code);
|
|
4393
4780
|
if (ctx.blocked) return {
|
|
4394
|
-
operation:
|
|
4781
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.MARK_DEPRECATED */.i.MARK_DEPRECATED,
|
|
4395
4782
|
fieldDefinitionId: field.id,
|
|
4396
4783
|
diff: {}
|
|
4397
4784
|
};
|
|
4398
4785
|
// A hidden NOT NULL column would make every new record fail (nobody supplies it any more).
|
|
4399
4786
|
if (column && !column.isNullable) {
|
|
4400
|
-
await this.setRequired(ctx, definition.tableName, field.code, field.fieldType, false,
|
|
4787
|
+
await this.setRequired(ctx, definition.tableName, field.code, field.fieldType, false, _config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.RELAX_DEPRECATED */.EQ.RELAX_DEPRECATED);
|
|
4401
4788
|
}
|
|
4402
4789
|
await ctx.metadata(async ()=>{
|
|
4403
4790
|
await ctx.qr.manager.getRepository(_entities_field_definition_entity_js__rspack_import_8/* .FieldDefinition */.c).update(field.id, {
|
|
@@ -4406,7 +4793,7 @@ class SchemaEvolutionService {
|
|
|
4406
4793
|
});
|
|
4407
4794
|
});
|
|
4408
4795
|
return {
|
|
4409
|
-
operation:
|
|
4796
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.MARK_DEPRECATED */.i.MARK_DEPRECATED,
|
|
4410
4797
|
fieldDefinitionId: field.id,
|
|
4411
4798
|
diff: {
|
|
4412
4799
|
field: field.code
|
|
@@ -4423,15 +4810,15 @@ class SchemaEvolutionService {
|
|
|
4423
4810
|
const { field: loadedField, definition: loaded } = await this.loadField(request.fieldDefinitionId);
|
|
4424
4811
|
const run = async (ctx)=>{
|
|
4425
4812
|
const { definition, field } = await this.current(ctx, request, loaded.id, loadedField.id);
|
|
4426
|
-
if (!field.deprecatedAt) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4813
|
+
if (!field.deprecatedAt) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.NOT_DEPRECATED */.M3.NOT_DEPRECATED, {
|
|
4427
4814
|
field: field.code
|
|
4428
4815
|
}));
|
|
4429
4816
|
const table = await this.requireTable(ctx, definition.tableName);
|
|
4430
|
-
if (table && !table.findColumnByName(field.code)) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4817
|
+
if (table && !table.findColumnByName(field.code)) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.COLUMN_GONE */.M3.COLUMN_GONE, {
|
|
4431
4818
|
column: field.code
|
|
4432
4819
|
}));
|
|
4433
4820
|
if (ctx.blocked) return {
|
|
4434
|
-
operation:
|
|
4821
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.RESTORE_FIELD */.i.RESTORE_FIELD,
|
|
4435
4822
|
fieldDefinitionId: field.id,
|
|
4436
4823
|
diff: {}
|
|
4437
4824
|
};
|
|
@@ -4440,9 +4827,9 @@ class SchemaEvolutionService {
|
|
|
4440
4827
|
deprecatedAt: null
|
|
4441
4828
|
});
|
|
4442
4829
|
});
|
|
4443
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4830
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.FIELD_OPTIONAL_AGAIN */.Uu.FIELD_OPTIONAL_AGAIN));
|
|
4444
4831
|
return {
|
|
4445
|
-
operation:
|
|
4832
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.RESTORE_FIELD */.i.RESTORE_FIELD,
|
|
4446
4833
|
fieldDefinitionId: field.id,
|
|
4447
4834
|
diff: {
|
|
4448
4835
|
field: field.code
|
|
@@ -4461,45 +4848,45 @@ class SchemaEvolutionService {
|
|
|
4461
4848
|
const run = async (ctx)=>{
|
|
4462
4849
|
const { definition, field } = await this.current(ctx, request, loaded.id, loadedField.id);
|
|
4463
4850
|
if (this.changedUnderneath(ctx, loadedField, field)) return {
|
|
4464
|
-
operation:
|
|
4851
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.DROP_COLUMN */.i.DROP_COLUMN,
|
|
4465
4852
|
fieldDefinitionId: field.id,
|
|
4466
4853
|
diff: {}
|
|
4467
4854
|
};
|
|
4468
|
-
if (!field.deprecatedAt) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4469
|
-
if (request.confirmCode !== field.code) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4855
|
+
if (!field.deprecatedAt) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.PURGE_REQUIRES_DEPRECATED */.M3.PURGE_REQUIRES_DEPRECATED));
|
|
4856
|
+
if (request.confirmCode !== field.code) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.PURGE_CONFIRM_CODE */.M3.PURGE_CONFIRM_CODE, {
|
|
4470
4857
|
code: field.code
|
|
4471
4858
|
}));
|
|
4472
|
-
if (impact.length) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4859
|
+
if (impact.length) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.PURGE_IN_USE */.M3.PURGE_IN_USE, {
|
|
4473
4860
|
field: field.code,
|
|
4474
|
-
references: (0,
|
|
4861
|
+
references: (0,_schema_change_types_js__rspack_import_23/* .describeImpact */.a)(impact)
|
|
4475
4862
|
}));
|
|
4476
4863
|
const table = await this.requireTable(ctx, definition.tableName);
|
|
4477
4864
|
const column = table?.findColumnByName(field.code);
|
|
4478
4865
|
if (ctx.blocked) return {
|
|
4479
|
-
operation:
|
|
4866
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.DROP_COLUMN */.i.DROP_COLUMN,
|
|
4480
4867
|
fieldDefinitionId: field.id,
|
|
4481
4868
|
diff: {}
|
|
4482
4869
|
};
|
|
4483
4870
|
if (table && column) {
|
|
4484
4871
|
const values = await this.scalar(ctx, `SELECT COUNT(*) AS c FROM ${ctx.q(definition.tableName)} WHERE ${ctx.q(field.code)} IS NOT NULL`);
|
|
4485
4872
|
ctx.setAffectedRows(values);
|
|
4486
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4873
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.VALUES_DELETED */.Uu.VALUES_DELETED, {
|
|
4487
4874
|
count: values
|
|
4488
4875
|
}));
|
|
4489
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4876
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.DROP_COLUMN */.EQ.DROP_COLUMN, {
|
|
4490
4877
|
column: field.code
|
|
4491
4878
|
}), async ()=>{
|
|
4492
4879
|
await ctx.qr.dropColumn(table, column);
|
|
4493
4880
|
});
|
|
4494
4881
|
} else {
|
|
4495
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4882
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.COLUMN_ALREADY_MISSING */.Uu.COLUMN_ALREADY_MISSING));
|
|
4496
4883
|
}
|
|
4497
4884
|
ctx.markDestructive();
|
|
4498
4885
|
await ctx.metadata(async ()=>{
|
|
4499
4886
|
await ctx.qr.manager.getRepository(_entities_field_definition_entity_js__rspack_import_8/* .FieldDefinition */.c).delete(field.id);
|
|
4500
4887
|
});
|
|
4501
4888
|
return {
|
|
4502
|
-
operation:
|
|
4889
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.DROP_COLUMN */.i.DROP_COLUMN,
|
|
4503
4890
|
fieldDefinitionId: null,
|
|
4504
4891
|
diff: {
|
|
4505
4892
|
field: field.code,
|
|
@@ -4519,16 +4906,16 @@ class SchemaEvolutionService {
|
|
|
4519
4906
|
const changes = request.changes ?? {};
|
|
4520
4907
|
this.rejectUnknownKeys(changes, _dtos_schema_change_dto_js__rspack_import_6/* .ENTITY_CHANGE_KEYS */.Oi, 'entity');
|
|
4521
4908
|
if (changes.status !== undefined && ![
|
|
4522
|
-
|
|
4523
|
-
|
|
4909
|
+
_enums_entity_status_enum_js__rspack_import_24/* .EntityStatus.ACTIVE */.c.ACTIVE,
|
|
4910
|
+
_enums_entity_status_enum_js__rspack_import_24/* .EntityStatus.DEPRECATED */.c.DEPRECATED
|
|
4524
4911
|
].includes(changes.status)) {
|
|
4525
4912
|
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
4526
4913
|
message: "status must be 'ACTIVE' or 'DEPRECATED'.",
|
|
4527
|
-
messageKey:
|
|
4914
|
+
messageKey: _config_message_keys_js__rspack_import_20/* .ENTITY_DEFINITION_MESSAGES.INVALID_STATUS */.pL.INVALID_STATUS
|
|
4528
4915
|
});
|
|
4529
4916
|
}
|
|
4530
4917
|
this.validateChanges(_dtos_schema_change_dto_js__rspack_import_6/* .EntityChangesDto */.OW, changes);
|
|
4531
|
-
const impact = changes.status ===
|
|
4918
|
+
const impact = changes.status === _enums_entity_status_enum_js__rspack_import_24/* .EntityStatus.DEPRECATED */.c.DEPRECATED ? await this.references.forEntity(loaded.code) : [];
|
|
4532
4919
|
const run = async (ctx)=>{
|
|
4533
4920
|
const { definition } = await this.current(ctx, request, loaded.id);
|
|
4534
4921
|
const patch = {};
|
|
@@ -4545,37 +4932,38 @@ class SchemaEvolutionService {
|
|
|
4545
4932
|
const touchesColumns = wantsSoft === true && !definition.isSoftDeleteEnabled || wantsAudit === true && !definition.isAuditEnabled;
|
|
4546
4933
|
const table = touchesColumns ? await this.requireTable(ctx, definition.tableName) : undefined;
|
|
4547
4934
|
if (ctx.blocked) return {
|
|
4548
|
-
operation:
|
|
4935
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.ALTER_ENTITY */.i.ALTER_ENTITY,
|
|
4549
4936
|
diff: {}
|
|
4550
4937
|
};
|
|
4551
4938
|
if (wantsSoft !== undefined && wantsSoft !== definition.isSoftDeleteEnabled) {
|
|
4552
4939
|
if (wantsSoft && table) {
|
|
4553
4940
|
if (!table.findColumnByName('deleted_at')) {
|
|
4554
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4941
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.ADD_DELETED_AT */.EQ.ADD_DELETED_AT), async ()=>{
|
|
4555
4942
|
await ctx.qr.addColumn(table, (0,_schema_columns_js__rspack_import_17/* .softDeleteColumn */.OG)());
|
|
4556
4943
|
});
|
|
4557
4944
|
}
|
|
4558
4945
|
} else if (!wantsSoft) {
|
|
4559
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4946
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.SOFT_DELETE_OFF */.Uu.SOFT_DELETE_OFF));
|
|
4560
4947
|
ctx.markDestructive();
|
|
4561
4948
|
}
|
|
4562
4949
|
patch.isSoftDeleteEnabled = wantsSoft;
|
|
4950
|
+
await this.reshapePlainIndexes(ctx, definition, wantsSoft);
|
|
4563
4951
|
}
|
|
4564
4952
|
if (wantsAudit !== undefined && wantsAudit !== definition.isAuditEnabled) {
|
|
4565
4953
|
if (wantsAudit && table) {
|
|
4566
4954
|
const missing = (0,_schema_columns_js__rspack_import_17/* .auditColumns */.HK)(ctx.driver).filter((c)=>!table.findColumnByName(c.name));
|
|
4567
4955
|
if (missing.length) {
|
|
4568
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4956
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.ADD_AUDIT_COLUMNS */.EQ.ADD_AUDIT_COLUMNS), async ()=>{
|
|
4569
4957
|
for (const c of missing)await ctx.qr.addColumn(table, c);
|
|
4570
4958
|
});
|
|
4571
4959
|
}
|
|
4572
4960
|
} else if (!wantsAudit) {
|
|
4573
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4961
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.AUDIT_OFF */.Uu.AUDIT_OFF));
|
|
4574
4962
|
}
|
|
4575
4963
|
patch.isAuditEnabled = wantsAudit;
|
|
4576
4964
|
}
|
|
4577
|
-
if (changes.status ===
|
|
4578
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4965
|
+
if (changes.status === _enums_entity_status_enum_js__rspack_import_24/* .EntityStatus.DEPRECATED */.c.DEPRECATED && impact.length) {
|
|
4966
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.ENTITY_REFERENCED */.Uu.ENTITY_REFERENCED, {
|
|
4579
4967
|
count: impact.length
|
|
4580
4968
|
}));
|
|
4581
4969
|
}
|
|
@@ -4583,7 +4971,7 @@ class SchemaEvolutionService {
|
|
|
4583
4971
|
if (Object.keys(patch).length) await ctx.qr.manager.getRepository(_entities_entity_definition_entity_js__rspack_import_7/* .EntityDefinition */.f).update(definition.id, patch);
|
|
4584
4972
|
});
|
|
4585
4973
|
return {
|
|
4586
|
-
operation:
|
|
4974
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.ALTER_ENTITY */.i.ALTER_ENTITY,
|
|
4587
4975
|
diff: {
|
|
4588
4976
|
changed: Object.keys(patch),
|
|
4589
4977
|
after: patch
|
|
@@ -4596,6 +4984,32 @@ class SchemaEvolutionService {
|
|
|
4596
4984
|
impact
|
|
4597
4985
|
};
|
|
4598
4986
|
}
|
|
4987
|
+
/**
|
|
4988
|
+
* Soft delete switched on or off: a plain index over live rows only is of no use to reads that no longer
|
|
4989
|
+
* ask for live rows (and the other way round), so every plain index takes the shape the entity now wants.
|
|
4990
|
+
*/ async reshapePlainIndexes(ctx, definition, softDelete) {
|
|
4991
|
+
if (ctx.driver !== 'postgres') return;
|
|
4992
|
+
const table = await ctx.qr.getTable(definition.tableName);
|
|
4993
|
+
if (!table) return;
|
|
4994
|
+
const liveOnly = this.liveOnly({
|
|
4995
|
+
isSoftDeleteEnabled: softDelete
|
|
4996
|
+
}, ctx.driver);
|
|
4997
|
+
const fields = await ctx.qr.manager.getRepository(_entities_field_definition_entity_js__rspack_import_8/* .FieldDefinition */.c).find({
|
|
4998
|
+
where: {
|
|
4999
|
+
entityDefinitionId: definition.id
|
|
5000
|
+
}
|
|
5001
|
+
});
|
|
5002
|
+
for (const field of fields.filter((f)=>f.isIndexed && !f.unique && table.findColumnByName(f.code))){
|
|
5003
|
+
// A missing index is left to `repair`; only one of the wrong shape is rebuilt here.
|
|
5004
|
+
const existing = this.indexOn(table, field.code, false);
|
|
5005
|
+
if (!existing.length || existing.every((index)=>(0,_schema_columns_js__rspack_import_17/* .isLiveRowsIndex */.YS)(index) === liveOnly)) continue;
|
|
5006
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.RECREATE_INDEX */.EQ.RECREATE_INDEX, {
|
|
5007
|
+
column: field.code
|
|
5008
|
+
}), async ()=>{
|
|
5009
|
+
await this.rebuildPlainIndex(ctx, table, definition.tableName, field.code, liveOnly);
|
|
5010
|
+
});
|
|
5011
|
+
}
|
|
5012
|
+
}
|
|
4599
5013
|
/** `"orders.customer_id", ...` - relation fields of other entities that point at this one. */ async relationsInto(ctx, definition) {
|
|
4600
5014
|
const pointing = (await ctx.qr.manager.getRepository(_entities_field_definition_entity_js__rspack_import_8/* .FieldDefinition */.c).find({
|
|
4601
5015
|
where: {
|
|
@@ -4621,34 +5035,34 @@ class SchemaEvolutionService {
|
|
|
4621
5035
|
const impact = await this.references.forEntity(loaded.code);
|
|
4622
5036
|
const run = async (ctx)=>{
|
|
4623
5037
|
const { definition } = await this.current(ctx, request, loaded.id);
|
|
4624
|
-
if (request.confirmCode !== definition.code) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5038
|
+
if (request.confirmCode !== definition.code) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.DROP_CONFIRM_CODE */.M3.DROP_CONFIRM_CODE, {
|
|
4625
5039
|
code: definition.code
|
|
4626
5040
|
}));
|
|
4627
|
-
if (impact.length) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
4628
|
-
references: (0,
|
|
5041
|
+
if (impact.length) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.DROP_IN_USE */.M3.DROP_IN_USE, {
|
|
5042
|
+
references: (0,_schema_change_types_js__rspack_import_23/* .describeImpact */.a)(impact)
|
|
4629
5043
|
}));
|
|
4630
5044
|
const relations = await this.relationsInto(ctx, definition);
|
|
4631
|
-
if (relations) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5045
|
+
if (relations) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_BLOCKER_MESSAGES.DROP_RELATION_IN_USE */.M3.DROP_RELATION_IN_USE, {
|
|
4632
5046
|
fields: relations
|
|
4633
5047
|
}));
|
|
4634
5048
|
const table = await ctx.qr.getTable(definition.tableName);
|
|
4635
5049
|
if (ctx.blocked) return {
|
|
4636
|
-
operation:
|
|
5050
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.DROP_TABLE */.i.DROP_TABLE,
|
|
4637
5051
|
diff: {}
|
|
4638
5052
|
};
|
|
4639
5053
|
if (table) {
|
|
4640
5054
|
const rows = await this.scalar(ctx, `SELECT COUNT(*) AS c FROM ${ctx.q(definition.tableName)}`);
|
|
4641
5055
|
ctx.setAffectedRows(rows);
|
|
4642
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5056
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.RECORDS_DELETED */.Uu.RECORDS_DELETED, {
|
|
4643
5057
|
count: rows
|
|
4644
5058
|
}));
|
|
4645
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5059
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.DROP_TABLE */.EQ.DROP_TABLE, {
|
|
4646
5060
|
table: definition.tableName
|
|
4647
5061
|
}), async ()=>{
|
|
4648
5062
|
await ctx.qr.dropTable(table);
|
|
4649
5063
|
});
|
|
4650
5064
|
} else {
|
|
4651
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5065
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.TABLE_ALREADY_MISSING */.Uu.TABLE_ALREADY_MISSING));
|
|
4652
5066
|
}
|
|
4653
5067
|
ctx.markDestructive();
|
|
4654
5068
|
await ctx.metadata(async ()=>{
|
|
@@ -4658,7 +5072,7 @@ class SchemaEvolutionService {
|
|
|
4658
5072
|
await ctx.qr.manager.getRepository(_entities_entity_definition_entity_js__rspack_import_7/* .EntityDefinition */.f).delete(definition.id);
|
|
4659
5073
|
});
|
|
4660
5074
|
return {
|
|
4661
|
-
operation:
|
|
5075
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.DROP_TABLE */.i.DROP_TABLE,
|
|
4662
5076
|
diff: {
|
|
4663
5077
|
entity: definition.code
|
|
4664
5078
|
},
|
|
@@ -4679,7 +5093,7 @@ class SchemaEvolutionService {
|
|
|
4679
5093
|
findings.push({
|
|
4680
5094
|
kind: 'missing_table',
|
|
4681
5095
|
severity: 'error',
|
|
4682
|
-
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5096
|
+
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_FINDING_MESSAGES.MISSING_TABLE */.Vu.MISSING_TABLE, {
|
|
4683
5097
|
table: definition.tableName
|
|
4684
5098
|
}),
|
|
4685
5099
|
repairable: true
|
|
@@ -4699,7 +5113,7 @@ class SchemaEvolutionService {
|
|
|
4699
5113
|
kind: 'missing_column',
|
|
4700
5114
|
severity: 'error',
|
|
4701
5115
|
field: name,
|
|
4702
|
-
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5116
|
+
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_FINDING_MESSAGES.SYSTEM_COLUMN_MISSING */.Vu.SYSTEM_COLUMN_MISSING, {
|
|
4703
5117
|
column: name
|
|
4704
5118
|
}),
|
|
4705
5119
|
repairable: name !== 'id'
|
|
@@ -4714,7 +5128,7 @@ class SchemaEvolutionService {
|
|
|
4714
5128
|
kind: 'missing_column',
|
|
4715
5129
|
severity: field.deprecatedAt ? 'warning' : 'error',
|
|
4716
5130
|
field: field.code,
|
|
4717
|
-
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5131
|
+
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_FINDING_MESSAGES.COLUMN_MISSING */.Vu.COLUMN_MISSING, {
|
|
4718
5132
|
column: field.code
|
|
4719
5133
|
}),
|
|
4720
5134
|
repairable: true
|
|
@@ -4729,7 +5143,7 @@ class SchemaEvolutionService {
|
|
|
4729
5143
|
kind: 'type_mismatch',
|
|
4730
5144
|
severity: 'error',
|
|
4731
5145
|
field: field.code,
|
|
4732
|
-
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5146
|
+
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_FINDING_MESSAGES.TYPE_MISMATCH */.Vu.TYPE_MISMATCH, {
|
|
4733
5147
|
column: field.code,
|
|
4734
5148
|
actual: column.type,
|
|
4735
5149
|
fieldType: field.fieldType,
|
|
@@ -4743,7 +5157,7 @@ class SchemaEvolutionService {
|
|
|
4743
5157
|
kind: 'nullability_mismatch',
|
|
4744
5158
|
severity: 'warning',
|
|
4745
5159
|
field: field.code,
|
|
4746
|
-
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5160
|
+
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_FINDING_MESSAGES.REQUIRED_BUT_NULLABLE */.Vu.REQUIRED_BUT_NULLABLE, {
|
|
4747
5161
|
column: field.code
|
|
4748
5162
|
}),
|
|
4749
5163
|
repairable: true
|
|
@@ -4754,18 +5168,19 @@ class SchemaEvolutionService {
|
|
|
4754
5168
|
kind: 'nullability_mismatch',
|
|
4755
5169
|
severity: 'warning',
|
|
4756
5170
|
field: field.code,
|
|
4757
|
-
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5171
|
+
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_FINDING_MESSAGES.OPTIONAL_BUT_NOT_NULL */.Vu.OPTIONAL_BUT_NOT_NULL, {
|
|
4758
5172
|
column: field.code
|
|
4759
5173
|
}),
|
|
4760
5174
|
repairable: true
|
|
4761
5175
|
});
|
|
4762
5176
|
}
|
|
4763
|
-
|
|
5177
|
+
// A plain index of the other shape (live rows only / all rows) counts as missing: repair rebuilds it.
|
|
5178
|
+
if (field.isIndexed && !field.unique && !this.hasPlainIndex(table, field.code, this.liveOnly(definition, driver))) {
|
|
4764
5179
|
findings.push({
|
|
4765
5180
|
kind: 'missing_index',
|
|
4766
5181
|
severity: 'warning',
|
|
4767
5182
|
field: field.code,
|
|
4768
|
-
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5183
|
+
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_FINDING_MESSAGES.INDEX_MISSING */.Vu.INDEX_MISSING, {
|
|
4769
5184
|
column: field.code
|
|
4770
5185
|
}),
|
|
4771
5186
|
repairable: true
|
|
@@ -4776,7 +5191,7 @@ class SchemaEvolutionService {
|
|
|
4776
5191
|
kind: 'missing_unique',
|
|
4777
5192
|
severity: 'warning',
|
|
4778
5193
|
field: field.code,
|
|
4779
|
-
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5194
|
+
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_FINDING_MESSAGES.UNIQUE_MISSING */.Vu.UNIQUE_MISSING, {
|
|
4780
5195
|
column: field.code
|
|
4781
5196
|
}),
|
|
4782
5197
|
repairable: true
|
|
@@ -4787,7 +5202,7 @@ class SchemaEvolutionService {
|
|
|
4787
5202
|
kind: 'stale_metadata',
|
|
4788
5203
|
severity: 'warning',
|
|
4789
5204
|
field: field.code,
|
|
4790
|
-
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5205
|
+
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_FINDING_MESSAGES.STALE_METADATA */.Vu.STALE_METADATA, {
|
|
4791
5206
|
dbType: field.dbType,
|
|
4792
5207
|
driver,
|
|
4793
5208
|
fieldType: field.fieldType
|
|
@@ -4802,7 +5217,7 @@ class SchemaEvolutionService {
|
|
|
4802
5217
|
kind: 'extra_column',
|
|
4803
5218
|
severity: 'warning',
|
|
4804
5219
|
field: column.name,
|
|
4805
|
-
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5220
|
+
...(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_FINDING_MESSAGES.EXTRA_COLUMN */.Vu.EXTRA_COLUMN, {
|
|
4806
5221
|
column: column.name
|
|
4807
5222
|
}),
|
|
4808
5223
|
repairable: false
|
|
@@ -4833,24 +5248,24 @@ class SchemaEvolutionService {
|
|
|
4833
5248
|
columns,
|
|
4834
5249
|
uniques
|
|
4835
5250
|
});
|
|
4836
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5251
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.RECREATE_TABLE */.EQ.RECREATE_TABLE, {
|
|
4837
5252
|
table: definition.tableName
|
|
4838
5253
|
}), async ()=>{
|
|
4839
5254
|
await ctx.qr.createTable(recreated, false);
|
|
4840
5255
|
});
|
|
4841
5256
|
fixed.push('missing_table');
|
|
4842
5257
|
for (const indexed of fields.filter((f)=>f.isIndexed && !f.unique)){
|
|
4843
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5258
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.RECREATE_INDEX */.EQ.RECREATE_INDEX, {
|
|
4844
5259
|
column: indexed.code
|
|
4845
5260
|
}), async ()=>{
|
|
4846
|
-
await ctx.qr.createIndex(recreated, (0,_schema_columns_js__rspack_import_17/* .plainIndex */.v7)(definition.tableName, indexed.code, ctx.driver, this.adapter));
|
|
5261
|
+
await ctx.qr.createIndex(recreated, (0,_schema_columns_js__rspack_import_17/* .plainIndex */.v7)(definition.tableName, indexed.code, ctx.driver, this.adapter, this.liveOnly(definition, ctx.driver)));
|
|
4847
5262
|
});
|
|
4848
5263
|
fixed.push(`missing_index:${indexed.code}`);
|
|
4849
5264
|
}
|
|
4850
|
-
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5265
|
+
ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.TABLE_RECREATED_EMPTY */.Uu.TABLE_RECREATED_EMPTY));
|
|
4851
5266
|
ctx.markDestructive();
|
|
4852
5267
|
return {
|
|
4853
|
-
operation:
|
|
5268
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.REPAIR */.i.REPAIR,
|
|
4854
5269
|
diff: {
|
|
4855
5270
|
fixed,
|
|
4856
5271
|
manual: 0
|
|
@@ -4864,16 +5279,16 @@ class SchemaEvolutionService {
|
|
|
4864
5279
|
case 'missing_column':
|
|
4865
5280
|
{
|
|
4866
5281
|
if (!field) {
|
|
4867
|
-
const sys =
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
5282
|
+
const sys = (0,_schema_columns_js__rspack_import_17/* .buildSystemColumns */.Rm)({
|
|
5283
|
+
isSoftDeleteEnabled: true,
|
|
5284
|
+
isAuditEnabled: true
|
|
5285
|
+
}, ctx.driver).find((c)=>c.name === finding.field && !c.isPrimary);
|
|
4871
5286
|
if (!sys) break;
|
|
4872
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5287
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.ADD_SYSTEM_COLUMN */.EQ.ADD_SYSTEM_COLUMN, {
|
|
4873
5288
|
column: sys.name
|
|
4874
5289
|
}), async ()=>ctx.qr.addColumn(table, sys));
|
|
4875
5290
|
} else {
|
|
4876
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5291
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.ADD_MISSING_COLUMN */.EQ.ADD_MISSING_COLUMN, {
|
|
4877
5292
|
column: field.code
|
|
4878
5293
|
}), async ()=>{
|
|
4879
5294
|
await ctx.qr.addColumn(table, (0,_schema_columns_js__rspack_import_17/* .buildFieldColumn */.fu)(field, ctx.driver, this.adapter, {
|
|
@@ -4883,7 +5298,7 @@ class SchemaEvolutionService {
|
|
|
4883
5298
|
});
|
|
4884
5299
|
// Re-added columns start empty, so a required field stays nullable until its records have values.
|
|
4885
5300
|
const rows = !field.nullable && !field.deprecatedAt ? await this.scalar(ctx, `SELECT COUNT(*) AS c FROM ${ctx.q(definition.tableName)}`) : 0;
|
|
4886
|
-
if (rows > 0) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5301
|
+
if (rows > 0) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.REQUIRED_HAS_NULLS */.Uu.REQUIRED_HAS_NULLS, {
|
|
4887
5302
|
field: field.code,
|
|
4888
5303
|
count: rows
|
|
4889
5304
|
}));
|
|
@@ -4892,10 +5307,10 @@ class SchemaEvolutionService {
|
|
|
4892
5307
|
break;
|
|
4893
5308
|
}
|
|
4894
5309
|
case 'missing_index':
|
|
4895
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5310
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.RECREATE_INDEX */.EQ.RECREATE_INDEX, {
|
|
4896
5311
|
column: finding.field
|
|
4897
5312
|
}), async ()=>{
|
|
4898
|
-
await
|
|
5313
|
+
await this.rebuildPlainIndex(ctx, table, definition.tableName, finding.field, this.liveOnly(definition, ctx.driver));
|
|
4899
5314
|
});
|
|
4900
5315
|
fixed.push(`missing_index:${finding.field}`);
|
|
4901
5316
|
break;
|
|
@@ -4903,12 +5318,12 @@ class SchemaEvolutionService {
|
|
|
4903
5318
|
{
|
|
4904
5319
|
const code = finding.field;
|
|
4905
5320
|
const dups = await this.countDuplicates(ctx, definition.tableName, code);
|
|
4906
|
-
if (dups > 0) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5321
|
+
if (dups > 0) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.UNIQUE_NOT_RECREATED */.Uu.UNIQUE_NOT_RECREATED, {
|
|
4907
5322
|
field: code,
|
|
4908
5323
|
count: dups
|
|
4909
5324
|
}));
|
|
4910
5325
|
else {
|
|
4911
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5326
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_STEP_MESSAGES.RECREATE_UNIQUE */.EQ.RECREATE_UNIQUE, {
|
|
4912
5327
|
column: code
|
|
4913
5328
|
}), async ()=>{
|
|
4914
5329
|
await (0,_schema_columns_js__rspack_import_17/* .addUnique */.$6)(ctx.qr, table, code, ctx.driver, this.adapter);
|
|
@@ -4923,7 +5338,7 @@ class SchemaEvolutionService {
|
|
|
4923
5338
|
if (!field || !column) break;
|
|
4924
5339
|
if (!field.nullable && column.isNullable) {
|
|
4925
5340
|
const nulls = await this.scalar(ctx, `SELECT COUNT(*) AS c FROM ${ctx.q(definition.tableName)} WHERE ${ctx.q(field.code)} IS NULL`);
|
|
4926
|
-
if (nulls > 0) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5341
|
+
if (nulls > 0) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.REQUIRED_HAS_NULLS */.Uu.REQUIRED_HAS_NULLS, {
|
|
4927
5342
|
field: field.code,
|
|
4928
5343
|
count: nulls
|
|
4929
5344
|
}));
|
|
@@ -4942,12 +5357,12 @@ class SchemaEvolutionService {
|
|
|
4942
5357
|
}
|
|
4943
5358
|
}
|
|
4944
5359
|
const manual = findings.filter((f)=>!f.repairable);
|
|
4945
|
-
for (const f of manual)ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5360
|
+
for (const f of manual)ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.NEEDS_MANUAL_ATTENTION */.Uu.NEEDS_MANUAL_ATTENTION, {
|
|
4946
5361
|
finding: (0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(f.messageKey, f.messageVariables)
|
|
4947
5362
|
}));
|
|
4948
|
-
if (fixed.length === 0 && manual.length === 0) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5363
|
+
if (fixed.length === 0 && manual.length === 0) ctx.warn((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_20/* .SCHEMA_WARNING_MESSAGES.NOTHING_TO_REPAIR */.Uu.NOTHING_TO_REPAIR));
|
|
4949
5364
|
return {
|
|
4950
|
-
operation:
|
|
5365
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_22/* .DdlOperation.REPAIR */.i.REPAIR,
|
|
4951
5366
|
diff: {
|
|
4952
5367
|
fixed,
|
|
4953
5368
|
manual: manual.length
|
|
@@ -4967,17 +5382,20 @@ SchemaEvolutionService = _ts_decorate([
|
|
|
4967
5382
|
scope: _nestjs_common__rspack_import_2.Scope.REQUEST
|
|
4968
5383
|
}),
|
|
4969
5384
|
_ts_param(0, (0,_nestjs_common__rspack_import_2.Inject)(_entity_builder_datasource_provider_js__rspack_import_10/* .EntityBuilderDataSourceProvider */.D)),
|
|
4970
|
-
_ts_param(1, (0,_nestjs_common__rspack_import_2.Inject)(
|
|
5385
|
+
_ts_param(1, (0,_nestjs_common__rspack_import_2.Inject)(_schema_dialect_adapter_service_js__rspack_import_19/* .SchemaDialectAdapterService */.I)),
|
|
4971
5386
|
_ts_param(2, (0,_nestjs_common__rspack_import_2.Inject)(_schema_change_executor_service_js__rspack_import_16/* .SchemaChangeExecutor */.T)),
|
|
4972
5387
|
_ts_param(3, (0,_nestjs_common__rspack_import_2.Inject)(_reference_scanner_service_js__rspack_import_15/* .ReferenceScannerService */.t)),
|
|
4973
5388
|
_ts_param(4, (0,_nestjs_common__rspack_import_2.Inject)(_entity_permission_service_js__rspack_import_11/* .EntityPermissionService */.u)),
|
|
5389
|
+
_ts_param(5, (0,_nestjs_common__rspack_import_2.Optional)()),
|
|
5390
|
+
_ts_param(5, (0,_nestjs_common__rspack_import_2.Inject)(_entity_builder_config_service_js__rspack_import_18/* .EntityBuilderConfigService */.E)),
|
|
4974
5391
|
_ts_metadata("design:type", Function),
|
|
4975
5392
|
_ts_metadata("design:paramtypes", [
|
|
4976
5393
|
typeof _entity_builder_datasource_provider_js__rspack_import_10/* .EntityBuilderDataSourceProvider */.D === "undefined" ? Object : _entity_builder_datasource_provider_js__rspack_import_10/* .EntityBuilderDataSourceProvider */.D,
|
|
4977
|
-
typeof
|
|
5394
|
+
typeof _schema_dialect_adapter_service_js__rspack_import_19/* .SchemaDialectAdapterService */.I === "undefined" ? Object : _schema_dialect_adapter_service_js__rspack_import_19/* .SchemaDialectAdapterService */.I,
|
|
4978
5395
|
typeof _schema_change_executor_service_js__rspack_import_16/* .SchemaChangeExecutor */.T === "undefined" ? Object : _schema_change_executor_service_js__rspack_import_16/* .SchemaChangeExecutor */.T,
|
|
4979
5396
|
typeof _reference_scanner_service_js__rspack_import_15/* .ReferenceScannerService */.t === "undefined" ? Object : _reference_scanner_service_js__rspack_import_15/* .ReferenceScannerService */.t,
|
|
4980
|
-
typeof _entity_permission_service_js__rspack_import_11/* .EntityPermissionService */.u === "undefined" ? Object : _entity_permission_service_js__rspack_import_11/* .EntityPermissionService */.u
|
|
5397
|
+
typeof _entity_permission_service_js__rspack_import_11/* .EntityPermissionService */.u === "undefined" ? Object : _entity_permission_service_js__rspack_import_11/* .EntityPermissionService */.u,
|
|
5398
|
+
typeof _entity_builder_config_service_js__rspack_import_18/* .EntityBuilderConfigService */.E === "undefined" ? Object : _entity_builder_config_service_js__rspack_import_18/* .EntityBuilderConfigService */.E
|
|
4981
5399
|
])
|
|
4982
5400
|
], SchemaEvolutionService);
|
|
4983
5401
|
|
|
@@ -4994,13 +5412,13 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
4994
5412
|
/* import */ var _flusys_nestjs_shared_utils__rspack_import_1 = __webpack_require__(9216);
|
|
4995
5413
|
/* import */ var _nestjs_common__rspack_import_2 = __webpack_require__(6157);
|
|
4996
5414
|
/* import */ var typeorm__rspack_import_3 = __webpack_require__(7158);
|
|
4997
|
-
/* import */ var
|
|
5415
|
+
/* import */ var _config_message_keys_js__rspack_import_18 = __webpack_require__(5732);
|
|
4998
5416
|
/* import */ var _entities_entity_definition_entity_js__rspack_import_4 = __webpack_require__(3189);
|
|
4999
5417
|
/* import */ var _entities_field_definition_entity_js__rspack_import_5 = __webpack_require__(2206);
|
|
5000
5418
|
/* import */ var _entities_flow_definition_entity_js__rspack_import_6 = __webpack_require__(3770);
|
|
5001
|
-
/* import */ var
|
|
5002
|
-
/* import */ var
|
|
5003
|
-
/* import */ var
|
|
5419
|
+
/* import */ var _enums_ddl_operation_enum_js__rspack_import_21 = __webpack_require__(9949);
|
|
5420
|
+
/* import */ var _enums_entity_status_enum_js__rspack_import_22 = __webpack_require__(1313);
|
|
5421
|
+
/* import */ var _enums_field_type_enum_js__rspack_import_20 = __webpack_require__(9614);
|
|
5004
5422
|
/* import */ var _flow_engine_flow_errors_js__rspack_import_7 = __webpack_require__(8542);
|
|
5005
5423
|
/* import */ var _entity_builder_datasource_provider_js__rspack_import_8 = __webpack_require__(424);
|
|
5006
5424
|
/* import */ var _entity_flow_scaffold_js__rspack_import_9 = __webpack_require__(8271);
|
|
@@ -5010,7 +5428,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
5010
5428
|
/* import */ var _identifier_rules_js__rspack_import_13 = __webpack_require__(413);
|
|
5011
5429
|
/* import */ var _schema_change_executor_service_js__rspack_import_14 = __webpack_require__(6605);
|
|
5012
5430
|
/* import */ var _schema_columns_js__rspack_import_15 = __webpack_require__(5313);
|
|
5013
|
-
/* import */ var
|
|
5431
|
+
/* import */ var _entity_builder_config_service_js__rspack_import_16 = __webpack_require__(4281);
|
|
5432
|
+
/* import */ var _schema_dialect_adapter_service_js__rspack_import_17 = __webpack_require__(7259);
|
|
5014
5433
|
function _ts_decorate(decorators, target, key, desc) {
|
|
5015
5434
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5016
5435
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -5054,6 +5473,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
5054
5473
|
|
|
5055
5474
|
|
|
5056
5475
|
|
|
5476
|
+
|
|
5057
5477
|
|
|
5058
5478
|
|
|
5059
5479
|
const presetId = (id)=>id ? {
|
|
@@ -5065,26 +5485,28 @@ class SchemaSyncService {
|
|
|
5065
5485
|
executor;
|
|
5066
5486
|
entityPermissionService;
|
|
5067
5487
|
flowDefinitionService;
|
|
5488
|
+
config;
|
|
5068
5489
|
logger = new _nestjs_common__rspack_import_2.Logger(SchemaSyncService.name);
|
|
5069
|
-
constructor(dataSourceProvider, dialectAdapter, executor, entityPermissionService, flowDefinitionService){
|
|
5490
|
+
constructor(dataSourceProvider, dialectAdapter, executor, entityPermissionService, flowDefinitionService, config){
|
|
5070
5491
|
this.dataSourceProvider = dataSourceProvider;
|
|
5071
5492
|
this.dialectAdapter = dialectAdapter;
|
|
5072
5493
|
this.executor = executor;
|
|
5073
5494
|
this.entityPermissionService = entityPermissionService;
|
|
5074
5495
|
this.flowDefinitionService = flowDefinitionService;
|
|
5496
|
+
this.config = config;
|
|
5075
5497
|
}
|
|
5076
5498
|
validateCreateRequest(dto) {
|
|
5077
|
-
(0,_identifier_rules_js__rspack_import_13/* .assertValidIdentifier */.
|
|
5499
|
+
(0,_identifier_rules_js__rspack_import_13/* .assertValidIdentifier */.k)(dto.code, 'entity');
|
|
5078
5500
|
const fields = dto.fields ?? [];
|
|
5079
5501
|
for (const field of fields){
|
|
5080
|
-
(0,_identifier_rules_js__rspack_import_13/* .assertValidIdentifier */.
|
|
5081
|
-
(0,_identifier_rules_js__rspack_import_13/* .assertIndexableField */.
|
|
5502
|
+
(0,_identifier_rules_js__rspack_import_13/* .assertValidIdentifier */.k)(field.code, 'field');
|
|
5503
|
+
(0,_identifier_rules_js__rspack_import_13/* .assertIndexableField */.f)(field);
|
|
5082
5504
|
}
|
|
5083
5505
|
const duplicate = fields.map((f)=>f.code).find((code, index, all)=>all.indexOf(code) !== index);
|
|
5084
5506
|
if (duplicate) {
|
|
5085
5507
|
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
5086
5508
|
message: `Field code '${duplicate}' is defined more than once.`,
|
|
5087
|
-
messageKey:
|
|
5509
|
+
messageKey: _config_message_keys_js__rspack_import_18/* .SCHEMA_MESSAGES.DUPLICATE_FIELD_CODE */.Hu.DUPLICATE_FIELD_CODE,
|
|
5088
5510
|
messageVariables: {
|
|
5089
5511
|
code: duplicate
|
|
5090
5512
|
}
|
|
@@ -5113,7 +5535,7 @@ class SchemaSyncService {
|
|
|
5113
5535
|
const taken = await ctx.qr.query((0,_flusys_nestjs_shared_classes__rspack_import_0.buildQuery)(`SELECT table_name FROM information_schema.tables WHERE table_schema = ${schemaExpr} AND table_name = ?`, ctx.driver), [
|
|
5114
5536
|
tableName
|
|
5115
5537
|
]);
|
|
5116
|
-
if (taken.length) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5538
|
+
if (taken.length) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_18/* .SCHEMA_BLOCKER_MESSAGES.TABLE_EXISTS */.M3.TABLE_EXISTS, {
|
|
5117
5539
|
table: tableName
|
|
5118
5540
|
}));
|
|
5119
5541
|
const definitions = ctx.qr.manager.getRepository(_entities_entity_definition_entity_js__rspack_import_4/* .EntityDefinition */.f);
|
|
@@ -5122,12 +5544,12 @@ class SchemaSyncService {
|
|
|
5122
5544
|
code: dto.code
|
|
5123
5545
|
}
|
|
5124
5546
|
});
|
|
5125
|
-
if (known) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5547
|
+
if (known) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_18/* .SCHEMA_BLOCKER_MESSAGES.ENTITY_CODE_EXISTS */.M3.ENTITY_CODE_EXISTS, {
|
|
5126
5548
|
code: dto.code
|
|
5127
5549
|
}));
|
|
5128
|
-
for (const spec of fieldSpecs.filter((f)=>f.fieldType ===
|
|
5550
|
+
for (const spec of fieldSpecs.filter((f)=>f.fieldType === _enums_field_type_enum_js__rspack_import_20/* .FieldType.RELATION */.P.RELATION)){
|
|
5129
5551
|
if (!spec.relationTargetEntityId) {
|
|
5130
|
-
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5552
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_18/* .SCHEMA_BLOCKER_MESSAGES.RELATION_TARGET_REQUIRED */.M3.RELATION_TARGET_REQUIRED, {
|
|
5131
5553
|
field: spec.code
|
|
5132
5554
|
}));
|
|
5133
5555
|
continue;
|
|
@@ -5137,24 +5559,16 @@ class SchemaSyncService {
|
|
|
5137
5559
|
id: spec.relationTargetEntityId
|
|
5138
5560
|
}
|
|
5139
5561
|
});
|
|
5140
|
-
if (!target) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5562
|
+
if (!target) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_18/* .SCHEMA_BLOCKER_MESSAGES.RELATION_FIELD_TARGET_MISSING */.M3.RELATION_FIELD_TARGET_MISSING, {
|
|
5141
5563
|
field: spec.code
|
|
5142
5564
|
}));
|
|
5143
5565
|
}
|
|
5144
5566
|
const withDefault = fieldSpecs.filter((f)=>f.defaultValue !== undefined && f.defaultValue !== null);
|
|
5145
|
-
const { errors: defaultErrors } = (0,_field_value_validator_js__rspack_import_11/* .validateRecord */.e)(withDefault.map((f)=>
|
|
5146
|
-
code: f.code,
|
|
5147
|
-
label: f.label,
|
|
5148
|
-
fieldType: f.fieldType,
|
|
5149
|
-
nullable: true,
|
|
5150
|
-
defaultValue: null,
|
|
5151
|
-
selectOptions: f.selectOptions ?? null,
|
|
5152
|
-
validationRules: f.validationRules ?? null
|
|
5153
|
-
})), Object.fromEntries(withDefault.map((f)=>[
|
|
5567
|
+
const { errors: defaultErrors } = (0,_field_value_validator_js__rspack_import_11/* .validateRecord */.e)(withDefault.map(_field_value_validator_js__rspack_import_11/* .valueRulesOf */.C), Object.fromEntries(withDefault.map((f)=>[
|
|
5154
5568
|
f.code,
|
|
5155
5569
|
f.defaultValue
|
|
5156
5570
|
])), 'insert');
|
|
5157
|
-
for (const error of defaultErrors)ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5571
|
+
for (const error of defaultErrors)ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_18/* .SCHEMA_BLOCKER_MESSAGES.DEFAULT_INVALID */.M3.DEFAULT_INVALID, {
|
|
5158
5572
|
problem: (0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(error.messageKey, error.messageVariables)
|
|
5159
5573
|
}));
|
|
5160
5574
|
if (flowEndpoints.length) {
|
|
@@ -5165,15 +5579,14 @@ class SchemaSyncService {
|
|
|
5165
5579
|
},
|
|
5166
5580
|
where: {
|
|
5167
5581
|
slug
|
|
5168
|
-
}
|
|
5169
|
-
withDeleted: true
|
|
5582
|
+
}
|
|
5170
5583
|
});
|
|
5171
|
-
if (clash) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5584
|
+
if (clash) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_18/* .SCHEMA_BLOCKER_MESSAGES.FLOW_SLUG_TAKEN */.M3.FLOW_SLUG_TAKEN, {
|
|
5172
5585
|
slug
|
|
5173
5586
|
}));
|
|
5174
5587
|
}
|
|
5175
5588
|
if (ctx.blocked) return {
|
|
5176
|
-
operation:
|
|
5589
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_21/* .DdlOperation.CREATE_TABLE */.i.CREATE_TABLE,
|
|
5177
5590
|
diff: {}
|
|
5178
5591
|
};
|
|
5179
5592
|
const columns = fieldSpecs.map((spec)=>(0,_schema_columns_js__rspack_import_15/* .buildFieldColumn */.fu)({
|
|
@@ -5196,16 +5609,16 @@ class SchemaSyncService {
|
|
|
5196
5609
|
...columns
|
|
5197
5610
|
]
|
|
5198
5611
|
});
|
|
5199
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5612
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_18/* .SCHEMA_STEP_MESSAGES.CREATE_TABLE */.EQ.CREATE_TABLE, {
|
|
5200
5613
|
table: tableName
|
|
5201
5614
|
}), async ()=>{
|
|
5202
5615
|
await ctx.qr.createTable(table, false);
|
|
5203
5616
|
});
|
|
5204
|
-
for (const spec of fieldSpecs.filter((f)=>
|
|
5205
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5617
|
+
for (const spec of fieldSpecs.filter((f)=>(0,_schema_columns_js__rspack_import_15/* .indexedByDefault */.w5)(f) && !f.unique)){
|
|
5618
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_18/* .SCHEMA_STEP_MESSAGES.ADD_INDEX */.EQ.ADD_INDEX, {
|
|
5206
5619
|
column: spec.code
|
|
5207
5620
|
}), async ()=>{
|
|
5208
|
-
await ctx.qr.createIndex(table, (0,_schema_columns_js__rspack_import_15/* .plainIndex */.v7)(tableName, spec.code, ctx.driver, this.dialectAdapter));
|
|
5621
|
+
await ctx.qr.createIndex(table, (0,_schema_columns_js__rspack_import_15/* .plainIndex */.v7)(tableName, spec.code, ctx.driver, this.dialectAdapter, isSoftDeleteEnabled && !!this.config?.isPartialIndexesEnabled()));
|
|
5209
5622
|
});
|
|
5210
5623
|
}
|
|
5211
5624
|
await ctx.metadata(async ()=>{
|
|
@@ -5216,7 +5629,7 @@ class SchemaSyncService {
|
|
|
5216
5629
|
label: dto.label,
|
|
5217
5630
|
description: dto.description ?? null,
|
|
5218
5631
|
tableName,
|
|
5219
|
-
status:
|
|
5632
|
+
status: _enums_entity_status_enum_js__rspack_import_22/* .EntityStatus.ACTIVE */.c.ACTIVE,
|
|
5220
5633
|
schemaVersion: 1,
|
|
5221
5634
|
isSoftDeleteEnabled,
|
|
5222
5635
|
isAuditEnabled,
|
|
@@ -5233,11 +5646,11 @@ class SchemaSyncService {
|
|
|
5233
5646
|
dbType: this.dialectAdapter.mapFieldType(spec.fieldType, ctx.driver),
|
|
5234
5647
|
nullable: spec.nullable ?? true,
|
|
5235
5648
|
unique: spec.unique ?? false,
|
|
5236
|
-
isIndexed:
|
|
5649
|
+
isIndexed: (0,_schema_columns_js__rspack_import_15/* .indexedByDefault */.w5)(spec),
|
|
5237
5650
|
defaultValue: spec.defaultValue ?? null,
|
|
5238
5651
|
validationRules: spec.validationRules ?? null,
|
|
5239
5652
|
selectOptions: spec.selectOptions ?? null,
|
|
5240
|
-
relationTargetEntityId: spec.fieldType ===
|
|
5653
|
+
relationTargetEntityId: spec.fieldType === _enums_field_type_enum_js__rspack_import_20/* .FieldType.RELATION */.P.RELATION ? spec.relationTargetEntityId : null,
|
|
5241
5654
|
order: spec.order ?? index,
|
|
5242
5655
|
uiConfig: spec.uiConfig ?? null,
|
|
5243
5656
|
isSearchable: spec.isSearchable ?? false,
|
|
@@ -5248,7 +5661,7 @@ class SchemaSyncService {
|
|
|
5248
5661
|
created.definition = definition;
|
|
5249
5662
|
});
|
|
5250
5663
|
return {
|
|
5251
|
-
operation:
|
|
5664
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_21/* .DdlOperation.CREATE_TABLE */.i.CREATE_TABLE,
|
|
5252
5665
|
entityDefinitionId: created.definition?.id ?? null,
|
|
5253
5666
|
diff: {
|
|
5254
5667
|
fields: fieldSpecs.map((f)=>({
|
|
@@ -5284,7 +5697,7 @@ class SchemaSyncService {
|
|
|
5284
5697
|
} catch (error) {
|
|
5285
5698
|
this.logger.error(`The flow '${flow.slug}' of entity '${dto.code}' could not be created: ${error.message}`);
|
|
5286
5699
|
return [
|
|
5287
|
-
(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5700
|
+
(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_18/* .SCHEMA_WARNING_MESSAGES.ENDPOINT_FLOW_FAILED */.Uu.ENDPOINT_FLOW_FAILED, {
|
|
5288
5701
|
slug: flow.slug,
|
|
5289
5702
|
detail: (0,_flow_engine_flow_errors_js__rspack_import_7/* .errorRef */.O$)(error)
|
|
5290
5703
|
})
|
|
@@ -5307,10 +5720,10 @@ class SchemaSyncService {
|
|
|
5307
5720
|
try {
|
|
5308
5721
|
({ plan: { warnings: planWarnings } } = await this.executor.apply(await this.createTarget(dto, user), this.createRun(dto, user, created, ids)));
|
|
5309
5722
|
} catch (error) {
|
|
5310
|
-
if (error instanceof _nestjs_common__rspack_import_2.ConflictException && error.getResponse().blockers?.some((b)=>b.messageKey ===
|
|
5723
|
+
if (error instanceof _nestjs_common__rspack_import_2.ConflictException && error.getResponse().blockers?.some((b)=>b.messageKey === _config_message_keys_js__rspack_import_18/* .SCHEMA_BLOCKER_MESSAGES.ENTITY_CODE_EXISTS */.M3.ENTITY_CODE_EXISTS || b.messageKey === _config_message_keys_js__rspack_import_18/* .SCHEMA_BLOCKER_MESSAGES.TABLE_EXISTS */.M3.TABLE_EXISTS)) {
|
|
5311
5724
|
throw new _nestjs_common__rspack_import_2.ConflictException({
|
|
5312
5725
|
message: `An entity with the code '${dto.code}' already exists.`,
|
|
5313
|
-
messageKey:
|
|
5726
|
+
messageKey: _config_message_keys_js__rspack_import_18/* .ENTITY_DEFINITION_MESSAGES.CODE_ALREADY_EXISTS */.pL.CODE_ALREADY_EXISTS,
|
|
5314
5727
|
messageVariables: {
|
|
5315
5728
|
code: dto.code
|
|
5316
5729
|
}
|
|
@@ -5332,17 +5745,20 @@ SchemaSyncService = _ts_decorate([
|
|
|
5332
5745
|
scope: _nestjs_common__rspack_import_2.Scope.REQUEST
|
|
5333
5746
|
}),
|
|
5334
5747
|
_ts_param(0, (0,_nestjs_common__rspack_import_2.Inject)(_entity_builder_datasource_provider_js__rspack_import_8/* .EntityBuilderDataSourceProvider */.D)),
|
|
5335
|
-
_ts_param(1, (0,_nestjs_common__rspack_import_2.Inject)(
|
|
5748
|
+
_ts_param(1, (0,_nestjs_common__rspack_import_2.Inject)(_schema_dialect_adapter_service_js__rspack_import_17/* .SchemaDialectAdapterService */.I)),
|
|
5336
5749
|
_ts_param(2, (0,_nestjs_common__rspack_import_2.Inject)(_schema_change_executor_service_js__rspack_import_14/* .SchemaChangeExecutor */.T)),
|
|
5337
5750
|
_ts_param(3, (0,_nestjs_common__rspack_import_2.Inject)(_entity_permission_service_js__rspack_import_10/* .EntityPermissionService */.u)),
|
|
5338
5751
|
_ts_param(4, (0,_nestjs_common__rspack_import_2.Inject)(_flow_definition_service_js__rspack_import_12/* .FlowDefinitionService */.Tk)),
|
|
5752
|
+
_ts_param(5, (0,_nestjs_common__rspack_import_2.Optional)()),
|
|
5753
|
+
_ts_param(5, (0,_nestjs_common__rspack_import_2.Inject)(_entity_builder_config_service_js__rspack_import_16/* .EntityBuilderConfigService */.E)),
|
|
5339
5754
|
_ts_metadata("design:type", Function),
|
|
5340
5755
|
_ts_metadata("design:paramtypes", [
|
|
5341
5756
|
typeof _entity_builder_datasource_provider_js__rspack_import_8/* .EntityBuilderDataSourceProvider */.D === "undefined" ? Object : _entity_builder_datasource_provider_js__rspack_import_8/* .EntityBuilderDataSourceProvider */.D,
|
|
5342
|
-
typeof
|
|
5757
|
+
typeof _schema_dialect_adapter_service_js__rspack_import_17/* .SchemaDialectAdapterService */.I === "undefined" ? Object : _schema_dialect_adapter_service_js__rspack_import_17/* .SchemaDialectAdapterService */.I,
|
|
5343
5758
|
typeof _schema_change_executor_service_js__rspack_import_14/* .SchemaChangeExecutor */.T === "undefined" ? Object : _schema_change_executor_service_js__rspack_import_14/* .SchemaChangeExecutor */.T,
|
|
5344
5759
|
typeof _entity_permission_service_js__rspack_import_10/* .EntityPermissionService */.u === "undefined" ? Object : _entity_permission_service_js__rspack_import_10/* .EntityPermissionService */.u,
|
|
5345
|
-
typeof _flow_definition_service_js__rspack_import_12/* .FlowDefinitionService */.Tk === "undefined" ? Object : _flow_definition_service_js__rspack_import_12/* .FlowDefinitionService */.Tk
|
|
5760
|
+
typeof _flow_definition_service_js__rspack_import_12/* .FlowDefinitionService */.Tk === "undefined" ? Object : _flow_definition_service_js__rspack_import_12/* .FlowDefinitionService */.Tk,
|
|
5761
|
+
typeof _entity_builder_config_service_js__rspack_import_16/* .EntityBuilderConfigService */.E === "undefined" ? Object : _entity_builder_config_service_js__rspack_import_16/* .EntityBuilderConfigService */.E
|
|
5346
5762
|
])
|
|
5347
5763
|
], SchemaSyncService);
|
|
5348
5764
|
|