@flusys/nestjs-entity-builder 9.1.0 → 9.1.2
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 +59 -26
- package/config/entity-builder.constants.d.ts +2 -0
- package/config/message-keys.d.ts +96 -12
- package/controllers/definition-bundle.controller.d.ts +15 -0
- package/controllers/flow-definition.controller.d.ts +7 -1
- package/controllers/index.d.ts +1 -1
- package/dtos/definition-bundle.dto.d.ts +57 -0
- package/dtos/flow.dto.d.ts +12 -20
- package/dtos/index.d.ts +1 -0
- package/entities/flow-definition.entity.d.ts +3 -9
- package/entities/flow-execution.entity.d.ts +3 -0
- package/entities/flow-version.entity.d.ts +10 -0
- package/entities/index.d.ts +3 -3
- package/fesm/21.js +101 -16
- package/fesm/458.js +695 -0
- package/fesm/{996.js → 677.js} +1582 -1047
- package/fesm/794.js +135 -240
- package/fesm/{489.js → 857.js} +216 -289
- package/fesm/{719.js → 870.js} +1955 -220
- package/fesm/{362.js → 897.js} +566 -2
- package/fesm/{606.js → 946.js} +564 -290
- package/fesm/config/index.js +15 -2
- package/fesm/controllers/index.js +9 -9
- package/fesm/docs/index.js +7 -4
- package/fesm/dtos/index.js +451 -256
- package/fesm/entities/index.js +58 -3
- package/fesm/guards/index.js +101 -22
- package/fesm/index.js +444 -948
- package/fesm/interfaces/index.js +92 -4
- package/fesm/modules/index.js +10 -628
- package/fesm/rule-engine/index.js +12 -3
- package/fesm/services/index.js +97 -27
- package/flow-engine/flow-api-key.d.ts +3 -7
- package/flow-engine/flow-graph.validator.d.ts +4 -2
- package/flow-engine/flow-permission-logic.d.ts +2 -0
- package/flow-engine/flow-run.types.d.ts +17 -8
- package/flow-engine/flow.types.d.ts +107 -15
- package/guards/designer-writable.interceptor.d.ts +12 -0
- package/guards/index.d.ts +1 -0
- package/interfaces/definition-bundle.interface.d.ts +111 -0
- package/interfaces/entity-builder-module.interface.d.ts +6 -0
- package/interfaces/flow-definition.interface.d.ts +13 -9
- package/interfaces/generic-record.interface.d.ts +11 -1
- package/interfaces/index.d.ts +1 -0
- package/package.json +5 -6
- package/rule-engine/rule-engine.service.d.ts +3 -1
- package/rule-engine/rule-permission.d.ts +3 -7
- package/rule-engine/rule-regex.d.ts +0 -2
- package/rule-engine/rule-values.d.ts +4 -1
- package/rule-engine/rule.interface.d.ts +2 -3
- package/services/definition-bundle.diff.d.ts +62 -0
- package/services/definition-bundle.file.d.ts +7 -0
- package/services/definition-bundle.service.d.ts +32 -0
- package/services/entity-builder-config.service.d.ts +2 -0
- package/services/entity-flow-scaffold.d.ts +1 -1
- package/services/flow-definition.service.d.ts +25 -12
- package/services/flow-execution.service.d.ts +7 -0
- package/services/flow-executor.service.d.ts +8 -8
- package/services/generic-entity.service.d.ts +5 -1
- package/services/index.d.ts +3 -1
- package/services/schema-evolution.service.d.ts +3 -1
- package/services/schema-sync.service.d.ts +5 -1
- package/controllers/flow-api-key.controller.d.ts +0 -14
- package/entities/flow-api-key.entity.d.ts +0 -10
- package/services/flow-api-key.service.d.ts +0 -31
package/fesm/{719.js → 870.js}
RENAMED
|
@@ -1,12 +1,1715 @@
|
|
|
1
|
-
export const __rspack_esm_id =
|
|
2
|
-
export const __rspack_esm_ids = [
|
|
1
|
+
export const __rspack_esm_id = 870;
|
|
2
|
+
export const __rspack_esm_ids = [870];
|
|
3
3
|
export const __webpack_modules__ = {
|
|
4
|
+
6691(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
5
|
+
/* import */ var _nestjs_swagger__rspack_import_0 = __webpack_require__(6176);
|
|
6
|
+
/* import */ var class_transformer__rspack_import_1 = __webpack_require__(5812);
|
|
7
|
+
/* import */ var class_validator__rspack_import_2 = __webpack_require__(5421);
|
|
8
|
+
/* import */ var _config_entity_builder_constants_js__rspack_import_4 = __webpack_require__(6576);
|
|
9
|
+
/* import */ var _enums_entity_status_enum_js__rspack_import_6 = __webpack_require__(1313);
|
|
10
|
+
/* import */ var _enums_field_type_enum_js__rspack_import_5 = __webpack_require__(9614);
|
|
11
|
+
/* import */ var _flow_engine_flow_types_js__rspack_import_3 = __webpack_require__(6256);
|
|
12
|
+
/* import */ var _interfaces_definition_bundle_interface_js__rspack_import_7 = __webpack_require__(8835);
|
|
13
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
14
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
15
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
16
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
17
|
+
} else {
|
|
18
|
+
for(var i = decorators.length - 1; i >= 0; i--){
|
|
19
|
+
if (d = decorators[i]) {
|
|
20
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
25
|
+
}
|
|
26
|
+
function _ts_metadata(metadataKey, metadataValue) {
|
|
27
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
28
|
+
return Reflect.metadata(metadataKey, metadataValue);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
const Nullable = ()=>(0,class_validator__rspack_import_2.ValidateIf)((_object, value)=>value !== null);
|
|
40
|
+
class BundleFieldDto {
|
|
41
|
+
id;
|
|
42
|
+
code;
|
|
43
|
+
label;
|
|
44
|
+
fieldType;
|
|
45
|
+
nullable;
|
|
46
|
+
unique;
|
|
47
|
+
isIndexed;
|
|
48
|
+
defaultValue;
|
|
49
|
+
validationRules;
|
|
50
|
+
selectOptions;
|
|
51
|
+
relationTarget;
|
|
52
|
+
order;
|
|
53
|
+
uiConfig;
|
|
54
|
+
isSearchable;
|
|
55
|
+
deprecated;
|
|
56
|
+
}
|
|
57
|
+
_ts_decorate([
|
|
58
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
59
|
+
(0,class_validator__rspack_import_2.IsUUID)(),
|
|
60
|
+
_ts_metadata("design:type", String)
|
|
61
|
+
], BundleFieldDto.prototype, "id", void 0);
|
|
62
|
+
_ts_decorate([
|
|
63
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
64
|
+
(0,class_validator__rspack_import_2.IsString)(),
|
|
65
|
+
(0,class_validator__rspack_import_2.MaxLength)((/* inlined export .ENTITY_CODE_MAX_LENGTH */63)),
|
|
66
|
+
(0,class_validator__rspack_import_2.Matches)(_config_entity_builder_constants_js__rspack_import_4/* .ENTITY_CODE_PATTERN */.vs),
|
|
67
|
+
_ts_metadata("design:type", String)
|
|
68
|
+
], BundleFieldDto.prototype, "code", void 0);
|
|
69
|
+
_ts_decorate([
|
|
70
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
71
|
+
(0,class_validator__rspack_import_2.IsString)(),
|
|
72
|
+
(0,class_validator__rspack_import_2.IsNotEmpty)(),
|
|
73
|
+
(0,class_validator__rspack_import_2.MaxLength)(255),
|
|
74
|
+
_ts_metadata("design:type", String)
|
|
75
|
+
], BundleFieldDto.prototype, "label", void 0);
|
|
76
|
+
_ts_decorate([
|
|
77
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)({
|
|
78
|
+
enum: _enums_field_type_enum_js__rspack_import_5/* .FieldType */.P
|
|
79
|
+
}),
|
|
80
|
+
(0,class_validator__rspack_import_2.IsEnum)(_enums_field_type_enum_js__rspack_import_5/* .FieldType */.P),
|
|
81
|
+
_ts_metadata("design:type", typeof _enums_field_type_enum_js__rspack_import_5/* .FieldType */.P === "undefined" ? Object : _enums_field_type_enum_js__rspack_import_5/* .FieldType */.P)
|
|
82
|
+
], BundleFieldDto.prototype, "fieldType", void 0);
|
|
83
|
+
_ts_decorate([
|
|
84
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
85
|
+
(0,class_validator__rspack_import_2.IsBoolean)(),
|
|
86
|
+
_ts_metadata("design:type", Boolean)
|
|
87
|
+
], BundleFieldDto.prototype, "nullable", void 0);
|
|
88
|
+
_ts_decorate([
|
|
89
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
90
|
+
(0,class_validator__rspack_import_2.IsBoolean)(),
|
|
91
|
+
_ts_metadata("design:type", Boolean)
|
|
92
|
+
], BundleFieldDto.prototype, "unique", void 0);
|
|
93
|
+
_ts_decorate([
|
|
94
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
95
|
+
(0,class_validator__rspack_import_2.IsBoolean)(),
|
|
96
|
+
_ts_metadata("design:type", Boolean)
|
|
97
|
+
], BundleFieldDto.prototype, "isIndexed", void 0);
|
|
98
|
+
_ts_decorate([
|
|
99
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)(),
|
|
100
|
+
(0,class_validator__rspack_import_2.Allow)(),
|
|
101
|
+
_ts_metadata("design:type", Object)
|
|
102
|
+
], BundleFieldDto.prototype, "defaultValue", void 0);
|
|
103
|
+
_ts_decorate([
|
|
104
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
105
|
+
type: Object,
|
|
106
|
+
nullable: true
|
|
107
|
+
}),
|
|
108
|
+
Nullable(),
|
|
109
|
+
(0,class_validator__rspack_import_2.IsObject)(),
|
|
110
|
+
_ts_metadata("design:type", Object)
|
|
111
|
+
], BundleFieldDto.prototype, "validationRules", void 0);
|
|
112
|
+
_ts_decorate([
|
|
113
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
114
|
+
type: [
|
|
115
|
+
Object
|
|
116
|
+
],
|
|
117
|
+
nullable: true
|
|
118
|
+
}),
|
|
119
|
+
Nullable(),
|
|
120
|
+
(0,class_validator__rspack_import_2.IsArray)(),
|
|
121
|
+
_ts_metadata("design:type", Object)
|
|
122
|
+
], BundleFieldDto.prototype, "selectOptions", void 0);
|
|
123
|
+
_ts_decorate([
|
|
124
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
125
|
+
description: 'Code of the entity a RELATION field points to',
|
|
126
|
+
nullable: true
|
|
127
|
+
}),
|
|
128
|
+
Nullable(),
|
|
129
|
+
(0,class_validator__rspack_import_2.IsString)(),
|
|
130
|
+
(0,class_validator__rspack_import_2.Matches)(_config_entity_builder_constants_js__rspack_import_4/* .ENTITY_CODE_PATTERN */.vs),
|
|
131
|
+
_ts_metadata("design:type", Object)
|
|
132
|
+
], BundleFieldDto.prototype, "relationTarget", void 0);
|
|
133
|
+
_ts_decorate([
|
|
134
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
135
|
+
(0,class_validator__rspack_import_2.IsInt)(),
|
|
136
|
+
(0,class_validator__rspack_import_2.Min)(0),
|
|
137
|
+
_ts_metadata("design:type", Number)
|
|
138
|
+
], BundleFieldDto.prototype, "order", void 0);
|
|
139
|
+
_ts_decorate([
|
|
140
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
141
|
+
type: Object,
|
|
142
|
+
nullable: true
|
|
143
|
+
}),
|
|
144
|
+
Nullable(),
|
|
145
|
+
(0,class_validator__rspack_import_2.IsObject)(),
|
|
146
|
+
_ts_metadata("design:type", Object)
|
|
147
|
+
], BundleFieldDto.prototype, "uiConfig", void 0);
|
|
148
|
+
_ts_decorate([
|
|
149
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
150
|
+
(0,class_validator__rspack_import_2.IsBoolean)(),
|
|
151
|
+
_ts_metadata("design:type", Boolean)
|
|
152
|
+
], BundleFieldDto.prototype, "isSearchable", void 0);
|
|
153
|
+
_ts_decorate([
|
|
154
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
155
|
+
(0,class_validator__rspack_import_2.IsBoolean)(),
|
|
156
|
+
_ts_metadata("design:type", Boolean)
|
|
157
|
+
], BundleFieldDto.prototype, "deprecated", void 0);
|
|
158
|
+
class BundleEntityDto {
|
|
159
|
+
id;
|
|
160
|
+
code;
|
|
161
|
+
label;
|
|
162
|
+
description;
|
|
163
|
+
status;
|
|
164
|
+
isSoftDeleteEnabled;
|
|
165
|
+
isAuditEnabled;
|
|
166
|
+
uiConfig;
|
|
167
|
+
fields;
|
|
168
|
+
}
|
|
169
|
+
_ts_decorate([
|
|
170
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
171
|
+
(0,class_validator__rspack_import_2.IsUUID)(),
|
|
172
|
+
_ts_metadata("design:type", String)
|
|
173
|
+
], BundleEntityDto.prototype, "id", void 0);
|
|
174
|
+
_ts_decorate([
|
|
175
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
176
|
+
(0,class_validator__rspack_import_2.IsString)(),
|
|
177
|
+
(0,class_validator__rspack_import_2.MaxLength)((/* inlined export .ENTITY_CODE_MAX_LENGTH */63)),
|
|
178
|
+
(0,class_validator__rspack_import_2.Matches)(_config_entity_builder_constants_js__rspack_import_4/* .ENTITY_CODE_PATTERN */.vs),
|
|
179
|
+
_ts_metadata("design:type", String)
|
|
180
|
+
], BundleEntityDto.prototype, "code", void 0);
|
|
181
|
+
_ts_decorate([
|
|
182
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
183
|
+
(0,class_validator__rspack_import_2.IsString)(),
|
|
184
|
+
(0,class_validator__rspack_import_2.IsNotEmpty)(),
|
|
185
|
+
(0,class_validator__rspack_import_2.MaxLength)(255),
|
|
186
|
+
_ts_metadata("design:type", String)
|
|
187
|
+
], BundleEntityDto.prototype, "label", void 0);
|
|
188
|
+
_ts_decorate([
|
|
189
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
190
|
+
nullable: true
|
|
191
|
+
}),
|
|
192
|
+
Nullable(),
|
|
193
|
+
(0,class_validator__rspack_import_2.IsString)(),
|
|
194
|
+
(0,class_validator__rspack_import_2.MaxLength)(500),
|
|
195
|
+
_ts_metadata("design:type", Object)
|
|
196
|
+
], BundleEntityDto.prototype, "description", void 0);
|
|
197
|
+
_ts_decorate([
|
|
198
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)({
|
|
199
|
+
enum: _enums_entity_status_enum_js__rspack_import_6/* .EntityStatus */.c
|
|
200
|
+
}),
|
|
201
|
+
(0,class_validator__rspack_import_2.IsEnum)(_enums_entity_status_enum_js__rspack_import_6/* .EntityStatus */.c),
|
|
202
|
+
_ts_metadata("design:type", typeof _enums_entity_status_enum_js__rspack_import_6/* .EntityStatus */.c === "undefined" ? Object : _enums_entity_status_enum_js__rspack_import_6/* .EntityStatus */.c)
|
|
203
|
+
], BundleEntityDto.prototype, "status", void 0);
|
|
204
|
+
_ts_decorate([
|
|
205
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
206
|
+
(0,class_validator__rspack_import_2.IsBoolean)(),
|
|
207
|
+
_ts_metadata("design:type", Boolean)
|
|
208
|
+
], BundleEntityDto.prototype, "isSoftDeleteEnabled", void 0);
|
|
209
|
+
_ts_decorate([
|
|
210
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
211
|
+
(0,class_validator__rspack_import_2.IsBoolean)(),
|
|
212
|
+
_ts_metadata("design:type", Boolean)
|
|
213
|
+
], BundleEntityDto.prototype, "isAuditEnabled", void 0);
|
|
214
|
+
_ts_decorate([
|
|
215
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
216
|
+
type: Object,
|
|
217
|
+
nullable: true
|
|
218
|
+
}),
|
|
219
|
+
Nullable(),
|
|
220
|
+
(0,class_validator__rspack_import_2.IsObject)(),
|
|
221
|
+
_ts_metadata("design:type", Object)
|
|
222
|
+
], BundleEntityDto.prototype, "uiConfig", void 0);
|
|
223
|
+
_ts_decorate([
|
|
224
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)({
|
|
225
|
+
type: [
|
|
226
|
+
BundleFieldDto
|
|
227
|
+
]
|
|
228
|
+
}),
|
|
229
|
+
(0,class_validator__rspack_import_2.IsArray)(),
|
|
230
|
+
(0,class_validator__rspack_import_2.ValidateNested)({
|
|
231
|
+
each: true
|
|
232
|
+
}),
|
|
233
|
+
(0,class_transformer__rspack_import_1.Type)(()=>BundleFieldDto),
|
|
234
|
+
_ts_metadata("design:type", Array)
|
|
235
|
+
], BundleEntityDto.prototype, "fields", void 0);
|
|
236
|
+
class BundleFlowDto {
|
|
237
|
+
name;
|
|
238
|
+
slug;
|
|
239
|
+
description;
|
|
240
|
+
isActive;
|
|
241
|
+
retainExecutions;
|
|
242
|
+
nodes;
|
|
243
|
+
edges;
|
|
244
|
+
}
|
|
245
|
+
_ts_decorate([
|
|
246
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
247
|
+
(0,class_validator__rspack_import_2.IsString)(),
|
|
248
|
+
(0,class_validator__rspack_import_2.IsNotEmpty)(),
|
|
249
|
+
(0,class_validator__rspack_import_2.MaxLength)(255),
|
|
250
|
+
_ts_metadata("design:type", String)
|
|
251
|
+
], BundleFlowDto.prototype, "name", void 0);
|
|
252
|
+
_ts_decorate([
|
|
253
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
254
|
+
(0,class_validator__rspack_import_2.IsString)(),
|
|
255
|
+
(0,class_validator__rspack_import_2.Matches)(_flow_engine_flow_types_js__rspack_import_3/* .FLOW_SLUG_PATTERN */.YD),
|
|
256
|
+
_ts_metadata("design:type", String)
|
|
257
|
+
], BundleFlowDto.prototype, "slug", void 0);
|
|
258
|
+
_ts_decorate([
|
|
259
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
260
|
+
nullable: true
|
|
261
|
+
}),
|
|
262
|
+
Nullable(),
|
|
263
|
+
(0,class_validator__rspack_import_2.IsString)(),
|
|
264
|
+
(0,class_validator__rspack_import_2.MaxLength)(500),
|
|
265
|
+
_ts_metadata("design:type", Object)
|
|
266
|
+
], BundleFlowDto.prototype, "description", void 0);
|
|
267
|
+
_ts_decorate([
|
|
268
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
269
|
+
(0,class_validator__rspack_import_2.IsBoolean)(),
|
|
270
|
+
_ts_metadata("design:type", Boolean)
|
|
271
|
+
], BundleFlowDto.prototype, "isActive", void 0);
|
|
272
|
+
_ts_decorate([
|
|
273
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)(),
|
|
274
|
+
(0,class_validator__rspack_import_2.IsInt)(),
|
|
275
|
+
(0,class_validator__rspack_import_2.Min)(0),
|
|
276
|
+
(0,class_validator__rspack_import_2.Max)(10000),
|
|
277
|
+
_ts_metadata("design:type", Number)
|
|
278
|
+
], BundleFlowDto.prototype, "retainExecutions", void 0);
|
|
279
|
+
_ts_decorate([
|
|
280
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)({
|
|
281
|
+
type: [
|
|
282
|
+
Object
|
|
283
|
+
]
|
|
284
|
+
}),
|
|
285
|
+
(0,class_validator__rspack_import_2.IsArray)(),
|
|
286
|
+
(0,class_validator__rspack_import_2.IsObject)({
|
|
287
|
+
each: true
|
|
288
|
+
}),
|
|
289
|
+
_ts_metadata("design:type", Array)
|
|
290
|
+
], BundleFlowDto.prototype, "nodes", void 0);
|
|
291
|
+
_ts_decorate([
|
|
292
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)({
|
|
293
|
+
type: [
|
|
294
|
+
Object
|
|
295
|
+
]
|
|
296
|
+
}),
|
|
297
|
+
(0,class_validator__rspack_import_2.IsArray)(),
|
|
298
|
+
(0,class_validator__rspack_import_2.IsObject)({
|
|
299
|
+
each: true
|
|
300
|
+
}),
|
|
301
|
+
_ts_metadata("design:type", Array)
|
|
302
|
+
], BundleFlowDto.prototype, "edges", void 0);
|
|
303
|
+
class DefinitionBundleDto {
|
|
304
|
+
format;
|
|
305
|
+
version;
|
|
306
|
+
entities;
|
|
307
|
+
flows;
|
|
308
|
+
}
|
|
309
|
+
_ts_decorate([
|
|
310
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)({
|
|
311
|
+
example: _interfaces_definition_bundle_interface_js__rspack_import_7/* .DEFINITION_BUNDLE_FORMAT */.D
|
|
312
|
+
}),
|
|
313
|
+
(0,class_validator__rspack_import_2.Equals)(_interfaces_definition_bundle_interface_js__rspack_import_7/* .DEFINITION_BUNDLE_FORMAT */.D),
|
|
314
|
+
_ts_metadata("design:type", Object)
|
|
315
|
+
], DefinitionBundleDto.prototype, "format", void 0);
|
|
316
|
+
_ts_decorate([
|
|
317
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)({
|
|
318
|
+
example: (/* inlined export .DEFINITION_BUNDLE_VERSION */1)
|
|
319
|
+
}),
|
|
320
|
+
(0,class_validator__rspack_import_2.Equals)((/* inlined export .DEFINITION_BUNDLE_VERSION */1)),
|
|
321
|
+
_ts_metadata("design:type", Object)
|
|
322
|
+
], DefinitionBundleDto.prototype, "version", void 0);
|
|
323
|
+
_ts_decorate([
|
|
324
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)({
|
|
325
|
+
type: [
|
|
326
|
+
BundleEntityDto
|
|
327
|
+
]
|
|
328
|
+
}),
|
|
329
|
+
(0,class_validator__rspack_import_2.IsArray)(),
|
|
330
|
+
(0,class_validator__rspack_import_2.ValidateNested)({
|
|
331
|
+
each: true
|
|
332
|
+
}),
|
|
333
|
+
(0,class_transformer__rspack_import_1.Type)(()=>BundleEntityDto),
|
|
334
|
+
_ts_metadata("design:type", Array)
|
|
335
|
+
], DefinitionBundleDto.prototype, "entities", void 0);
|
|
336
|
+
_ts_decorate([
|
|
337
|
+
(0,_nestjs_swagger__rspack_import_0.ApiProperty)({
|
|
338
|
+
type: [
|
|
339
|
+
BundleFlowDto
|
|
340
|
+
]
|
|
341
|
+
}),
|
|
342
|
+
(0,class_validator__rspack_import_2.IsArray)(),
|
|
343
|
+
(0,class_validator__rspack_import_2.ValidateNested)({
|
|
344
|
+
each: true
|
|
345
|
+
}),
|
|
346
|
+
(0,class_transformer__rspack_import_1.Type)(()=>BundleFlowDto),
|
|
347
|
+
_ts_metadata("design:type", Array)
|
|
348
|
+
], DefinitionBundleDto.prototype, "flows", void 0);
|
|
349
|
+
class ExportBundleDto {
|
|
350
|
+
entityCodes;
|
|
351
|
+
flowSlugs;
|
|
352
|
+
}
|
|
353
|
+
_ts_decorate([
|
|
354
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
355
|
+
type: [
|
|
356
|
+
String
|
|
357
|
+
],
|
|
358
|
+
description: 'Entity codes to export (all when left out)'
|
|
359
|
+
}),
|
|
360
|
+
(0,class_validator__rspack_import_2.IsOptional)(),
|
|
361
|
+
(0,class_validator__rspack_import_2.IsArray)(),
|
|
362
|
+
(0,class_validator__rspack_import_2.ArrayUnique)(),
|
|
363
|
+
(0,class_validator__rspack_import_2.IsString)({
|
|
364
|
+
each: true
|
|
365
|
+
}),
|
|
366
|
+
_ts_metadata("design:type", Array)
|
|
367
|
+
], ExportBundleDto.prototype, "entityCodes", void 0);
|
|
368
|
+
_ts_decorate([
|
|
369
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
370
|
+
type: [
|
|
371
|
+
String
|
|
372
|
+
],
|
|
373
|
+
description: 'Flow slugs to export (every published flow when left out)'
|
|
374
|
+
}),
|
|
375
|
+
(0,class_validator__rspack_import_2.IsOptional)(),
|
|
376
|
+
(0,class_validator__rspack_import_2.IsArray)(),
|
|
377
|
+
(0,class_validator__rspack_import_2.ArrayUnique)(),
|
|
378
|
+
(0,class_validator__rspack_import_2.IsString)({
|
|
379
|
+
each: true
|
|
380
|
+
}),
|
|
381
|
+
_ts_metadata("design:type", Array)
|
|
382
|
+
], ExportBundleDto.prototype, "flowSlugs", void 0);
|
|
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
|
+
/** The form fields sent with the bundle file to plan-import / apply-import. */ class ImportBundleOptionsDto {
|
|
385
|
+
deprecateMissingFields;
|
|
386
|
+
confirm;
|
|
387
|
+
expectedChecksum;
|
|
388
|
+
expectedPlanChecksum;
|
|
389
|
+
}
|
|
390
|
+
_ts_decorate([
|
|
391
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
392
|
+
description: 'Deprecate fields this environment has and the bundle does not (their columns and data stay)',
|
|
393
|
+
default: false
|
|
394
|
+
}),
|
|
395
|
+
(0,class_validator__rspack_import_2.IsOptional)(),
|
|
396
|
+
FormBoolean(),
|
|
397
|
+
(0,class_validator__rspack_import_2.IsBoolean)(),
|
|
398
|
+
_ts_metadata("design:type", Boolean)
|
|
399
|
+
], ImportBundleOptionsDto.prototype, "deprecateMissingFields", void 0);
|
|
400
|
+
_ts_decorate([
|
|
401
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
402
|
+
description: 'apply-import: acknowledge steps that lose (or may lose) data',
|
|
403
|
+
default: false
|
|
404
|
+
}),
|
|
405
|
+
(0,class_validator__rspack_import_2.IsOptional)(),
|
|
406
|
+
FormBoolean(),
|
|
407
|
+
(0,class_validator__rspack_import_2.IsBoolean)(),
|
|
408
|
+
_ts_metadata("design:type", Boolean)
|
|
409
|
+
], ImportBundleOptionsDto.prototype, "confirm", void 0);
|
|
410
|
+
_ts_decorate([
|
|
411
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
412
|
+
description: 'apply-import: the checksum of the bundle that was reviewed; a different bundle is refused'
|
|
413
|
+
}),
|
|
414
|
+
(0,class_validator__rspack_import_2.IsOptional)(),
|
|
415
|
+
(0,class_validator__rspack_import_2.IsString)(),
|
|
416
|
+
(0,class_validator__rspack_import_2.Matches)(/^[0-9a-f]{64}$/),
|
|
417
|
+
_ts_metadata("design:type", String)
|
|
418
|
+
], ImportBundleOptionsDto.prototype, "expectedChecksum", void 0);
|
|
419
|
+
_ts_decorate([
|
|
420
|
+
(0,_nestjs_swagger__rspack_import_0.ApiPropertyOptional)({
|
|
421
|
+
description: 'apply-import: the planChecksum of the plan that was reviewed; a changed plan is refused, and it is required with confirm'
|
|
422
|
+
}),
|
|
423
|
+
(0,class_validator__rspack_import_2.IsOptional)(),
|
|
424
|
+
(0,class_validator__rspack_import_2.IsString)(),
|
|
425
|
+
(0,class_validator__rspack_import_2.Matches)(/^[0-9a-f]{64}$/),
|
|
426
|
+
_ts_metadata("design:type", String)
|
|
427
|
+
], ImportBundleOptionsDto.prototype, "expectedPlanChecksum", void 0);
|
|
428
|
+
|
|
429
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
430
|
+
JE: () => (DefinitionBundleDto),
|
|
431
|
+
KH: () => (BundleFlowDto),
|
|
432
|
+
QJ: () => (ExportBundleDto),
|
|
433
|
+
U3: () => (BundleFieldDto),
|
|
434
|
+
hX: () => (BundleEntityDto),
|
|
435
|
+
vS: () => (ImportBundleOptionsDto)
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
},
|
|
440
|
+
8835(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
441
|
+
const DEFINITION_BUNDLE_FORMAT = 'flusys.entity-builder.bundle';
|
|
442
|
+
const DEFINITION_BUNDLE_VERSION = 1;
|
|
443
|
+
|
|
444
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
445
|
+
}, {
|
|
446
|
+
D: DEFINITION_BUNDLE_FORMAT
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
},
|
|
4
451
|
2492(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
5
452
|
const FLOW_REFERENCE_PROVIDER = 'FLOW_REFERENCE_PROVIDER';
|
|
6
453
|
|
|
7
454
|
__webpack_require__.d(__webpack_exports__, {
|
|
8
|
-
}, {
|
|
9
|
-
$: FLOW_REFERENCE_PROVIDER
|
|
455
|
+
}, {
|
|
456
|
+
$: FLOW_REFERENCE_PROVIDER
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
},
|
|
461
|
+
3801(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
462
|
+
/* import */ var _flusys_nestjs_shared_utils__rspack_import_0 = __webpack_require__(9216);
|
|
463
|
+
/* import */ var node_crypto__rspack_import_1 = __webpack_require__(2561);
|
|
464
|
+
/* import */ var _config_message_keys_js__rspack_import_2 = __webpack_require__(5732);
|
|
465
|
+
/* import */ var _enums_entity_status_enum_js__rspack_import_3 = __webpack_require__(1313);
|
|
466
|
+
/* import */ var _enums_field_type_enum_js__rspack_import_4 = __webpack_require__(9614);
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
/** JSON with object keys sorted at every level: equal definitions always give the same text. */ function canonicalJson(value) {
|
|
473
|
+
return JSON.stringify(sortKeys(value));
|
|
474
|
+
}
|
|
475
|
+
function sortKeys(value) {
|
|
476
|
+
if (Array.isArray(value)) return value.map(sortKeys);
|
|
477
|
+
if (value && typeof value === 'object' && !(value instanceof Date)) {
|
|
478
|
+
return Object.fromEntries(Object.keys(value).toSorted().filter((key)=>value[key] !== undefined).map((key)=>[
|
|
479
|
+
key,
|
|
480
|
+
sortKeys(value[key])
|
|
481
|
+
]));
|
|
482
|
+
}
|
|
483
|
+
return value;
|
|
484
|
+
}
|
|
485
|
+
const same = (a, b)=>canonicalJson(a ?? null) === canonicalJson(b ?? null);
|
|
486
|
+
/** Code-point order: the same in every locale, so exports and plans read the same everywhere. */ const byCode = (a, b)=>a < b ? -1 : a > b ? 1 : 0;
|
|
487
|
+
/** What a step, extra or result is about: the flow slug, `entity.field` or the entity code. */ const bundleSubject = (item)=>item.flowSlug ?? (item.fieldCode ? `${item.entityCode}.${item.fieldCode}` : item.entityCode ?? '');
|
|
488
|
+
const bundleChecksum = (bundle)=>(0,node_crypto__rspack_import_1.createHash)('sha256').update(canonicalJson(bundle)).digest('hex');
|
|
489
|
+
// ── flows: API keys and environment variables ─────────────────────────────────────────
|
|
490
|
+
/** Request steps without their API keys: a key belongs to one environment and is never promoted. */ function stripApiKeys(nodes) {
|
|
491
|
+
return nodes.map((node)=>{
|
|
492
|
+
if (node?.type !== 'trigger' || node.config?.['apiKey'] === undefined) return node;
|
|
493
|
+
const { apiKey: _apiKey, ...config } = node.config;
|
|
494
|
+
return {
|
|
495
|
+
...node,
|
|
496
|
+
config
|
|
497
|
+
};
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
const VARIABLE_PATTERN = /\$\{var:([A-Za-z_][A-Za-z0-9_]*)\}/g;
|
|
501
|
+
/** 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
|
+
/** 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
|
+
...node,
|
|
515
|
+
config: mapStrings(node.config, fn)
|
|
516
|
+
} : node);
|
|
517
|
+
const escapeRegExp = (text)=>text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
518
|
+
/**
|
|
519
|
+
* Export: every occurrence of this environment's variable values in a step's settings becomes `${var:NAME}`
|
|
520
|
+
* (longest value first; one pass, so a placeholder already written is never rewritten by a shorter value).
|
|
521
|
+
*/ function extractVariables(nodes, variables) {
|
|
522
|
+
const nameOf = new Map();
|
|
523
|
+
for (const [name, value] of Object.entries(variables).filter(([, text])=>typeof text === 'string' && text.length >= MIN_VARIABLE_VALUE_LENGTH).toSorted(([nameA, a], [nameB, b])=>b.length - a.length || byCode(nameA, nameB))){
|
|
524
|
+
if (!nameOf.has(value)) nameOf.set(value, name);
|
|
525
|
+
}
|
|
526
|
+
if (!nameOf.size) return nodes;
|
|
527
|
+
const pattern = new RegExp([
|
|
528
|
+
...nameOf.keys()
|
|
529
|
+
].map(escapeRegExp).join('|'), 'g');
|
|
530
|
+
return mapConfigStrings(nodes, (text)=>text.replace(pattern, (value)=>`\${var:${nameOf.get(value)}}`));
|
|
531
|
+
}
|
|
532
|
+
/** 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) {
|
|
533
|
+
const missing = new Set();
|
|
534
|
+
const resolved = mapConfigStrings(nodes, (text)=>text.replace(VARIABLE_PATTERN, (token, name)=>{
|
|
535
|
+
if (typeof variables[name] === 'string') return variables[name];
|
|
536
|
+
missing.add(name);
|
|
537
|
+
return token;
|
|
538
|
+
}));
|
|
539
|
+
return {
|
|
540
|
+
nodes: resolved,
|
|
541
|
+
missing: [
|
|
542
|
+
...missing
|
|
543
|
+
].toSorted(byCode)
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
/** Slugs the Call flow steps of a flow run. */ function calledFlowSlugs(nodes) {
|
|
547
|
+
return nodes.filter((node)=>node?.type === 'call_flow' && typeof node.config?.['flowSlug'] === 'string').map((node)=>node.config['flowSlug']);
|
|
548
|
+
}
|
|
549
|
+
/** Called flows before their callers, so each Call flow step finds its flow published; otherwise by slug. */ function orderFlows(flows) {
|
|
550
|
+
const bySlug = new Map(flows.map((flow)=>[
|
|
551
|
+
flow.slug,
|
|
552
|
+
flow
|
|
553
|
+
]));
|
|
554
|
+
const ordered = [];
|
|
555
|
+
const state = new Map();
|
|
556
|
+
const visit = (flow)=>{
|
|
557
|
+
if (state.has(flow.slug)) return;
|
|
558
|
+
state.set(flow.slug, 'visiting');
|
|
559
|
+
for (const slug of calledFlowSlugs(flow.nodes ?? []).toSorted(byCode)){
|
|
560
|
+
const callee = bySlug.get(slug);
|
|
561
|
+
if (callee) visit(callee);
|
|
562
|
+
}
|
|
563
|
+
state.set(flow.slug, 'done');
|
|
564
|
+
ordered.push(flow);
|
|
565
|
+
};
|
|
566
|
+
flows.toSorted((a, b)=>byCode(a.slug, b.slug)).forEach(visit);
|
|
567
|
+
return ordered;
|
|
568
|
+
}
|
|
569
|
+
const FIELD_COMPARED_KEYS = [
|
|
570
|
+
'label',
|
|
571
|
+
'fieldType',
|
|
572
|
+
'nullable',
|
|
573
|
+
'unique',
|
|
574
|
+
'isIndexed',
|
|
575
|
+
'defaultValue',
|
|
576
|
+
'validationRules',
|
|
577
|
+
'selectOptions',
|
|
578
|
+
'relationTarget',
|
|
579
|
+
'order',
|
|
580
|
+
'uiConfig',
|
|
581
|
+
'isSearchable'
|
|
582
|
+
];
|
|
583
|
+
const ENTITY_COMPARED_KEYS = [
|
|
584
|
+
'label',
|
|
585
|
+
'description',
|
|
586
|
+
'uiConfig',
|
|
587
|
+
'isSoftDeleteEnabled',
|
|
588
|
+
'isAuditEnabled',
|
|
589
|
+
'status'
|
|
590
|
+
];
|
|
591
|
+
function changedValues(from, to, keys) {
|
|
592
|
+
return Object.fromEntries(keys.filter((key)=>!same(from[key], to[key])).map((key)=>[
|
|
593
|
+
key,
|
|
594
|
+
to[key] ?? null
|
|
595
|
+
]));
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Pairs each item of the bundle with one of this environment's: by id first (a renamed one keeps
|
|
599
|
+
* its id), then by code among those no id claimed, so a rename never takes a field another item owns.
|
|
600
|
+
*/ function matchDefinitions(items, current) {
|
|
601
|
+
const pairs = new Map();
|
|
602
|
+
const taken = new Set();
|
|
603
|
+
const claim = (item, hit)=>{
|
|
604
|
+
if (!hit) return;
|
|
605
|
+
pairs.set(item, hit);
|
|
606
|
+
taken.add(hit.id);
|
|
607
|
+
};
|
|
608
|
+
for (const item of items)claim(item, current.find((c)=>c.id === item.id && !taken.has(c.id)));
|
|
609
|
+
for (const item of items.filter((i)=>!pairs.has(i)))claim(item, current.find((c)=>c.code === item.code && !taken.has(c.id)));
|
|
610
|
+
return pairs;
|
|
611
|
+
}
|
|
612
|
+
/** The bundle's own problems: duplicates, and relations to an entity neither the bundle nor this environment has. */ function bundleProblems(entities, current) {
|
|
613
|
+
const problems = [];
|
|
614
|
+
const codes = new Set();
|
|
615
|
+
for (const entity of entities){
|
|
616
|
+
if (codes.has(entity.code)) problems.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_2/* .BUNDLE_MESSAGES.DUPLICATE_ENTITY */.iX.DUPLICATE_ENTITY, {
|
|
617
|
+
entity: entity.code
|
|
618
|
+
}));
|
|
619
|
+
if (entity.status === _enums_entity_status_enum_js__rspack_import_3/* .EntityStatus.DRAFT */.c.DRAFT) problems.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_2/* .BUNDLE_MESSAGES.ENTITY_DRAFT_IN_BUNDLE */.iX.ENTITY_DRAFT_IN_BUNDLE, {
|
|
620
|
+
entity: entity.code
|
|
621
|
+
}));
|
|
622
|
+
codes.add(entity.code);
|
|
623
|
+
const fieldCodes = new Set();
|
|
624
|
+
const fieldIds = new Set();
|
|
625
|
+
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)(_config_message_keys_js__rspack_import_2/* .BUNDLE_MESSAGES.DUPLICATE_FIELD */.iX.DUPLICATE_FIELD, {
|
|
627
|
+
entity: entity.code,
|
|
628
|
+
field: field.code
|
|
629
|
+
}));
|
|
630
|
+
fieldCodes.add(field.code);
|
|
631
|
+
fieldIds.add(field.id);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
const known = new Set([
|
|
635
|
+
...codes,
|
|
636
|
+
...current.map((e)=>e.code)
|
|
637
|
+
]);
|
|
638
|
+
for (const entity of entities){
|
|
639
|
+
for (const field of entity.fields.filter((f)=>f.fieldType === _enums_field_type_enum_js__rspack_import_4/* .FieldType.RELATION */.P.RELATION && !f.deprecated)){
|
|
640
|
+
if (!field.relationTarget || !known.has(field.relationTarget)) {
|
|
641
|
+
problems.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_2/* .BUNDLE_MESSAGES.RELATION_TARGET_UNKNOWN */.iX.RELATION_TARGET_UNKNOWN, {
|
|
642
|
+
entity: entity.code,
|
|
643
|
+
field: field.code,
|
|
644
|
+
target: field.relationTarget ?? ''
|
|
645
|
+
}));
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
return problems;
|
|
650
|
+
}
|
|
651
|
+
/** A code no field of the entity has or gets, for the temporary step of a rename cycle. */ function temporaryCode(fieldId, taken) {
|
|
652
|
+
const base = `tmp_${fieldId.replace(/[^0-9a-z]/gi, '').toLowerCase().slice(0, 12)}`;
|
|
653
|
+
let code = base;
|
|
654
|
+
for(let n = 2; taken.has(code); n++)code = `${base}_${n}`;
|
|
655
|
+
taken.add(code);
|
|
656
|
+
return code;
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Renames in an order that never takes a code another field still has: a rename waits for the one
|
|
660
|
+
* that frees its new code (a -> b after b -> c), and a cycle (a <-> b) goes through a temporary code
|
|
661
|
+
* first (a -> tmp, b -> a, tmp -> b). Each rename rewrites the references to its field, so the
|
|
662
|
+
* references end up exactly where the bundle has them.
|
|
663
|
+
*/ function orderRenames(entityCode, renames, taken) {
|
|
664
|
+
const ordered = [];
|
|
665
|
+
const pending = renames.map((rename)=>({
|
|
666
|
+
...rename,
|
|
667
|
+
waited: false
|
|
668
|
+
})).toSorted((a, b)=>byCode(a.from, b.from));
|
|
669
|
+
const step = (rename, from, to, dependsOnEarlierStep, warnings)=>({
|
|
670
|
+
kind: 'rename_field',
|
|
671
|
+
entityCode,
|
|
672
|
+
fieldCode: from,
|
|
673
|
+
targetFieldId: rename.targetFieldId,
|
|
674
|
+
details: {
|
|
675
|
+
from,
|
|
676
|
+
to
|
|
677
|
+
},
|
|
678
|
+
dependsOnEarlierStep,
|
|
679
|
+
changes: {
|
|
680
|
+
code: to
|
|
681
|
+
},
|
|
682
|
+
...warnings ? {
|
|
683
|
+
warnings
|
|
684
|
+
} : {}
|
|
685
|
+
});
|
|
686
|
+
while(pending.length){
|
|
687
|
+
const ready = pending.filter((rename)=>!pending.some((other)=>other !== rename && other.from === rename.to));
|
|
688
|
+
if (ready.length) {
|
|
689
|
+
for (const rename of ready){
|
|
690
|
+
ordered.push(step(rename, rename.from, rename.to, rename.restored || rename.waited));
|
|
691
|
+
pending.splice(pending.indexOf(rename), 1);
|
|
692
|
+
}
|
|
693
|
+
for (const rename of pending)rename.waited = true;
|
|
694
|
+
continue;
|
|
695
|
+
}
|
|
696
|
+
const first = pending[0];
|
|
697
|
+
const temporary = temporaryCode(first.targetFieldId, taken);
|
|
698
|
+
ordered.push(step(first, first.from, temporary, first.restored || first.waited, [
|
|
699
|
+
(0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_2/* .BUNDLE_MESSAGES.RENAME_VIA_TEMPORARY */.iX.RENAME_VIA_TEMPORARY, {
|
|
700
|
+
field: first.from,
|
|
701
|
+
temporary,
|
|
702
|
+
to: first.to
|
|
703
|
+
})
|
|
704
|
+
]));
|
|
705
|
+
const freed = pending.find((rename)=>rename.to === first.from);
|
|
706
|
+
if (freed) freed.waited = true;
|
|
707
|
+
first.from = temporary;
|
|
708
|
+
first.waited = true;
|
|
709
|
+
}
|
|
710
|
+
return ordered;
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* What it takes to bring this environment's entities to the bundle's. Entities and fields are
|
|
714
|
+
* matched by id first (a field renamed where it was designed keeps its id), then by code. Nothing
|
|
715
|
+
* the bundle lacks is removed: such definitions are reported as extras, and only with
|
|
716
|
+
* `deprecateMissingFields` are missing fields deprecated (which keeps their column and data).
|
|
717
|
+
*
|
|
718
|
+
* Order: entities switched back on, new entities (their relation fields wait until every new entity
|
|
719
|
+
* exists), field changes of existing entities (per entity: restores, renames, changes, new fields,
|
|
720
|
+
* deprecations), the new entities' relation fields, and entities switched off last. A DRAFT entity
|
|
721
|
+
* (no table) on either side blocks the import.
|
|
722
|
+
*/ function diffEntities(entities, current, options = {}) {
|
|
723
|
+
const result = {
|
|
724
|
+
operations: [],
|
|
725
|
+
unchangedEntities: 0,
|
|
726
|
+
unchangedFields: 0,
|
|
727
|
+
extras: [],
|
|
728
|
+
blockers: bundleProblems(entities, current)
|
|
729
|
+
};
|
|
730
|
+
const entityUpdatesFirst = [];
|
|
731
|
+
const creates = [];
|
|
732
|
+
const fieldOps = [];
|
|
733
|
+
const relationAdds = [];
|
|
734
|
+
const entityUpdatesLast = [];
|
|
735
|
+
const sorted = entities.toSorted((a, b)=>byCode(a.code, b.code));
|
|
736
|
+
const pairs = matchDefinitions(sorted, current);
|
|
737
|
+
const matched = new Set([
|
|
738
|
+
...pairs.values()
|
|
739
|
+
].map((e)=>e.id));
|
|
740
|
+
for (const entity of sorted){
|
|
741
|
+
const target = pairs.get(entity);
|
|
742
|
+
if (target && target.code !== entity.code) {
|
|
743
|
+
result.blockers.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_2/* .BUNDLE_MESSAGES.ENTITY_CODE_CHANGED */.iX.ENTITY_CODE_CHANGED, {
|
|
744
|
+
entity: entity.code,
|
|
745
|
+
current: target.code
|
|
746
|
+
}));
|
|
747
|
+
continue;
|
|
748
|
+
}
|
|
749
|
+
if (!target) {
|
|
750
|
+
const live = entity.fields.filter((f)=>!f.deprecated);
|
|
751
|
+
creates.push({
|
|
752
|
+
kind: 'create_entity',
|
|
753
|
+
entityCode: entity.code,
|
|
754
|
+
details: {
|
|
755
|
+
fields: live.filter((f)=>f.fieldType !== _enums_field_type_enum_js__rspack_import_4/* .FieldType.RELATION */.P.RELATION).map((f)=>f.code)
|
|
756
|
+
},
|
|
757
|
+
dependsOnEarlierStep: false,
|
|
758
|
+
entity: {
|
|
759
|
+
...entity,
|
|
760
|
+
fields: live.filter((f)=>f.fieldType !== _enums_field_type_enum_js__rspack_import_4/* .FieldType.RELATION */.P.RELATION)
|
|
761
|
+
}
|
|
762
|
+
});
|
|
763
|
+
for (const field of live.filter((f)=>f.fieldType === _enums_field_type_enum_js__rspack_import_4/* .FieldType.RELATION */.P.RELATION)){
|
|
764
|
+
relationAdds.push({
|
|
765
|
+
kind: 'add_field',
|
|
766
|
+
entityCode: entity.code,
|
|
767
|
+
fieldCode: field.code,
|
|
768
|
+
details: {
|
|
769
|
+
fieldType: field.fieldType,
|
|
770
|
+
relationTarget: field.relationTarget
|
|
771
|
+
},
|
|
772
|
+
dependsOnEarlierStep: true,
|
|
773
|
+
field
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
if (entity.status === _enums_entity_status_enum_js__rspack_import_3/* .EntityStatus.DEPRECATED */.c.DEPRECATED) {
|
|
777
|
+
entityUpdatesLast.push({
|
|
778
|
+
kind: 'update_entity',
|
|
779
|
+
entityCode: entity.code,
|
|
780
|
+
details: {
|
|
781
|
+
changes: [
|
|
782
|
+
'status'
|
|
783
|
+
]
|
|
784
|
+
},
|
|
785
|
+
dependsOnEarlierStep: true,
|
|
786
|
+
changes: {
|
|
787
|
+
status: _enums_entity_status_enum_js__rspack_import_3/* .EntityStatus.DEPRECATED */.c.DEPRECATED
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
continue;
|
|
792
|
+
}
|
|
793
|
+
if (target.status === _enums_entity_status_enum_js__rspack_import_3/* .EntityStatus.DRAFT */.c.DRAFT) {
|
|
794
|
+
result.blockers.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_2/* .BUNDLE_MESSAGES.ENTITY_DRAFT_HERE */.iX.ENTITY_DRAFT_HERE, {
|
|
795
|
+
entity: entity.code
|
|
796
|
+
}));
|
|
797
|
+
continue;
|
|
798
|
+
}
|
|
799
|
+
const entityChanges = changedValues(target, entity, ENTITY_COMPARED_KEYS);
|
|
800
|
+
const deprecating = entityChanges['status'] === _enums_entity_status_enum_js__rspack_import_3/* .EntityStatus.DEPRECATED */.c.DEPRECATED;
|
|
801
|
+
if (Object.keys(entityChanges).length) {
|
|
802
|
+
(deprecating ? entityUpdatesLast : entityUpdatesFirst).push({
|
|
803
|
+
kind: 'update_entity',
|
|
804
|
+
entityCode: entity.code,
|
|
805
|
+
details: {
|
|
806
|
+
changes: Object.keys(entityChanges)
|
|
807
|
+
},
|
|
808
|
+
dependsOnEarlierStep: false,
|
|
809
|
+
changes: entityChanges
|
|
810
|
+
});
|
|
811
|
+
} else {
|
|
812
|
+
result.unchangedEntities++;
|
|
813
|
+
}
|
|
814
|
+
const fields = entity.fields.toSorted((a, b)=>a.order - b.order || byCode(a.code, b.code));
|
|
815
|
+
const fieldPairs = matchDefinitions(fields, target.fields);
|
|
816
|
+
const usedFieldIds = new Set([
|
|
817
|
+
...fieldPairs.values()
|
|
818
|
+
].map((f)=>f.id));
|
|
819
|
+
const restores = [];
|
|
820
|
+
const renames = [];
|
|
821
|
+
const updates = [];
|
|
822
|
+
const adds = [];
|
|
823
|
+
const deprecations = [];
|
|
824
|
+
for (const field of fields){
|
|
825
|
+
const existing = fieldPairs.get(field);
|
|
826
|
+
if (!existing) {
|
|
827
|
+
if (field.deprecated) continue;
|
|
828
|
+
adds.push({
|
|
829
|
+
kind: 'add_field',
|
|
830
|
+
entityCode: entity.code,
|
|
831
|
+
fieldCode: field.code,
|
|
832
|
+
details: {
|
|
833
|
+
fieldType: field.fieldType,
|
|
834
|
+
relationTarget: field.relationTarget
|
|
835
|
+
},
|
|
836
|
+
dependsOnEarlierStep: false,
|
|
837
|
+
field
|
|
838
|
+
});
|
|
839
|
+
continue;
|
|
840
|
+
}
|
|
841
|
+
const at = {
|
|
842
|
+
entityCode: entity.code,
|
|
843
|
+
targetFieldId: existing.id
|
|
844
|
+
};
|
|
845
|
+
let touched = false;
|
|
846
|
+
// A deprecated field cannot be changed until it is restored; a rename does not stop the other changes from being previewed.
|
|
847
|
+
const restored = existing.deprecated && !field.deprecated;
|
|
848
|
+
if (restored) {
|
|
849
|
+
restores.push({
|
|
850
|
+
...at,
|
|
851
|
+
kind: 'restore_field',
|
|
852
|
+
fieldCode: existing.code,
|
|
853
|
+
details: {},
|
|
854
|
+
dependsOnEarlierStep: false
|
|
855
|
+
});
|
|
856
|
+
touched = true;
|
|
857
|
+
}
|
|
858
|
+
if (existing.code !== field.code && !field.deprecated) {
|
|
859
|
+
renames.push({
|
|
860
|
+
targetFieldId: existing.id,
|
|
861
|
+
from: existing.code,
|
|
862
|
+
to: field.code,
|
|
863
|
+
restored
|
|
864
|
+
});
|
|
865
|
+
touched = true;
|
|
866
|
+
}
|
|
867
|
+
const changes = field.deprecated ? {} : changedValues(existing, field, FIELD_COMPARED_KEYS);
|
|
868
|
+
if (Object.keys(changes).length) {
|
|
869
|
+
updates.push({
|
|
870
|
+
...at,
|
|
871
|
+
kind: 'update_field',
|
|
872
|
+
fieldCode: field.code,
|
|
873
|
+
details: {
|
|
874
|
+
changes: Object.keys(changes)
|
|
875
|
+
},
|
|
876
|
+
dependsOnEarlierStep: restored,
|
|
877
|
+
changes
|
|
878
|
+
});
|
|
879
|
+
touched = true;
|
|
880
|
+
}
|
|
881
|
+
if (field.deprecated && !existing.deprecated) {
|
|
882
|
+
deprecations.push({
|
|
883
|
+
...at,
|
|
884
|
+
kind: 'deprecate_field',
|
|
885
|
+
fieldCode: existing.code,
|
|
886
|
+
details: {},
|
|
887
|
+
dependsOnEarlierStep: false
|
|
888
|
+
});
|
|
889
|
+
touched = true;
|
|
890
|
+
}
|
|
891
|
+
if (!touched) result.unchangedFields++;
|
|
892
|
+
}
|
|
893
|
+
// A new field may take a code a rename frees: it is added once that rename has run.
|
|
894
|
+
const freedCodes = new Set(renames.map((r)=>r.from));
|
|
895
|
+
for (const add of adds)if (freedCodes.has(add.fieldCode)) add.dependsOnEarlierStep = true;
|
|
896
|
+
const takenCodes = new Set([
|
|
897
|
+
...target.fields.map((f)=>f.code),
|
|
898
|
+
...fields.map((f)=>f.code)
|
|
899
|
+
]);
|
|
900
|
+
fieldOps.push(...restores, ...orderRenames(entity.code, renames, takenCodes), ...updates, ...adds, ...deprecations);
|
|
901
|
+
for (const extra of target.fields.filter((f)=>!usedFieldIds.has(f.id) && !f.deprecated)){
|
|
902
|
+
if (options.deprecateMissingFields) {
|
|
903
|
+
fieldOps.push({
|
|
904
|
+
kind: 'deprecate_field',
|
|
905
|
+
entityCode: entity.code,
|
|
906
|
+
fieldCode: extra.code,
|
|
907
|
+
targetFieldId: extra.id,
|
|
908
|
+
details: {},
|
|
909
|
+
dependsOnEarlierStep: false
|
|
910
|
+
});
|
|
911
|
+
} else {
|
|
912
|
+
result.extras.push({
|
|
913
|
+
kind: 'field',
|
|
914
|
+
entityCode: entity.code,
|
|
915
|
+
fieldCode: extra.code
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
for (const extra of current.filter((e)=>!matched.has(e.id)))result.extras.push({
|
|
921
|
+
kind: 'entity',
|
|
922
|
+
entityCode: extra.code
|
|
923
|
+
});
|
|
924
|
+
result.operations = [
|
|
925
|
+
...entityUpdatesFirst,
|
|
926
|
+
...creates,
|
|
927
|
+
...fieldOps,
|
|
928
|
+
...relationAdds,
|
|
929
|
+
...entityUpdatesLast
|
|
930
|
+
];
|
|
931
|
+
return result;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
935
|
+
Og: () => (matchDefinitions),
|
|
936
|
+
Q5: () => (calledFlowSlugs),
|
|
937
|
+
dX: () => (stripApiKeys),
|
|
938
|
+
dj: () => (canonicalJson),
|
|
939
|
+
gT: () => (applyVariables),
|
|
940
|
+
lj: () => (extractVariables),
|
|
941
|
+
qG: () => (orderFlows),
|
|
942
|
+
zb: () => (diffEntities)
|
|
943
|
+
}, {
|
|
944
|
+
$I: ENTITY_COMPARED_KEYS,
|
|
945
|
+
VU: byCode,
|
|
946
|
+
bs: bundleSubject,
|
|
947
|
+
i9: bundleChecksum,
|
|
948
|
+
mT: FIELD_COMPARED_KEYS
|
|
949
|
+
});
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
},
|
|
953
|
+
6412(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
954
|
+
/* import */ var _nestjs_common__rspack_import_0 = __webpack_require__(6157);
|
|
955
|
+
/* import */ var class_transformer__rspack_import_1 = __webpack_require__(5812);
|
|
956
|
+
/* import */ var class_validator__rspack_import_2 = __webpack_require__(5421);
|
|
957
|
+
/* import */ var _config_message_keys_js__rspack_import_4 = __webpack_require__(5732);
|
|
958
|
+
/* import */ var _dtos_definition_bundle_dto_js__rspack_import_3 = __webpack_require__(6691);
|
|
959
|
+
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
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 = '') {
|
|
966
|
+
return errors.flatMap((error)=>{
|
|
967
|
+
const field = parent ? `${parent}.${error.property}` : error.property;
|
|
968
|
+
const own = error.constraints ? [
|
|
969
|
+
{
|
|
970
|
+
field,
|
|
971
|
+
message: Object.values(error.constraints).join('; ')
|
|
972
|
+
}
|
|
973
|
+
] : [];
|
|
974
|
+
return [
|
|
975
|
+
...own,
|
|
976
|
+
...problems(error.children ?? [], field)
|
|
977
|
+
];
|
|
978
|
+
});
|
|
979
|
+
}
|
|
980
|
+
const invalid = (errors = [])=>new _nestjs_common__rspack_import_0.BadRequestException({
|
|
981
|
+
message: 'The file is not a valid entity builder bundle.',
|
|
982
|
+
messageKey: _config_message_keys_js__rspack_import_4/* .BUNDLE_MESSAGES.FILE_INVALID */.iX.FILE_INVALID,
|
|
983
|
+
...errors.length ? {
|
|
984
|
+
errors: errors.slice(0, MAX_REPORTED_PROBLEMS)
|
|
985
|
+
} : {}
|
|
986
|
+
});
|
|
987
|
+
/**
|
|
988
|
+
* The uploaded bundle, parsed and checked as strictly as a request body (unknown keys refused). The
|
|
989
|
+
* 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 FileInterceptor).
|
|
991
|
+
*/ function readBundleFile(file) {
|
|
992
|
+
if (!file?.buffer?.length) {
|
|
993
|
+
throw new _nestjs_common__rspack_import_0.BadRequestException({
|
|
994
|
+
message: 'Attach the bundle file as the "bundle" form field.',
|
|
995
|
+
messageKey: _config_message_keys_js__rspack_import_4/* .BUNDLE_MESSAGES.FILE_REQUIRED */.iX.FILE_REQUIRED
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
let raw;
|
|
999
|
+
try {
|
|
1000
|
+
raw = JSON.parse(file.buffer.toString('utf8').replace(/^\uFEFF/, ''));
|
|
1001
|
+
} catch {
|
|
1002
|
+
throw invalid();
|
|
1003
|
+
}
|
|
1004
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) throw invalid();
|
|
1005
|
+
const bundle = (0,class_transformer__rspack_import_1.plainToInstance)(_dtos_definition_bundle_dto_js__rspack_import_3/* .DefinitionBundleDto */.JE, raw);
|
|
1006
|
+
const errors = (0,class_validator__rspack_import_2.validateSync)(bundle, {
|
|
1007
|
+
whitelist: true,
|
|
1008
|
+
forbidNonWhitelisted: true
|
|
1009
|
+
});
|
|
1010
|
+
if (errors.length) throw invalid(problems(errors));
|
|
1011
|
+
return bundle;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
1015
|
+
z: () => (readBundleFile)
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1018
|
+
|
|
1019
|
+
},
|
|
1020
|
+
7463(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
1021
|
+
/* import */ var _flusys_nestjs_shared_utils__rspack_import_0 = __webpack_require__(9216);
|
|
1022
|
+
/* import */ var _nestjs_common__rspack_import_1 = __webpack_require__(6157);
|
|
1023
|
+
/* import */ var node_crypto__rspack_import_2 = __webpack_require__(2561);
|
|
1024
|
+
/* import */ var typeorm__rspack_import_3 = __webpack_require__(7158);
|
|
1025
|
+
/* import */ var _config_message_keys_js__rspack_import_17 = __webpack_require__(5732);
|
|
1026
|
+
/* import */ var _dtos_schema_change_dto_js__rspack_import_4 = __webpack_require__(4945);
|
|
1027
|
+
/* import */ var _entities_entity_definition_entity_js__rspack_import_5 = __webpack_require__(3189);
|
|
1028
|
+
/* import */ var _enums_entity_status_enum_js__rspack_import_16 = __webpack_require__(1313);
|
|
1029
|
+
/* import */ var _entities_field_definition_entity_js__rspack_import_6 = __webpack_require__(2206);
|
|
1030
|
+
/* import */ var _entities_flow_definition_entity_js__rspack_import_7 = __webpack_require__(3770);
|
|
1031
|
+
/* import */ var _flow_engine_flow_errors_js__rspack_import_8 = __webpack_require__(8542);
|
|
1032
|
+
/* import */ var _flow_engine_flow_types_js__rspack_import_9 = __webpack_require__(6256);
|
|
1033
|
+
/* import */ var _interfaces_definition_bundle_interface_js__rspack_import_18 = __webpack_require__(8835);
|
|
1034
|
+
/* import */ var _interfaces_flow_definition_interface_js__rspack_import_19 = __webpack_require__(9609);
|
|
1035
|
+
/* import */ var _definition_bundle_diff_js__rspack_import_10 = __webpack_require__(3801);
|
|
1036
|
+
/* import */ var _entity_builder_config_service_js__rspack_import_11 = __webpack_require__(4281);
|
|
1037
|
+
/* import */ var _entity_builder_datasource_provider_js__rspack_import_12 = __webpack_require__(424);
|
|
1038
|
+
/* import */ var _flow_definition_service_js__rspack_import_13 = __webpack_require__(5229);
|
|
1039
|
+
/* import */ var _schema_evolution_service_js__rspack_import_14 = __webpack_require__(3606);
|
|
1040
|
+
/* import */ var _schema_sync_service_js__rspack_import_15 = __webpack_require__(3474);
|
|
1041
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
1042
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1043
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
1044
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
1045
|
+
} else {
|
|
1046
|
+
for(var i = decorators.length - 1; i >= 0; i--){
|
|
1047
|
+
if (d = decorators[i]) {
|
|
1048
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1053
|
+
}
|
|
1054
|
+
function _ts_metadata(metadataKey, metadataValue) {
|
|
1055
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
1056
|
+
return Reflect.metadata(metadataKey, metadataValue);
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
function _ts_param(paramIndex, decorator) {
|
|
1060
|
+
return function(target, key) {
|
|
1061
|
+
decorator(target, key, paramIndex);
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
/** 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 _nestjs_common__rspack_import_1.HttpException)) return [];
|
|
1086
|
+
const response = error.getResponse();
|
|
1087
|
+
if (typeof response !== 'object') return [];
|
|
1088
|
+
const details = response.blockers ?? response.errors ?? [];
|
|
1089
|
+
return details.filter((d)=>typeof d?.messageKey === 'string').map((d)=>(0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(d.messageKey, d.messageVariables));
|
|
1090
|
+
}
|
|
1091
|
+
/** 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
|
+
'fieldType',
|
|
1093
|
+
'nullable',
|
|
1094
|
+
'unique'
|
|
1095
|
+
];
|
|
1096
|
+
const LOSSY_ENTITY_CHANGES = [
|
|
1097
|
+
'isSoftDeleteEnabled',
|
|
1098
|
+
'isAuditEnabled'
|
|
1099
|
+
];
|
|
1100
|
+
function mayLoseData(step) {
|
|
1101
|
+
const changes = Array.isArray(step.details['changes']) ? step.details['changes'] : [];
|
|
1102
|
+
if (step.kind === 'update_field') return changes.some((c)=>LOSSY_FIELD_CHANGES.includes(c));
|
|
1103
|
+
return step.kind === 'update_entity' && changes.some((c)=>LOSSY_ENTITY_CHANGES.includes(c));
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* What was reviewed: the bundle, the options and every step (kind, subject, changes, and whether its
|
|
1107
|
+
* preview loses data). Not the SQL or row counts, which change with every write and would refuse each apply.
|
|
1108
|
+
*/ function planChecksum(bundle, deprecateMissingFields, steps) {
|
|
1109
|
+
const reviewed = steps.map((step)=>({
|
|
1110
|
+
kind: step.kind,
|
|
1111
|
+
subject: (0,_definition_bundle_diff_js__rspack_import_10/* .bundleSubject */.bs)(step),
|
|
1112
|
+
details: step.details,
|
|
1113
|
+
destructive: step.preview?.destructive ?? null
|
|
1114
|
+
}));
|
|
1115
|
+
return (0,node_crypto__rspack_import_2.createHash)('sha256').update((0,_definition_bundle_diff_js__rspack_import_10/* .canonicalJson */.dj)({
|
|
1116
|
+
bundle,
|
|
1117
|
+
deprecateMissingFields,
|
|
1118
|
+
steps: reviewed
|
|
1119
|
+
})).digest('hex');
|
|
1120
|
+
}
|
|
1121
|
+
const newApiKey = ()=>`fk_${(0,node_crypto__rspack_import_2.randomBytes)(4).toString('hex')}_${(0,node_crypto__rspack_import_2.randomBytes)(16).toString('hex')}`;
|
|
1122
|
+
const triggerPath = (node)=>typeof node.config?.['path'] === 'string' && node.config['path'] ? node.config['path'] : null;
|
|
1123
|
+
const needsApiKey = (node)=>node?.type === 'trigger' && node.config?.['authMode'] === 'api_key';
|
|
1124
|
+
/** The stored API keys of a flow's Request steps (published and draft), by step id. */ function storedApiKeys(flow) {
|
|
1125
|
+
const keys = new Map();
|
|
1126
|
+
for (const node of [
|
|
1127
|
+
...flow?.nodes ?? [],
|
|
1128
|
+
...flow?.draft?.nodes ?? []
|
|
1129
|
+
]){
|
|
1130
|
+
if (node?.type === 'trigger' && (0,_flow_engine_flow_types_js__rspack_import_9/* .isStoredApiKey */.xA)(node.config?.['apiKey']) && !keys.has(node.id)) keys.set(node.id, node.config['apiKey']);
|
|
1131
|
+
}
|
|
1132
|
+
return keys;
|
|
1133
|
+
}
|
|
1134
|
+
class DefinitionBundleService {
|
|
1135
|
+
provider;
|
|
1136
|
+
config;
|
|
1137
|
+
schemaSync;
|
|
1138
|
+
evolution;
|
|
1139
|
+
flows;
|
|
1140
|
+
constructor(provider, config, schemaSync, evolution, flows){
|
|
1141
|
+
this.provider = provider;
|
|
1142
|
+
this.config = config;
|
|
1143
|
+
this.schemaSync = schemaSync;
|
|
1144
|
+
this.evolution = evolution;
|
|
1145
|
+
this.flows = flows;
|
|
1146
|
+
}
|
|
1147
|
+
variables() {
|
|
1148
|
+
return this.config.getBundleVariables();
|
|
1149
|
+
}
|
|
1150
|
+
// ── export ──────────────────────────────────────────────────────────────────────────
|
|
1151
|
+
async export(dto) {
|
|
1152
|
+
const current = await this.loadEntities();
|
|
1153
|
+
const selected = dto.entityCodes ? current.filter((e)=>dto.entityCodes.includes(e.code)) : current;
|
|
1154
|
+
// 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 === _enums_entity_status_enum_js__rspack_import_16/* .EntityStatus.DRAFT */.c.DRAFT).toSorted((a, b)=>(0,_definition_bundle_diff_js__rspack_import_10/* .byCode */.VU)(a.code, b.code));
|
|
1156
|
+
const entities = selected.filter((e)=>e.status !== _enums_entity_status_enum_js__rspack_import_16/* .EntityStatus.DRAFT */.c.DRAFT).toSorted((a, b)=>(0,_definition_bundle_diff_js__rspack_import_10/* .byCode */.VU)(a.code, b.code)).map((entity)=>({
|
|
1157
|
+
...entity,
|
|
1158
|
+
fields: entity.fields.toSorted((a, b)=>a.order - b.order || (0,_definition_bundle_diff_js__rspack_import_10/* .byCode */.VU)(a.code, b.code))
|
|
1159
|
+
}));
|
|
1160
|
+
const flowRepo = await this.provider.getRepository(_entities_flow_definition_entity_js__rspack_import_7/* .FlowDefinition */.G);
|
|
1161
|
+
const rows = (await flowRepo.find({
|
|
1162
|
+
where: dto.flowSlugs ? {
|
|
1163
|
+
slug: (0,typeorm__rspack_import_3.In)(dto.flowSlugs)
|
|
1164
|
+
} : {}
|
|
1165
|
+
})).toSorted((a, b)=>(0,_definition_bundle_diff_js__rspack_import_10/* .byCode */.VU)(a.slug, b.slug));
|
|
1166
|
+
const warnings = [
|
|
1167
|
+
...drafts.map((entity)=>(0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.ENTITY_DRAFT_SKIPPED */.iX.ENTITY_DRAFT_SKIPPED, {
|
|
1168
|
+
entity: entity.code
|
|
1169
|
+
})),
|
|
1170
|
+
...rows.filter((flow)=>!(0,_flow_definition_service_js__rspack_import_13/* .isPublished */.HF)(flow)).map((flow)=>(0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.FLOW_UNPUBLISHED_SKIPPED */.iX.FLOW_UNPUBLISHED_SKIPPED, {
|
|
1171
|
+
flow: flow.slug
|
|
1172
|
+
}))
|
|
1173
|
+
];
|
|
1174
|
+
const variables = this.variables();
|
|
1175
|
+
const flows = rows.filter(_flow_definition_service_js__rspack_import_13/* .isPublished */.HF).map((flow)=>{
|
|
1176
|
+
const snapshot = (0,_flow_definition_service_js__rspack_import_13/* .snapshotOf */.eY)(flow);
|
|
1177
|
+
return {
|
|
1178
|
+
...snapshot,
|
|
1179
|
+
description: snapshot.description ?? null,
|
|
1180
|
+
nodes: (0,_definition_bundle_diff_js__rspack_import_10/* .extractVariables */.lj)((0,_definition_bundle_diff_js__rspack_import_10/* .stripApiKeys */.dX)(snapshot.nodes ?? []), variables),
|
|
1181
|
+
edges: snapshot.edges ?? []
|
|
1182
|
+
};
|
|
1183
|
+
});
|
|
1184
|
+
// Keys sorted at every level: PostgreSQL and MySQL hand JSON columns back in different key orders.
|
|
1185
|
+
const bundle = JSON.parse((0,_definition_bundle_diff_js__rspack_import_10/* .canonicalJson */.dj)({
|
|
1186
|
+
format: _interfaces_definition_bundle_interface_js__rspack_import_18/* .DEFINITION_BUNDLE_FORMAT */.D,
|
|
1187
|
+
version: (/* inlined export .DEFINITION_BUNDLE_VERSION */1),
|
|
1188
|
+
entities,
|
|
1189
|
+
flows
|
|
1190
|
+
}));
|
|
1191
|
+
return {
|
|
1192
|
+
bundle,
|
|
1193
|
+
checksum: (0,_definition_bundle_diff_js__rspack_import_10/* .bundleChecksum */.i9)(bundle),
|
|
1194
|
+
warnings
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
/** Every entity of this environment with its fields, relations named by target code. */ async loadEntities() {
|
|
1198
|
+
const definitions = await (await this.provider.getRepository(_entities_entity_definition_entity_js__rspack_import_5/* .EntityDefinition */.f)).find();
|
|
1199
|
+
const fields = await (await this.provider.getRepository(_entities_field_definition_entity_js__rspack_import_6/* .FieldDefinition */.c)).find();
|
|
1200
|
+
const codeOf = new Map(definitions.map((d)=>[
|
|
1201
|
+
d.id,
|
|
1202
|
+
d.code
|
|
1203
|
+
]));
|
|
1204
|
+
return definitions.map((definition)=>({
|
|
1205
|
+
id: definition.id,
|
|
1206
|
+
code: definition.code,
|
|
1207
|
+
label: definition.label,
|
|
1208
|
+
description: definition.description ?? null,
|
|
1209
|
+
status: definition.status,
|
|
1210
|
+
isSoftDeleteEnabled: definition.isSoftDeleteEnabled,
|
|
1211
|
+
isAuditEnabled: definition.isAuditEnabled,
|
|
1212
|
+
uiConfig: definition.uiConfig ?? null,
|
|
1213
|
+
fields: fields.filter((f)=>f.entityDefinitionId === definition.id && !f.isSystemField).map((f)=>({
|
|
1214
|
+
id: f.id,
|
|
1215
|
+
code: f.code,
|
|
1216
|
+
label: f.label,
|
|
1217
|
+
fieldType: f.fieldType,
|
|
1218
|
+
nullable: f.nullable,
|
|
1219
|
+
unique: f.unique,
|
|
1220
|
+
isIndexed: f.isIndexed,
|
|
1221
|
+
defaultValue: f.defaultValue ?? null,
|
|
1222
|
+
validationRules: f.validationRules ?? null,
|
|
1223
|
+
selectOptions: f.selectOptions ?? null,
|
|
1224
|
+
relationTarget: f.relationTargetEntityId ? codeOf.get(f.relationTargetEntityId) ?? null : null,
|
|
1225
|
+
order: f.order,
|
|
1226
|
+
uiConfig: f.uiConfig ?? null,
|
|
1227
|
+
isSearchable: f.isSearchable,
|
|
1228
|
+
deprecated: !!f.deprecatedAt
|
|
1229
|
+
}))
|
|
1230
|
+
}));
|
|
1231
|
+
}
|
|
1232
|
+
// ── plan ────────────────────────────────────────────────────────────────────────────
|
|
1233
|
+
async planImport(dto, user) {
|
|
1234
|
+
const { plan } = await this.buildPlan(dto, user);
|
|
1235
|
+
return plan;
|
|
1236
|
+
}
|
|
1237
|
+
/** The plan, with what apply-import runs: the entity operations and the flows, in order. */ async buildPlan(dto, user) {
|
|
1238
|
+
const bundle = dto.bundle;
|
|
1239
|
+
const current = await this.loadEntities();
|
|
1240
|
+
const entityDiff = (0,_definition_bundle_diff_js__rspack_import_10/* .diffEntities */.zb)(bundle.entities, current, {
|
|
1241
|
+
deprecateMissingFields: dto.deprecateMissingFields === true
|
|
1242
|
+
});
|
|
1243
|
+
const flowDiff = await this.diffFlows(bundle.flows);
|
|
1244
|
+
const existingCodes = new Set(current.map((e)=>e.code));
|
|
1245
|
+
const steps = [];
|
|
1246
|
+
for (const operation of entityDiff.operations){
|
|
1247
|
+
const dependent = operation.dependsOnEarlierStep || operation.kind !== 'create_entity' && !existingCodes.has(operation.entityCode) || this.relationNotYetCreated(operation, existingCodes);
|
|
1248
|
+
const step = {
|
|
1249
|
+
kind: operation.kind,
|
|
1250
|
+
entityCode: operation.entityCode,
|
|
1251
|
+
...operation.fieldCode ? {
|
|
1252
|
+
fieldCode: operation.fieldCode
|
|
1253
|
+
} : {},
|
|
1254
|
+
details: operation.details,
|
|
1255
|
+
preview: null,
|
|
1256
|
+
warnings: [
|
|
1257
|
+
...operation.warnings ?? [],
|
|
1258
|
+
...dependent ? [
|
|
1259
|
+
(0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.STEP_AFTER_EARLIER */.iX.STEP_AFTER_EARLIER)
|
|
1260
|
+
] : []
|
|
1261
|
+
],
|
|
1262
|
+
blockers: []
|
|
1263
|
+
};
|
|
1264
|
+
if (!dependent) {
|
|
1265
|
+
try {
|
|
1266
|
+
step.preview = await this.previewEntityStep(operation, current, user);
|
|
1267
|
+
step.blockers.push(...step.preview.blockers);
|
|
1268
|
+
} catch (error) {
|
|
1269
|
+
step.blockers.push((0,_flow_engine_flow_errors_js__rspack_import_8/* .errorRef */.O$)(error));
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
steps.push(step);
|
|
1273
|
+
}
|
|
1274
|
+
const schemaChanges = entityDiff.operations.length > 0;
|
|
1275
|
+
const importedSlugs = new Set(flowDiff.planned.map((p)=>p.flow.slug));
|
|
1276
|
+
for (const planned of flowDiff.planned){
|
|
1277
|
+
const step = {
|
|
1278
|
+
kind: planned.kind,
|
|
1279
|
+
flowSlug: planned.flow.slug,
|
|
1280
|
+
details: planned.details,
|
|
1281
|
+
preview: null,
|
|
1282
|
+
warnings: [
|
|
1283
|
+
...planned.warnings
|
|
1284
|
+
],
|
|
1285
|
+
blockers: [
|
|
1286
|
+
...planned.blockers
|
|
1287
|
+
]
|
|
1288
|
+
};
|
|
1289
|
+
// A flow with a code step needs that permission from whoever imports it, as from whoever saves it.
|
|
1290
|
+
await this.flows.assertMayAuthor((0,_flow_definition_service_js__rspack_import_13/* .toFlowSettings */.RK)(planned.flow), user).catch((error)=>step.blockers.push((0,_flow_engine_flow_errors_js__rspack_import_8/* .errorRef */.O$)(error)));
|
|
1291
|
+
const dependsOnImport = schemaChanges || (0,_definition_bundle_diff_js__rspack_import_10/* .calledFlowSlugs */.Q5)(planned.flow.nodes).some((slug)=>importedSlugs.has(slug));
|
|
1292
|
+
if (dependsOnImport) {
|
|
1293
|
+
step.warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.FLOWS_CHECKED_ON_APPLY */.iX.FLOWS_CHECKED_ON_APPLY));
|
|
1294
|
+
} else if (!step.blockers.length) {
|
|
1295
|
+
const { errors, warnings } = await this.flows.validate((0,_flow_definition_service_js__rspack_import_13/* .toFlowSettings */.RK)(planned.flow));
|
|
1296
|
+
step.blockers.push(...errors);
|
|
1297
|
+
step.warnings.push(...warnings);
|
|
1298
|
+
}
|
|
1299
|
+
steps.push(step);
|
|
1300
|
+
}
|
|
1301
|
+
const checksum = (0,_definition_bundle_diff_js__rspack_import_10/* .bundleChecksum */.i9)(bundle);
|
|
1302
|
+
const plan = {
|
|
1303
|
+
checksum,
|
|
1304
|
+
planChecksum: planChecksum(checksum, dto.deprecateMissingFields === true, steps),
|
|
1305
|
+
steps,
|
|
1306
|
+
unchanged: {
|
|
1307
|
+
entities: entityDiff.unchangedEntities,
|
|
1308
|
+
fields: entityDiff.unchangedFields,
|
|
1309
|
+
flows: flowDiff.unchanged
|
|
1310
|
+
},
|
|
1311
|
+
extras: [
|
|
1312
|
+
...entityDiff.extras,
|
|
1313
|
+
...flowDiff.extras
|
|
1314
|
+
],
|
|
1315
|
+
blockers: [
|
|
1316
|
+
...entityDiff.blockers,
|
|
1317
|
+
...flowDiff.blockers
|
|
1318
|
+
],
|
|
1319
|
+
destructive: steps.some((s)=>s.preview?.destructive),
|
|
1320
|
+
mayLoseData: steps.some((s)=>s.preview?.destructive || !s.preview && mayLoseData(s))
|
|
1321
|
+
};
|
|
1322
|
+
return {
|
|
1323
|
+
plan,
|
|
1324
|
+
operations: entityDiff.operations,
|
|
1325
|
+
flows: flowDiff.planned
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
/** A relation to an entity this import creates: its id is only known once the entity exists. */ relationNotYetCreated(operation, existingCodes) {
|
|
1329
|
+
const target = operation.field?.relationTarget ?? operation.changes?.['relationTarget'];
|
|
1330
|
+
return !!target && !existingCodes.has(target);
|
|
1331
|
+
}
|
|
1332
|
+
async previewEntityStep(operation, current, user) {
|
|
1333
|
+
if (operation.kind === 'create_entity') return this.schemaSync.planCreateEntity(this.createRequest(operation.entity), user);
|
|
1334
|
+
return this.evolution.plan(this.changeRequest(operation, current), user);
|
|
1335
|
+
}
|
|
1336
|
+
async diffFlows(bundleFlows) {
|
|
1337
|
+
const repo = await this.provider.getRepository(_entities_flow_definition_entity_js__rspack_import_7/* .FlowDefinition */.G);
|
|
1338
|
+
const existing = await repo.find();
|
|
1339
|
+
const bySlug = new Map(existing.map((flow)=>[
|
|
1340
|
+
flow.slug,
|
|
1341
|
+
flow
|
|
1342
|
+
]));
|
|
1343
|
+
const slugs = bundleFlows.map((f)=>f.slug);
|
|
1344
|
+
const deleted = slugs.length ? new Set((await repo.find({
|
|
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();
|
|
1355
|
+
const result = {
|
|
1356
|
+
planned: [],
|
|
1357
|
+
unchanged: 0,
|
|
1358
|
+
extras: [],
|
|
1359
|
+
blockers: []
|
|
1360
|
+
};
|
|
1361
|
+
const seen = new Set();
|
|
1362
|
+
for (const slug of slugs){
|
|
1363
|
+
if (seen.has(slug)) result.blockers.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.DUPLICATE_FLOW */.iX.DUPLICATE_FLOW, {
|
|
1364
|
+
flow: slug
|
|
1365
|
+
}));
|
|
1366
|
+
seen.add(slug);
|
|
1367
|
+
}
|
|
1368
|
+
for (const bundleFlow of (0,_definition_bundle_diff_js__rspack_import_10/* .orderFlows */.qG)(bundleFlows)){
|
|
1369
|
+
const { nodes, missing } = (0,_definition_bundle_diff_js__rspack_import_10/* .applyVariables */.gT)(bundleFlow.nodes ?? [], variables);
|
|
1370
|
+
const flow = {
|
|
1371
|
+
...bundleFlow,
|
|
1372
|
+
nodes,
|
|
1373
|
+
edges: bundleFlow.edges ?? []
|
|
1374
|
+
};
|
|
1375
|
+
const blockers = missing.map((name)=>(0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.VARIABLE_MISSING */.iX.VARIABLE_MISSING, {
|
|
1376
|
+
name,
|
|
1377
|
+
flow: flow.slug
|
|
1378
|
+
}));
|
|
1379
|
+
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
|
+
const keys = storedApiKeys(target);
|
|
1384
|
+
const warnings = flow.nodes.filter((node)=>needsApiKey(node) && !keys.has(node.id)).map((node)=>(0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.FLOW_API_KEY_GENERATED */.iX.FLOW_API_KEY_GENERATED, {
|
|
1385
|
+
flow: flow.slug,
|
|
1386
|
+
path: triggerPath(node) ?? ''
|
|
1387
|
+
}));
|
|
1388
|
+
if (!target) {
|
|
1389
|
+
result.planned.push({
|
|
1390
|
+
kind: 'create_flow',
|
|
1391
|
+
flow,
|
|
1392
|
+
existingId: null,
|
|
1393
|
+
details: {},
|
|
1394
|
+
warnings,
|
|
1395
|
+
blockers
|
|
1396
|
+
});
|
|
1397
|
+
continue;
|
|
1398
|
+
}
|
|
1399
|
+
const live = (0,_flow_definition_service_js__rspack_import_13/* .snapshotOf */.eY)(target);
|
|
1400
|
+
const changed = _interfaces_flow_definition_interface_js__rspack_import_19/* .FLOW_VERSIONED_FIELDS.filter */.v.filter((key)=>key === 'nodes' ? (0,_definition_bundle_diff_js__rspack_import_10/* .canonicalJson */.dj)((0,_definition_bundle_diff_js__rspack_import_10/* .stripApiKeys */.dX)(live.nodes ?? [])) !== (0,_definition_bundle_diff_js__rspack_import_10/* .canonicalJson */.dj)((0,_definition_bundle_diff_js__rspack_import_10/* .stripApiKeys */.dX)(flow.nodes)) : (0,_definition_bundle_diff_js__rspack_import_10/* .canonicalJson */.dj)(live[key] ?? null) !== (0,_definition_bundle_diff_js__rspack_import_10/* .canonicalJson */.dj)(flow[key] ?? null));
|
|
1401
|
+
if (!changed.length && (0,_flow_definition_service_js__rspack_import_13/* .isPublished */.HF)(target) && !blockers.length) {
|
|
1402
|
+
result.unchanged++;
|
|
1403
|
+
continue;
|
|
1404
|
+
}
|
|
1405
|
+
if (target.draft) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.FLOW_DRAFT_REPLACED */.iX.FLOW_DRAFT_REPLACED, {
|
|
1406
|
+
flow: flow.slug
|
|
1407
|
+
}));
|
|
1408
|
+
result.planned.push({
|
|
1409
|
+
kind: 'update_flow',
|
|
1410
|
+
flow,
|
|
1411
|
+
existingId: target.id,
|
|
1412
|
+
details: {
|
|
1413
|
+
changes: changed
|
|
1414
|
+
},
|
|
1415
|
+
warnings,
|
|
1416
|
+
blockers
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
for (const extra of existing.filter((flow)=>!seen.has(flow.slug)))result.extras.push({
|
|
1420
|
+
kind: 'flow',
|
|
1421
|
+
flowSlug: extra.slug
|
|
1422
|
+
});
|
|
1423
|
+
return result;
|
|
1424
|
+
}
|
|
1425
|
+
// ── requests for the designer's services ────────────────────────────────────────────
|
|
1426
|
+
fieldSpec(field, relationTargetEntityId) {
|
|
1427
|
+
return {
|
|
1428
|
+
code: field.code,
|
|
1429
|
+
label: field.label,
|
|
1430
|
+
fieldType: field.fieldType,
|
|
1431
|
+
nullable: field.nullable,
|
|
1432
|
+
unique: field.unique,
|
|
1433
|
+
isIndexed: field.isIndexed,
|
|
1434
|
+
defaultValue: field.defaultValue ?? undefined,
|
|
1435
|
+
validationRules: field.validationRules ?? undefined,
|
|
1436
|
+
selectOptions: field.selectOptions ?? undefined,
|
|
1437
|
+
order: field.order,
|
|
1438
|
+
uiConfig: field.uiConfig ?? undefined,
|
|
1439
|
+
isSearchable: field.isSearchable,
|
|
1440
|
+
...relationTargetEntityId ? {
|
|
1441
|
+
relationTargetEntityId
|
|
1442
|
+
} : {}
|
|
1443
|
+
};
|
|
1444
|
+
}
|
|
1445
|
+
createRequest(entity) {
|
|
1446
|
+
return {
|
|
1447
|
+
code: entity.code,
|
|
1448
|
+
label: entity.label,
|
|
1449
|
+
description: entity.description ?? undefined,
|
|
1450
|
+
isSoftDeleteEnabled: entity.isSoftDeleteEnabled,
|
|
1451
|
+
isAuditEnabled: entity.isAuditEnabled,
|
|
1452
|
+
uiConfig: entity.uiConfig ?? undefined,
|
|
1453
|
+
fields: entity.fields.map((field)=>this.fieldSpec(field))
|
|
1454
|
+
};
|
|
1455
|
+
}
|
|
1456
|
+
/** The schema change for one step, with this environment's ids (looked up now: earlier steps may have created them). */ changeRequest(operation, current) {
|
|
1457
|
+
const entity = current.find((e)=>e.code === operation.entityCode);
|
|
1458
|
+
const idOf = (code)=>code ? current.find((e)=>e.code === code)?.id : undefined;
|
|
1459
|
+
switch(operation.kind){
|
|
1460
|
+
case 'add_field':
|
|
1461
|
+
return {
|
|
1462
|
+
action: _dtos_schema_change_dto_js__rspack_import_4/* .SchemaChangeAction.ADD_FIELD */.M3.ADD_FIELD,
|
|
1463
|
+
entityDefinitionId: entity?.id,
|
|
1464
|
+
field: this.fieldSpec(operation.field, idOf(operation.field.relationTarget))
|
|
1465
|
+
};
|
|
1466
|
+
case 'rename_field':
|
|
1467
|
+
case 'update_field':
|
|
1468
|
+
{
|
|
1469
|
+
const { relationTarget, ...changes } = operation.changes ?? {};
|
|
1470
|
+
if (relationTarget !== undefined) Object.assign(changes, {
|
|
1471
|
+
relationTargetEntityId: idOf(relationTarget) ?? null
|
|
1472
|
+
});
|
|
1473
|
+
return {
|
|
1474
|
+
action: _dtos_schema_change_dto_js__rspack_import_4/* .SchemaChangeAction.UPDATE_FIELD */.M3.UPDATE_FIELD,
|
|
1475
|
+
fieldDefinitionId: operation.targetFieldId,
|
|
1476
|
+
changes
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1479
|
+
case 'deprecate_field':
|
|
1480
|
+
return {
|
|
1481
|
+
action: _dtos_schema_change_dto_js__rspack_import_4/* .SchemaChangeAction.DEPRECATE_FIELD */.M3.DEPRECATE_FIELD,
|
|
1482
|
+
fieldDefinitionId: operation.targetFieldId
|
|
1483
|
+
};
|
|
1484
|
+
case 'restore_field':
|
|
1485
|
+
return {
|
|
1486
|
+
action: _dtos_schema_change_dto_js__rspack_import_4/* .SchemaChangeAction.RESTORE_FIELD */.M3.RESTORE_FIELD,
|
|
1487
|
+
fieldDefinitionId: operation.targetFieldId
|
|
1488
|
+
};
|
|
1489
|
+
default:
|
|
1490
|
+
return {
|
|
1491
|
+
action: _dtos_schema_change_dto_js__rspack_import_4/* .SchemaChangeAction.UPDATE_ENTITY */.M3.UPDATE_ENTITY,
|
|
1492
|
+
entityDefinitionId: entity?.id,
|
|
1493
|
+
changes: operation.changes
|
|
1494
|
+
};
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
// ── apply ───────────────────────────────────────────────────────────────────────────
|
|
1498
|
+
async applyImport(dto, user) {
|
|
1499
|
+
const checksum = (0,_definition_bundle_diff_js__rspack_import_10/* .bundleChecksum */.i9)(dto.bundle);
|
|
1500
|
+
if (dto.expectedChecksum && dto.expectedChecksum !== checksum) {
|
|
1501
|
+
throw new _nestjs_common__rspack_import_1.ConflictException({
|
|
1502
|
+
message: 'The bundle is not the one that was reviewed. Plan the import again.',
|
|
1503
|
+
messageKey: _config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.CHECKSUM_MISMATCH */.iX.CHECKSUM_MISMATCH,
|
|
1504
|
+
messageVariables: {
|
|
1505
|
+
checksum
|
|
1506
|
+
}
|
|
1507
|
+
});
|
|
1508
|
+
}
|
|
1509
|
+
const { plan, operations, flows } = await this.buildPlan(dto, user);
|
|
1510
|
+
if (dto.expectedPlanChecksum && dto.expectedPlanChecksum !== plan.planChecksum) {
|
|
1511
|
+
throw new _nestjs_common__rspack_import_1.ConflictException({
|
|
1512
|
+
message: 'The plan changed since it was reviewed. Plan the import again.',
|
|
1513
|
+
messageKey: _config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.PLAN_CHANGED */.iX.PLAN_CHANGED,
|
|
1514
|
+
messageVariables: {
|
|
1515
|
+
planChecksum: plan.planChecksum
|
|
1516
|
+
}
|
|
1517
|
+
});
|
|
1518
|
+
}
|
|
1519
|
+
// `errors` is what the global exception filter passes on, so the caller sees every reason.
|
|
1520
|
+
const blockers = [
|
|
1521
|
+
...plan.blockers.map((b)=>({
|
|
1522
|
+
field: 'bundle',
|
|
1523
|
+
...b
|
|
1524
|
+
})),
|
|
1525
|
+
...plan.steps.flatMap((s)=>s.blockers.map((b)=>({
|
|
1526
|
+
field: (0,_definition_bundle_diff_js__rspack_import_10/* .bundleSubject */.bs)(s),
|
|
1527
|
+
...b
|
|
1528
|
+
})))
|
|
1529
|
+
];
|
|
1530
|
+
if (blockers.length) {
|
|
1531
|
+
throw new _nestjs_common__rspack_import_1.ConflictException({
|
|
1532
|
+
message: 'The import is blocked. Plan it again to see why.',
|
|
1533
|
+
messageKey: _config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.APPLY_BLOCKED */.iX.APPLY_BLOCKED,
|
|
1534
|
+
errors: blockers
|
|
1535
|
+
});
|
|
1536
|
+
}
|
|
1537
|
+
if (plan.mayLoseData && dto.confirm !== true) {
|
|
1538
|
+
const lossy = plan.steps.filter((s)=>s.preview?.destructive || !s.preview && mayLoseData(s)).map((s)=>({
|
|
1539
|
+
field: (0,_definition_bundle_diff_js__rspack_import_10/* .bundleSubject */.bs)(s),
|
|
1540
|
+
messageKey: _config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.CONFIRM_REQUIRED */.iX.CONFIRM_REQUIRED
|
|
1541
|
+
}));
|
|
1542
|
+
throw new _nestjs_common__rspack_import_1.BadRequestException({
|
|
1543
|
+
message: 'The import loses data or information. Review the plan and resend with confirm: true.',
|
|
1544
|
+
messageKey: _config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.CONFIRM_REQUIRED */.iX.CONFIRM_REQUIRED,
|
|
1545
|
+
errors: lossy
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1548
|
+
// A confirmation covers the steps that were reviewed, never ones the environment has grown since.
|
|
1549
|
+
if (plan.mayLoseData && !dto.expectedPlanChecksum) {
|
|
1550
|
+
throw new _nestjs_common__rspack_import_1.BadRequestException({
|
|
1551
|
+
message: 'Send the planChecksum of the reviewed plan as expectedPlanChecksum to confirm it.',
|
|
1552
|
+
messageKey: _config_message_keys_js__rspack_import_17/* .BUNDLE_MESSAGES.PLAN_CHECKSUM_REQUIRED */.iX.PLAN_CHECKSUM_REQUIRED
|
|
1553
|
+
});
|
|
1554
|
+
}
|
|
1555
|
+
const result = {
|
|
1556
|
+
checksum: plan.checksum,
|
|
1557
|
+
completed: true,
|
|
1558
|
+
steps: [],
|
|
1559
|
+
apiKeys: [],
|
|
1560
|
+
warnings: plan.steps.flatMap((s)=>s.warnings)
|
|
1561
|
+
};
|
|
1562
|
+
const note = `Imported from bundle ${plan.checksum.slice(0, 12)}`;
|
|
1563
|
+
const run = async (step, fn)=>{
|
|
1564
|
+
if (!result.completed) return result.steps.push({
|
|
1565
|
+
...step,
|
|
1566
|
+
status: 'skipped'
|
|
1567
|
+
});
|
|
1568
|
+
try {
|
|
1569
|
+
await fn();
|
|
1570
|
+
result.steps.push({
|
|
1571
|
+
...step,
|
|
1572
|
+
status: 'applied'
|
|
1573
|
+
});
|
|
1574
|
+
} catch (error) {
|
|
1575
|
+
result.completed = false;
|
|
1576
|
+
const reasons = failureDetails(error);
|
|
1577
|
+
result.steps.push({
|
|
1578
|
+
...step,
|
|
1579
|
+
status: 'failed',
|
|
1580
|
+
error: (0,_flow_engine_flow_errors_js__rspack_import_8/* .errorRef */.O$)(error),
|
|
1581
|
+
...reasons.length ? {
|
|
1582
|
+
blockers: reasons
|
|
1583
|
+
} : {}
|
|
1584
|
+
});
|
|
1585
|
+
}
|
|
1586
|
+
};
|
|
1587
|
+
// Entity codes and field ids never change during an import: only a created entity adds ids to look up.
|
|
1588
|
+
let current = await this.loadEntities();
|
|
1589
|
+
for (const operation of operations){
|
|
1590
|
+
await run({
|
|
1591
|
+
kind: operation.kind,
|
|
1592
|
+
entityCode: operation.entityCode,
|
|
1593
|
+
...operation.fieldCode ? {
|
|
1594
|
+
fieldCode: operation.fieldCode
|
|
1595
|
+
} : {}
|
|
1596
|
+
}, ()=>this.applyEntityStep(operation, current, dto.confirm === true, user));
|
|
1597
|
+
if (operation.kind === 'create_entity' && result.completed) current = await this.loadEntities();
|
|
1598
|
+
}
|
|
1599
|
+
for (const planned of flows){
|
|
1600
|
+
await run({
|
|
1601
|
+
kind: planned.kind,
|
|
1602
|
+
flowSlug: planned.flow.slug
|
|
1603
|
+
}, ()=>this.applyFlowStep(planned, note, result.apiKeys, user));
|
|
1604
|
+
}
|
|
1605
|
+
return result;
|
|
1606
|
+
}
|
|
1607
|
+
async applyEntityStep(operation, current, confirm, user) {
|
|
1608
|
+
if (operation.kind === 'create_entity') {
|
|
1609
|
+
const entity = operation.entity;
|
|
1610
|
+
await this.schemaSync.createEntity(this.createRequest(entity), user, {
|
|
1611
|
+
entityId: await this.idIsFree(_entities_entity_definition_entity_js__rspack_import_5/* .EntityDefinition */.f, entity.id) ? entity.id : undefined,
|
|
1612
|
+
fieldIds: Object.fromEntries(await this.freeFieldIds(entity.fields))
|
|
1613
|
+
});
|
|
1614
|
+
return;
|
|
1615
|
+
}
|
|
1616
|
+
const request = {
|
|
1617
|
+
...this.changeRequest(operation, current),
|
|
1618
|
+
confirm
|
|
1619
|
+
};
|
|
1620
|
+
const fieldId = operation.kind === 'add_field' && await this.idIsFree(_entities_field_definition_entity_js__rspack_import_6/* .FieldDefinition */.c, operation.field.id) ? operation.field.id : undefined;
|
|
1621
|
+
await this.evolution.apply(request, user, {
|
|
1622
|
+
fieldId
|
|
1623
|
+
});
|
|
1624
|
+
}
|
|
1625
|
+
async idIsFree(entity, id) {
|
|
1626
|
+
return !await (await this.provider.getRepository(entity)).exists({
|
|
1627
|
+
where: {
|
|
1628
|
+
id
|
|
1629
|
+
},
|
|
1630
|
+
withDeleted: true
|
|
1631
|
+
});
|
|
1632
|
+
}
|
|
1633
|
+
async freeFieldIds(fields) {
|
|
1634
|
+
if (!fields.length) return [];
|
|
1635
|
+
const taken = new Set((await (await this.provider.getRepository(_entities_field_definition_entity_js__rspack_import_6/* .FieldDefinition */.c)).find({
|
|
1636
|
+
select: {
|
|
1637
|
+
id: true
|
|
1638
|
+
},
|
|
1639
|
+
where: {
|
|
1640
|
+
id: (0,typeorm__rspack_import_3.In)(fields.map((f)=>f.id))
|
|
1641
|
+
},
|
|
1642
|
+
withDeleted: true
|
|
1643
|
+
})).map((f)=>f.id));
|
|
1644
|
+
return fields.filter((f)=>!taken.has(f.id)).map((f)=>[
|
|
1645
|
+
f.code,
|
|
1646
|
+
f.id
|
|
1647
|
+
]);
|
|
1648
|
+
}
|
|
1649
|
+
/** 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) {
|
|
1650
|
+
const existing = planned.existingId ? await this.flows.findOrFail(planned.existingId) : undefined;
|
|
1651
|
+
const keys = storedApiKeys(existing);
|
|
1652
|
+
const generated = [];
|
|
1653
|
+
const nodes = planned.flow.nodes.map((node)=>{
|
|
1654
|
+
if (!needsApiKey(node)) return node;
|
|
1655
|
+
const stored = keys.get(node.id);
|
|
1656
|
+
if (stored) return {
|
|
1657
|
+
...node,
|
|
1658
|
+
config: {
|
|
1659
|
+
...node.config,
|
|
1660
|
+
apiKey: stored
|
|
1661
|
+
}
|
|
1662
|
+
};
|
|
1663
|
+
const key = newApiKey();
|
|
1664
|
+
generated.push({
|
|
1665
|
+
flowSlug: planned.flow.slug,
|
|
1666
|
+
nodeId: node.id,
|
|
1667
|
+
path: triggerPath(node),
|
|
1668
|
+
key
|
|
1669
|
+
});
|
|
1670
|
+
return {
|
|
1671
|
+
...node,
|
|
1672
|
+
config: {
|
|
1673
|
+
...node.config,
|
|
1674
|
+
apiKey: key
|
|
1675
|
+
}
|
|
1676
|
+
};
|
|
1677
|
+
});
|
|
1678
|
+
const values = {
|
|
1679
|
+
...planned.flow,
|
|
1680
|
+
description: planned.flow.description ?? undefined,
|
|
1681
|
+
nodes
|
|
1682
|
+
};
|
|
1683
|
+
const id = existing ? (await this.flows.update({
|
|
1684
|
+
...values,
|
|
1685
|
+
id: existing.id
|
|
1686
|
+
}, user), existing.id) : (await this.flows.insert(values, user)).id;
|
|
1687
|
+
// Saved: these keys are stored now, so they are answered even if publishing fails (the next import reuses them).
|
|
1688
|
+
apiKeys.push(...generated);
|
|
1689
|
+
await this.flows.publish(id, note, user);
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
DefinitionBundleService = _ts_decorate([
|
|
1693
|
+
(0,_nestjs_common__rspack_import_1.Injectable)({
|
|
1694
|
+
scope: _nestjs_common__rspack_import_1.Scope.REQUEST
|
|
1695
|
+
}),
|
|
1696
|
+
_ts_param(0, (0,_nestjs_common__rspack_import_1.Inject)(_entity_builder_datasource_provider_js__rspack_import_12/* .EntityBuilderDataSourceProvider */.D)),
|
|
1697
|
+
_ts_param(1, (0,_nestjs_common__rspack_import_1.Inject)(_entity_builder_config_service_js__rspack_import_11/* .EntityBuilderConfigService */.E)),
|
|
1698
|
+
_ts_param(2, (0,_nestjs_common__rspack_import_1.Inject)(_schema_sync_service_js__rspack_import_15/* .SchemaSyncService */.W)),
|
|
1699
|
+
_ts_param(3, (0,_nestjs_common__rspack_import_1.Inject)(_schema_evolution_service_js__rspack_import_14/* .SchemaEvolutionService */._)),
|
|
1700
|
+
_ts_param(4, (0,_nestjs_common__rspack_import_1.Inject)(_flow_definition_service_js__rspack_import_13/* .FlowDefinitionService */.Tk)),
|
|
1701
|
+
_ts_metadata("design:type", Function),
|
|
1702
|
+
_ts_metadata("design:paramtypes", [
|
|
1703
|
+
typeof _entity_builder_datasource_provider_js__rspack_import_12/* .EntityBuilderDataSourceProvider */.D === "undefined" ? Object : _entity_builder_datasource_provider_js__rspack_import_12/* .EntityBuilderDataSourceProvider */.D,
|
|
1704
|
+
typeof _entity_builder_config_service_js__rspack_import_11/* .EntityBuilderConfigService */.E === "undefined" ? Object : _entity_builder_config_service_js__rspack_import_11/* .EntityBuilderConfigService */.E,
|
|
1705
|
+
typeof _schema_sync_service_js__rspack_import_15/* .SchemaSyncService */.W === "undefined" ? Object : _schema_sync_service_js__rspack_import_15/* .SchemaSyncService */.W,
|
|
1706
|
+
typeof _schema_evolution_service_js__rspack_import_14/* .SchemaEvolutionService */._ === "undefined" ? Object : _schema_evolution_service_js__rspack_import_14/* .SchemaEvolutionService */._,
|
|
1707
|
+
typeof _flow_definition_service_js__rspack_import_13/* .FlowDefinitionService */.Tk === "undefined" ? Object : _flow_definition_service_js__rspack_import_13/* .FlowDefinitionService */.Tk
|
|
1708
|
+
])
|
|
1709
|
+
], DefinitionBundleService);
|
|
1710
|
+
|
|
1711
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
1712
|
+
P: () => (DefinitionBundleService)
|
|
10
1713
|
});
|
|
11
1714
|
|
|
12
1715
|
|
|
@@ -147,9 +1850,13 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
147
1850
|
|
|
148
1851
|
},
|
|
149
1852
|
8271(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
150
|
-
/* import */ var
|
|
151
|
-
/* import */ var
|
|
152
|
-
/* import */ var
|
|
1853
|
+
/* import */ var _flusys_nestjs_shared_constants__rspack_import_0 = __webpack_require__(9140);
|
|
1854
|
+
/* import */ var _config_message_keys_js__rspack_import_4 = __webpack_require__(5732);
|
|
1855
|
+
/* import */ var _enums_field_type_enum_js__rspack_import_2 = __webpack_require__(9614);
|
|
1856
|
+
/* import */ var _flow_engine_flow_permission_logic_js__rspack_import_3 = __webpack_require__(8220);
|
|
1857
|
+
/* import */ var _flow_engine_flow_types_js__rspack_import_1 = __webpack_require__(6256);
|
|
1858
|
+
|
|
1859
|
+
|
|
153
1860
|
|
|
154
1861
|
|
|
155
1862
|
|
|
@@ -186,19 +1893,19 @@ const DEFAULT_NO_MATCH_MESSAGE = 'No record matches the filter.';
|
|
|
186
1893
|
const MAX_NAME_LENGTH = 255;
|
|
187
1894
|
/** A supplied text when it has content, the English default otherwise. */ const textOr = (value, fallback)=>value?.trim() || fallback;
|
|
188
1895
|
const INPUT_TYPE = {
|
|
189
|
-
[
|
|
190
|
-
[
|
|
191
|
-
[
|
|
192
|
-
[
|
|
193
|
-
[
|
|
194
|
-
[
|
|
195
|
-
[
|
|
196
|
-
[
|
|
197
|
-
[
|
|
198
|
-
[
|
|
199
|
-
[
|
|
200
|
-
[
|
|
201
|
-
[
|
|
1896
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.TEXT */.P.TEXT]: 'string',
|
|
1897
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.LONG_TEXT */.P.LONG_TEXT]: 'text',
|
|
1898
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.INTEGER */.P.INTEGER]: 'integer',
|
|
1899
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.DECIMAL */.P.DECIMAL]: 'number',
|
|
1900
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.BOOLEAN */.P.BOOLEAN]: 'boolean',
|
|
1901
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.DATE */.P.DATE]: 'date',
|
|
1902
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.DATETIME */.P.DATETIME]: 'datetime',
|
|
1903
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.EMAIL */.P.EMAIL]: 'email',
|
|
1904
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.SINGLE_SELECT */.P.SINGLE_SELECT]: 'choice',
|
|
1905
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.MULTI_SELECT */.P.MULTI_SELECT]: 'array',
|
|
1906
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.RELATION */.P.RELATION]: 'uuid',
|
|
1907
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.JSON */.P.JSON]: 'object',
|
|
1908
|
+
[_enums_field_type_enum_js__rspack_import_2/* .FieldType.FILE */.P.FILE]: 'uuid'
|
|
202
1909
|
};
|
|
203
1910
|
const LIST_LIMIT = 50;
|
|
204
1911
|
const READ_ENDPOINTS = new Set([
|
|
@@ -207,7 +1914,47 @@ const READ_ENDPOINTS = new Set([
|
|
|
207
1914
|
'getAll',
|
|
208
1915
|
'getByFilter'
|
|
209
1916
|
]);
|
|
210
|
-
/**
|
|
1917
|
+
/** The entity permissions each endpoint asks for - the ones created with the entity; an upsert may create and update. */ const ENDPOINT_ACTIONS = {
|
|
1918
|
+
insert: [
|
|
1919
|
+
'create'
|
|
1920
|
+
],
|
|
1921
|
+
insertMany: [
|
|
1922
|
+
'create'
|
|
1923
|
+
],
|
|
1924
|
+
getById: [
|
|
1925
|
+
'read'
|
|
1926
|
+
],
|
|
1927
|
+
getByIds: [
|
|
1928
|
+
'read'
|
|
1929
|
+
],
|
|
1930
|
+
getAll: [
|
|
1931
|
+
'read'
|
|
1932
|
+
],
|
|
1933
|
+
getByFilter: [
|
|
1934
|
+
'read'
|
|
1935
|
+
],
|
|
1936
|
+
update: [
|
|
1937
|
+
'update'
|
|
1938
|
+
],
|
|
1939
|
+
updateMany: [
|
|
1940
|
+
'update'
|
|
1941
|
+
],
|
|
1942
|
+
bulkUpsert: [
|
|
1943
|
+
'create',
|
|
1944
|
+
'update'
|
|
1945
|
+
],
|
|
1946
|
+
delete: [
|
|
1947
|
+
'delete'
|
|
1948
|
+
]
|
|
1949
|
+
};
|
|
1950
|
+
function endpointPermissions(entityCode, endpoint) {
|
|
1951
|
+
const actions = ENDPOINT_ACTIONS[endpoint].map((action)=>(0,_flow_engine_flow_permission_logic_js__rspack_import_3/* .permissionAction */.s)((0,_flusys_nestjs_shared_constants__rspack_import_0.dynamicEntityPermission)(entityCode, action)));
|
|
1952
|
+
return actions.length === 1 ? actions[0] : {
|
|
1953
|
+
type: 'group',
|
|
1954
|
+
operator: 'AND',
|
|
1955
|
+
children: actions
|
|
1956
|
+
};
|
|
1957
|
+
}
|
|
211
1958
|
const COLUMN = {
|
|
212
1959
|
x: 40,
|
|
213
1960
|
gap: 300
|
|
@@ -228,16 +1975,56 @@ const lit = (value)=>({
|
|
|
228
1975
|
function optionValues(options) {
|
|
229
1976
|
return (options ?? []).map((o)=>o && typeof o === 'object' && 'value' in o ? String(o.value) : String(o));
|
|
230
1977
|
}
|
|
231
|
-
|
|
1978
|
+
const NUMERIC_TYPES = new Set([
|
|
1979
|
+
_enums_field_type_enum_js__rspack_import_2/* .FieldType.INTEGER */.P.INTEGER,
|
|
1980
|
+
_enums_field_type_enum_js__rspack_import_2/* .FieldType.DECIMAL */.P.DECIMAL
|
|
1981
|
+
]);
|
|
1982
|
+
const TEXT_TYPES = new Set([
|
|
1983
|
+
_enums_field_type_enum_js__rspack_import_2/* .FieldType.TEXT */.P.TEXT,
|
|
1984
|
+
_enums_field_type_enum_js__rspack_import_2/* .FieldType.LONG_TEXT */.P.LONG_TEXT,
|
|
1985
|
+
_enums_field_type_enum_js__rspack_import_2/* .FieldType.EMAIL */.P.EMAIL
|
|
1986
|
+
]);
|
|
1987
|
+
/** The field's rules a Request body checks the same way the record write does. */ function inputRules(field) {
|
|
1988
|
+
const rules = field.validationRules ?? {};
|
|
1989
|
+
const keys = NUMERIC_TYPES.has(field.fieldType) ? [
|
|
1990
|
+
'min',
|
|
1991
|
+
'max'
|
|
1992
|
+
] : TEXT_TYPES.has(field.fieldType) ? [
|
|
1993
|
+
'minLength',
|
|
1994
|
+
'maxLength'
|
|
1995
|
+
] : [];
|
|
1996
|
+
return Object.fromEntries(keys.filter((key)=>typeof rules[key] === 'number' && Number.isFinite(rules[key])).map((key)=>[
|
|
1997
|
+
key,
|
|
1998
|
+
rules[key]
|
|
1999
|
+
]));
|
|
2000
|
+
}
|
|
2001
|
+
/**
|
|
2002
|
+
* The Request body input of a field: a choice carries its options, a multi-select is a list of
|
|
2003
|
+
* those choices, a relation or file is an id. `rules`: a write also checks the field's own value rules.
|
|
2004
|
+
*/ function fieldInput(field, required, rules = true) {
|
|
232
2005
|
const options = optionValues(field.selectOptions);
|
|
233
|
-
const
|
|
234
|
-
return {
|
|
2006
|
+
const base = {
|
|
235
2007
|
name: field.code,
|
|
236
2008
|
label: field.label || field.code,
|
|
237
|
-
type,
|
|
238
2009
|
...required ? {
|
|
239
2010
|
required: true
|
|
240
2011
|
} : {},
|
|
2012
|
+
...rules ? inputRules(field) : {}
|
|
2013
|
+
};
|
|
2014
|
+
if (field.fieldType === _enums_field_type_enum_js__rspack_import_2/* .FieldType.MULTI_SELECT */.P.MULTI_SELECT) return {
|
|
2015
|
+
...base,
|
|
2016
|
+
type: 'array',
|
|
2017
|
+
...options.length ? {
|
|
2018
|
+
itemType: 'choice',
|
|
2019
|
+
options
|
|
2020
|
+
} : {
|
|
2021
|
+
itemType: 'string'
|
|
2022
|
+
}
|
|
2023
|
+
};
|
|
2024
|
+
const type = INPUT_TYPE[field.fieldType] === 'choice' && !options.length ? 'string' : INPUT_TYPE[field.fieldType];
|
|
2025
|
+
return {
|
|
2026
|
+
...base,
|
|
2027
|
+
type,
|
|
241
2028
|
...type === 'choice' ? {
|
|
242
2029
|
options
|
|
243
2030
|
} : {}
|
|
@@ -249,7 +2036,8 @@ const fieldMap = (fields, scope)=>Object.fromEntries(fields.map((f)=>[
|
|
|
249
2036
|
ref(`${scope}.${f.code}`)
|
|
250
2037
|
]));
|
|
251
2038
|
const optionalFieldInputs = (fields)=>fields.map((f)=>fieldInput(f, false));
|
|
252
|
-
/**
|
|
2039
|
+
/** Inputs of a read filter: only the value's type is checked, never the write rules. */ const filterInputs = (fields)=>fields.map((f)=>fieldInput(f, false, false));
|
|
2040
|
+
/** Fields an equality filter can match - a list or JSON value cannot be compared as one value. */ const filterableFields = (entity)=>entity.fields.filter((f)=>f.fieldType !== _enums_field_type_enum_js__rspack_import_2/* .FieldType.MULTI_SELECT */.P.MULTI_SELECT && f.fieldType !== _enums_field_type_enum_js__rspack_import_2/* .FieldType.JSON */.P.JSON);
|
|
253
2041
|
const idInput = (t)=>({
|
|
254
2042
|
name: 'id',
|
|
255
2043
|
label: t.inputLabels.id,
|
|
@@ -278,8 +2066,9 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
278
2066
|
});
|
|
279
2067
|
/**
|
|
280
2068
|
* The steps of one endpoint. Its step ids are `<endpoint>_<step>` (`id()`), so the endpoints of one
|
|
281
|
-
* flow never share a step. A bulk body is the list itself (`itemSchema` checks each item)
|
|
282
|
-
*
|
|
2069
|
+
* flow never share a step. A bulk body is the list itself (`itemSchema` checks each item), written by
|
|
2070
|
+
* one step that walks it (`target: many`, each item read as `loop.item`), all or nothing, and
|
|
2071
|
+
* answered with the saved records in order.
|
|
283
2072
|
*/ function endpointGraph(entity, endpoint, texts) {
|
|
284
2073
|
const id = (step)=>`${endpoint}_${step}`;
|
|
285
2074
|
const entityCode = entity.code;
|
|
@@ -301,33 +2090,26 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
301
2090
|
]
|
|
302
2091
|
]
|
|
303
2092
|
});
|
|
304
|
-
const bulk = (itemSchema,
|
|
2093
|
+
const bulk = (itemSchema, step, statusCode)=>({
|
|
305
2094
|
bodyType: 'list',
|
|
306
2095
|
inputSchema: itemSchema,
|
|
307
2096
|
steps: [
|
|
308
2097
|
{
|
|
309
|
-
|
|
310
|
-
|
|
2098
|
+
...step,
|
|
2099
|
+
id: id('records'),
|
|
311
2100
|
column: 1,
|
|
312
2101
|
config: {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
2102
|
+
...step.config,
|
|
2103
|
+
target: 'many',
|
|
2104
|
+
items: ref('input')
|
|
316
2105
|
}
|
|
317
2106
|
},
|
|
318
|
-
|
|
319
|
-
respond(id('respond'), 2, statusCode, ref(`context.${id('each')}.results`))
|
|
2107
|
+
respond(id('respond'), 2, statusCode, ref(`context.${id('records')}.items`))
|
|
320
2108
|
],
|
|
321
2109
|
edges: [
|
|
322
2110
|
[
|
|
323
|
-
id('
|
|
324
|
-
'
|
|
325
|
-
body[0].id
|
|
326
|
-
],
|
|
327
|
-
...bodyEdges,
|
|
328
|
-
[
|
|
329
|
-
id('each'),
|
|
330
|
-
'done',
|
|
2111
|
+
id('records'),
|
|
2112
|
+
'out',
|
|
331
2113
|
id('respond')
|
|
332
2114
|
]
|
|
333
2115
|
]
|
|
@@ -344,18 +2126,13 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
344
2126
|
}
|
|
345
2127
|
}, 201);
|
|
346
2128
|
case 'insertMany':
|
|
347
|
-
return bulk(insertInputs,
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
row: 1,
|
|
353
|
-
config: {
|
|
354
|
-
entityCode,
|
|
355
|
-
fields: fieldMap(entity.fields, 'loop.item')
|
|
356
|
-
}
|
|
2129
|
+
return bulk(insertInputs, {
|
|
2130
|
+
type: 'entity_insert',
|
|
2131
|
+
config: {
|
|
2132
|
+
entityCode,
|
|
2133
|
+
fields: fieldMap(entity.fields, 'loop.item')
|
|
357
2134
|
}
|
|
358
|
-
|
|
2135
|
+
}, 201);
|
|
359
2136
|
case 'getById':
|
|
360
2137
|
return single([
|
|
361
2138
|
idInput(texts)
|
|
@@ -379,7 +2156,7 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
379
2156
|
value: ref('input.ids')
|
|
380
2157
|
}
|
|
381
2158
|
},
|
|
382
|
-
limit:
|
|
2159
|
+
limit: _flow_engine_flow_types_js__rspack_import_1/* .FLOW_LIMITS.MAX_QUERY_LIMIT */.Or.MAX_QUERY_LIMIT
|
|
383
2160
|
}
|
|
384
2161
|
});
|
|
385
2162
|
case 'getAll':
|
|
@@ -389,7 +2166,7 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
389
2166
|
label: texts.inputLabels.search,
|
|
390
2167
|
type: 'string'
|
|
391
2168
|
},
|
|
392
|
-
...
|
|
2169
|
+
...filterInputs(filterFields)
|
|
393
2170
|
], {
|
|
394
2171
|
type: 'entity_query',
|
|
395
2172
|
config: {
|
|
@@ -406,7 +2183,7 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
406
2183
|
...idInput(texts),
|
|
407
2184
|
required: false
|
|
408
2185
|
},
|
|
409
|
-
...
|
|
2186
|
+
...filterInputs(filterFields)
|
|
410
2187
|
],
|
|
411
2188
|
steps: [
|
|
412
2189
|
{
|
|
@@ -442,7 +2219,7 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
442
2219
|
respond(id('not_found'), 3, 404, {
|
|
443
2220
|
success: lit(false),
|
|
444
2221
|
message: lit(texts.noMatchMessage),
|
|
445
|
-
messageKey: lit(
|
|
2222
|
+
messageKey: lit(_config_message_keys_js__rspack_import_4/* .GENERIC_RECORD_MESSAGES.NO_MATCH */.j4.NO_MATCH)
|
|
446
2223
|
}, 1)
|
|
447
2224
|
],
|
|
448
2225
|
edges: [
|
|
@@ -479,19 +2256,13 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
479
2256
|
return bulk([
|
|
480
2257
|
idInput(texts),
|
|
481
2258
|
...optionalFieldInputs(entity.fields)
|
|
482
|
-
],
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
row: 1,
|
|
488
|
-
config: {
|
|
489
|
-
entityCode,
|
|
490
|
-
id: ref('loop.item.id'),
|
|
491
|
-
fields: fieldMap(entity.fields, 'loop.item')
|
|
492
|
-
}
|
|
2259
|
+
], {
|
|
2260
|
+
type: 'entity_update',
|
|
2261
|
+
config: {
|
|
2262
|
+
entityCode,
|
|
2263
|
+
fields: fieldMap(entity.fields, 'loop.item')
|
|
493
2264
|
}
|
|
494
|
-
|
|
2265
|
+
}, 200);
|
|
495
2266
|
case 'bulkUpsert':
|
|
496
2267
|
return bulk([
|
|
497
2268
|
{
|
|
@@ -499,89 +2270,14 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
499
2270
|
required: false
|
|
500
2271
|
},
|
|
501
2272
|
...optionalFieldInputs(entity.fields)
|
|
502
|
-
],
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
config: {
|
|
509
|
-
rule: {
|
|
510
|
-
operator: 'AND',
|
|
511
|
-
conditions: [
|
|
512
|
-
{
|
|
513
|
-
field: 'loop.item.id',
|
|
514
|
-
comparison: 'is_not_empty'
|
|
515
|
-
}
|
|
516
|
-
]
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
},
|
|
520
|
-
{
|
|
521
|
-
id: id('updated'),
|
|
522
|
-
type: 'entity_update',
|
|
523
|
-
column: 2,
|
|
524
|
-
row: 1,
|
|
525
|
-
config: {
|
|
526
|
-
entityCode,
|
|
527
|
-
id: ref('loop.item.id'),
|
|
528
|
-
fields: fieldMap(entity.fields, 'loop.item')
|
|
529
|
-
}
|
|
530
|
-
},
|
|
531
|
-
{
|
|
532
|
-
id: id('inserted'),
|
|
533
|
-
type: 'entity_insert',
|
|
534
|
-
column: 2,
|
|
535
|
-
row: 2,
|
|
536
|
-
config: {
|
|
537
|
-
entityCode,
|
|
538
|
-
fields: fieldMap(entity.fields, 'loop.item')
|
|
539
|
-
}
|
|
540
|
-
},
|
|
541
|
-
{
|
|
542
|
-
id: id('keep_updated'),
|
|
543
|
-
type: 'set',
|
|
544
|
-
column: 3,
|
|
545
|
-
row: 1,
|
|
546
|
-
config: {
|
|
547
|
-
values: {
|
|
548
|
-
saved: ref(`context.${id('updated')}`)
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
},
|
|
552
|
-
{
|
|
553
|
-
id: id('keep_inserted'),
|
|
554
|
-
type: 'set',
|
|
555
|
-
column: 3,
|
|
556
|
-
row: 2,
|
|
557
|
-
config: {
|
|
558
|
-
values: {
|
|
559
|
-
saved: ref(`context.${id('inserted')}`)
|
|
560
|
-
}
|
|
561
|
-
}
|
|
2273
|
+
], {
|
|
2274
|
+
type: 'entity_update',
|
|
2275
|
+
config: {
|
|
2276
|
+
entityCode,
|
|
2277
|
+
fields: fieldMap(entity.fields, 'loop.item'),
|
|
2278
|
+
onNotFound: 'insert'
|
|
562
2279
|
}
|
|
563
|
-
|
|
564
|
-
[
|
|
565
|
-
id('has_id'),
|
|
566
|
-
'true',
|
|
567
|
-
id('updated')
|
|
568
|
-
],
|
|
569
|
-
[
|
|
570
|
-
id('has_id'),
|
|
571
|
-
'false',
|
|
572
|
-
id('inserted')
|
|
573
|
-
],
|
|
574
|
-
[
|
|
575
|
-
id('updated'),
|
|
576
|
-
'out',
|
|
577
|
-
id('keep_updated')
|
|
578
|
-
],
|
|
579
|
-
[
|
|
580
|
-
id('inserted'),
|
|
581
|
-
'out',
|
|
582
|
-
id('keep_inserted')
|
|
583
|
-
]
|
|
584
|
-
], ref('vars.saved'), 200);
|
|
2280
|
+
}, 200);
|
|
585
2281
|
case 'delete':
|
|
586
2282
|
return single([
|
|
587
2283
|
idInput(texts)
|
|
@@ -597,10 +2293,12 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
597
2293
|
/**
|
|
598
2294
|
* The ready-made flow of an entity: `api-flows/<entity>` with one Request step per endpoint of the
|
|
599
2295
|
* generic API controller, each on its own path (`ENTITY_FLOW_PATHS`) with its own body, laid out
|
|
600
|
-
* one below the other.
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
2296
|
+
* one below the other. Each asks its caller for the entity's own permission (`entity_builder.entity.<code>.<action>`,
|
|
2297
|
+
* created with the entity), since a flow's access is its only gate, and it is an ordinary flow
|
|
2298
|
+
* afterwards - the user can change or delete it like any other. A
|
|
2299
|
+
* write endpoint is transactional: a bulk endpoint writes its whole list in one step, so a failing
|
|
2300
|
+
* item rolls back the whole request; a read endpoint opens none. A bulk body holds at most
|
|
2301
|
+
* FLOW_LIMITS.MAX_WRITE_ITEMS items.
|
|
604
2302
|
*/ function buildEntityFlow(entity, endpoints, texts = {}) {
|
|
605
2303
|
const resolved = {
|
|
606
2304
|
inputLabels: {
|
|
@@ -622,7 +2320,12 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
622
2320
|
const config = {
|
|
623
2321
|
path: ENTITY_FLOW_PATHS[endpoint],
|
|
624
2322
|
bodyType: graph.bodyType ?? 'object',
|
|
625
|
-
inputSchema: graph.inputSchema
|
|
2323
|
+
inputSchema: graph.inputSchema,
|
|
2324
|
+
authMode: 'permission',
|
|
2325
|
+
permissions: endpointPermissions(entity.code, endpoint),
|
|
2326
|
+
...READ_ENDPOINTS.has(endpoint) ? {} : {
|
|
2327
|
+
isTransactional: true
|
|
2328
|
+
}
|
|
626
2329
|
};
|
|
627
2330
|
nodes.push({
|
|
628
2331
|
id: endpoint,
|
|
@@ -654,11 +2357,6 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
654
2357
|
name: entity.label.slice(0, MAX_NAME_LENGTH),
|
|
655
2358
|
slug: entityFlowSlug(entity.code),
|
|
656
2359
|
isActive: true,
|
|
657
|
-
authMode: 'jwt',
|
|
658
|
-
runAs: 'caller',
|
|
659
|
-
isTransactional: endpoints.some((endpoint)=>!READ_ENDPOINTS.has(endpoint)),
|
|
660
|
-
bodyType: 'object',
|
|
661
|
-
inputSchema: [],
|
|
662
2360
|
nodes,
|
|
663
2361
|
edges
|
|
664
2362
|
};
|
|
@@ -1862,8 +3560,8 @@ class SchemaEvolutionService {
|
|
|
1862
3560
|
const prepared = await this.prepare(request, user);
|
|
1863
3561
|
return this.executor.simulate(prepared.target, prepared.run, prepared.impact);
|
|
1864
3562
|
}
|
|
1865
|
-
async apply(request, user) {
|
|
1866
|
-
const prepared = await this.prepare(request, user);
|
|
3563
|
+
/** `options.fieldId`: the id add_field gives the new field (an import keeps the id it has where it was designed). */ async apply(request, user, options = {}) {
|
|
3564
|
+
const prepared = await this.prepare(request, user, options.fieldId);
|
|
1867
3565
|
const { plan, outcome } = await this.executor.apply(prepared.target, prepared.run, {
|
|
1868
3566
|
confirm: request.confirm === true,
|
|
1869
3567
|
impact: prepared.impact
|
|
@@ -2041,10 +3739,10 @@ class SchemaEvolutionService {
|
|
|
2041
3739
|
return true;
|
|
2042
3740
|
}
|
|
2043
3741
|
// ── dispatch ────────────────────────────────────────────────────────────────────────
|
|
2044
|
-
async prepare(request, user) {
|
|
3742
|
+
async prepare(request, user, fieldId) {
|
|
2045
3743
|
switch(request.action){
|
|
2046
3744
|
case _dtos_schema_change_dto_js__rspack_import_6/* .SchemaChangeAction.ADD_FIELD */.M3.ADD_FIELD:
|
|
2047
|
-
return this.prepareAddField(request, user);
|
|
3745
|
+
return this.prepareAddField(request, user, fieldId);
|
|
2048
3746
|
case _dtos_schema_change_dto_js__rspack_import_6/* .SchemaChangeAction.UPDATE_FIELD */.M3.UPDATE_FIELD:
|
|
2049
3747
|
return this.prepareUpdateField(request, user);
|
|
2050
3748
|
case _dtos_schema_change_dto_js__rspack_import_6/* .SchemaChangeAction.DEPRECATE_FIELD */.M3.DEPRECATE_FIELD:
|
|
@@ -2141,7 +3839,7 @@ class SchemaEvolutionService {
|
|
|
2141
3839
|
return table.indices.filter((i)=>i.columnNames.length === 1 && i.columnNames[0] === column && i.isUnique === unique);
|
|
2142
3840
|
}
|
|
2143
3841
|
// ── add_field ───────────────────────────────────────────────────────────────────────
|
|
2144
|
-
async prepareAddField(request, user) {
|
|
3842
|
+
async prepareAddField(request, user, fieldId) {
|
|
2145
3843
|
const { definition: loaded } = await this.loadEntity(request.entityDefinitionId);
|
|
2146
3844
|
const spec = request.field;
|
|
2147
3845
|
if (!spec) {
|
|
@@ -2166,7 +3864,12 @@ class SchemaEvolutionService {
|
|
|
2166
3864
|
const nullable = spec.nullable ?? true;
|
|
2167
3865
|
const unique = spec.unique ?? false;
|
|
2168
3866
|
const dbType = this.adapter.mapFieldType(spec.fieldType, ctx.driver);
|
|
2169
|
-
|
|
3867
|
+
const isRelation = spec.fieldType === _enums_field_type_enum_js__rspack_import_20/* .FieldType.RELATION */.P.RELATION;
|
|
3868
|
+
if (isRelation && !spec.relationTargetEntityId) {
|
|
3869
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_19/* .SCHEMA_BLOCKER_MESSAGES.RELATION_TARGET_REQUIRED */.M3.RELATION_TARGET_REQUIRED, {
|
|
3870
|
+
field: spec.code
|
|
3871
|
+
}));
|
|
3872
|
+
} else if (isRelation) {
|
|
2170
3873
|
const target = await ctx.qr.manager.getRepository(_entities_entity_definition_entity_js__rspack_import_7/* .EntityDefinition */.f).findOne({
|
|
2171
3874
|
where: {
|
|
2172
3875
|
id: spec.relationTargetEntityId
|
|
@@ -2206,8 +3909,8 @@ class SchemaEvolutionService {
|
|
|
2206
3909
|
}));
|
|
2207
3910
|
}
|
|
2208
3911
|
}
|
|
2209
|
-
//
|
|
2210
|
-
if (unique && backfill !== null && rows > 1) {
|
|
3912
|
+
// Only a required field is backfilled; every existing row gets the same value, so two rows or more would clash.
|
|
3913
|
+
if (unique && !nullable && backfill !== null && rows > 1) {
|
|
2211
3914
|
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_19/* .SCHEMA_BLOCKER_MESSAGES.UNIQUE_BACKFILL_CONFLICT */.M3.UNIQUE_BACKFILL_CONFLICT));
|
|
2212
3915
|
}
|
|
2213
3916
|
if (ctx.blocked || !table) {
|
|
@@ -2257,10 +3960,13 @@ class SchemaEvolutionService {
|
|
|
2257
3960
|
await ctx.qr.createIndex(table, (0,_schema_columns_js__rspack_import_17/* .plainIndex */.v7)(definition.tableName, spec.code, ctx.driver, this.adapter));
|
|
2258
3961
|
});
|
|
2259
3962
|
}
|
|
2260
|
-
let
|
|
3963
|
+
let savedFieldId = null;
|
|
2261
3964
|
await ctx.metadata(async ()=>{
|
|
2262
3965
|
const repo = ctx.qr.manager.getRepository(_entities_field_definition_entity_js__rspack_import_8/* .FieldDefinition */.c);
|
|
2263
3966
|
const saved = await repo.save(repo.create({
|
|
3967
|
+
...fieldId ? {
|
|
3968
|
+
id: fieldId
|
|
3969
|
+
} : {},
|
|
2264
3970
|
entityDefinitionId: definition.id,
|
|
2265
3971
|
code: spec.code,
|
|
2266
3972
|
label: spec.label,
|
|
@@ -2272,18 +3978,18 @@ class SchemaEvolutionService {
|
|
|
2272
3978
|
defaultValue: spec.defaultValue ?? null,
|
|
2273
3979
|
validationRules: spec.validationRules ?? null,
|
|
2274
3980
|
selectOptions: spec.selectOptions ?? null,
|
|
2275
|
-
relationTargetEntityId: spec.relationTargetEntityId
|
|
3981
|
+
relationTargetEntityId: isRelation ? spec.relationTargetEntityId : null,
|
|
2276
3982
|
order: spec.order ?? Math.max(-1, ...fields.map((f)=>f.order)) + 1,
|
|
2277
3983
|
uiConfig: spec.uiConfig ?? null,
|
|
2278
3984
|
isSearchable: spec.isSearchable ?? false,
|
|
2279
3985
|
isSystemField: false,
|
|
2280
3986
|
deprecatedAt: null
|
|
2281
3987
|
}));
|
|
2282
|
-
|
|
3988
|
+
savedFieldId = saved.id;
|
|
2283
3989
|
});
|
|
2284
3990
|
return {
|
|
2285
3991
|
operation: _enums_ddl_operation_enum_js__rspack_import_21/* .DdlOperation.ADD_COLUMN */.i.ADD_COLUMN,
|
|
2286
|
-
fieldDefinitionId:
|
|
3992
|
+
fieldDefinitionId: savedFieldId,
|
|
2287
3993
|
diff: {
|
|
2288
3994
|
field: {
|
|
2289
3995
|
code: spec.code,
|
|
@@ -3288,21 +4994,23 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
3288
4994
|
/* import */ var _flusys_nestjs_shared_utils__rspack_import_1 = __webpack_require__(9216);
|
|
3289
4995
|
/* import */ var _nestjs_common__rspack_import_2 = __webpack_require__(6157);
|
|
3290
4996
|
/* import */ var typeorm__rspack_import_3 = __webpack_require__(7158);
|
|
3291
|
-
/* import */ var
|
|
4997
|
+
/* import */ var _config_message_keys_js__rspack_import_17 = __webpack_require__(5732);
|
|
3292
4998
|
/* import */ var _entities_entity_definition_entity_js__rspack_import_4 = __webpack_require__(3189);
|
|
3293
4999
|
/* import */ var _entities_field_definition_entity_js__rspack_import_5 = __webpack_require__(2206);
|
|
3294
5000
|
/* import */ var _entities_flow_definition_entity_js__rspack_import_6 = __webpack_require__(3770);
|
|
3295
|
-
/* import */ var
|
|
3296
|
-
/* import */ var
|
|
5001
|
+
/* import */ var _enums_ddl_operation_enum_js__rspack_import_20 = __webpack_require__(9949);
|
|
5002
|
+
/* import */ var _enums_entity_status_enum_js__rspack_import_21 = __webpack_require__(1313);
|
|
5003
|
+
/* import */ var _enums_field_type_enum_js__rspack_import_19 = __webpack_require__(9614);
|
|
3297
5004
|
/* import */ var _flow_engine_flow_errors_js__rspack_import_7 = __webpack_require__(8542);
|
|
3298
5005
|
/* import */ var _entity_builder_datasource_provider_js__rspack_import_8 = __webpack_require__(424);
|
|
3299
5006
|
/* import */ var _entity_flow_scaffold_js__rspack_import_9 = __webpack_require__(8271);
|
|
3300
5007
|
/* import */ var _entity_permission_service_js__rspack_import_10 = __webpack_require__(1462);
|
|
3301
|
-
/* import */ var
|
|
3302
|
-
/* import */ var
|
|
3303
|
-
/* import */ var
|
|
3304
|
-
/* import */ var
|
|
3305
|
-
/* import */ var
|
|
5008
|
+
/* import */ var _field_value_validator_js__rspack_import_11 = __webpack_require__(3525);
|
|
5009
|
+
/* import */ var _flow_definition_service_js__rspack_import_12 = __webpack_require__(5229);
|
|
5010
|
+
/* import */ var _identifier_rules_js__rspack_import_13 = __webpack_require__(413);
|
|
5011
|
+
/* import */ var _schema_change_executor_service_js__rspack_import_14 = __webpack_require__(6605);
|
|
5012
|
+
/* import */ var _schema_columns_js__rspack_import_15 = __webpack_require__(5313);
|
|
5013
|
+
/* import */ var _schema_dialect_adapter_service_js__rspack_import_16 = __webpack_require__(7259);
|
|
3306
5014
|
function _ts_decorate(decorators, target, key, desc) {
|
|
3307
5015
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3308
5016
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -3346,6 +5054,11 @@ function _ts_param(paramIndex, decorator) {
|
|
|
3346
5054
|
|
|
3347
5055
|
|
|
3348
5056
|
|
|
5057
|
+
|
|
5058
|
+
|
|
5059
|
+
const presetId = (id)=>id ? {
|
|
5060
|
+
id
|
|
5061
|
+
} : {};
|
|
3349
5062
|
class SchemaSyncService {
|
|
3350
5063
|
dataSourceProvider;
|
|
3351
5064
|
dialectAdapter;
|
|
@@ -3361,17 +5074,17 @@ class SchemaSyncService {
|
|
|
3361
5074
|
this.flowDefinitionService = flowDefinitionService;
|
|
3362
5075
|
}
|
|
3363
5076
|
validateCreateRequest(dto) {
|
|
3364
|
-
(0,
|
|
5077
|
+
(0,_identifier_rules_js__rspack_import_13/* .assertValidIdentifier */.kV)(dto.code, 'entity');
|
|
3365
5078
|
const fields = dto.fields ?? [];
|
|
3366
5079
|
for (const field of fields){
|
|
3367
|
-
(0,
|
|
3368
|
-
(0,
|
|
5080
|
+
(0,_identifier_rules_js__rspack_import_13/* .assertValidIdentifier */.kV)(field.code, 'field');
|
|
5081
|
+
(0,_identifier_rules_js__rspack_import_13/* .assertIndexableField */.fY)(field);
|
|
3369
5082
|
}
|
|
3370
5083
|
const duplicate = fields.map((f)=>f.code).find((code, index, all)=>all.indexOf(code) !== index);
|
|
3371
5084
|
if (duplicate) {
|
|
3372
5085
|
throw new _nestjs_common__rspack_import_2.BadRequestException({
|
|
3373
5086
|
message: `Field code '${duplicate}' is defined more than once.`,
|
|
3374
|
-
messageKey:
|
|
5087
|
+
messageKey: _config_message_keys_js__rspack_import_17/* .SCHEMA_MESSAGES.DUPLICATE_FIELD_CODE */.Hu.DUPLICATE_FIELD_CODE,
|
|
3375
5088
|
messageVariables: {
|
|
3376
5089
|
code: duplicate
|
|
3377
5090
|
}
|
|
@@ -3379,7 +5092,7 @@ class SchemaSyncService {
|
|
|
3379
5092
|
}
|
|
3380
5093
|
}
|
|
3381
5094
|
async createTarget(dto, user) {
|
|
3382
|
-
const lockCodes = await (0,
|
|
5095
|
+
const lockCodes = await (0,_schema_change_executor_service_js__rspack_import_14/* .relationTargetCodes */.e)(this.dataSourceProvider, (dto.fields ?? []).map((f)=>f.relationTargetEntityId));
|
|
3383
5096
|
return {
|
|
3384
5097
|
action: 'create_entity',
|
|
3385
5098
|
entityDefinitionId: null,
|
|
@@ -3389,7 +5102,7 @@ class SchemaSyncService {
|
|
|
3389
5102
|
lockCodes
|
|
3390
5103
|
};
|
|
3391
5104
|
}
|
|
3392
|
-
createRun(dto, user, created) {
|
|
5105
|
+
createRun(dto, user, created, ids = {}) {
|
|
3393
5106
|
const tableName = `${(/* inlined export .ENTITY_TABLE_PREFIX */"eb_")}${dto.code}`;
|
|
3394
5107
|
const fieldSpecs = dto.fields ?? [];
|
|
3395
5108
|
const flowEndpoints = dto.flowEndpoints ?? [];
|
|
@@ -3400,7 +5113,7 @@ class SchemaSyncService {
|
|
|
3400
5113
|
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), [
|
|
3401
5114
|
tableName
|
|
3402
5115
|
]);
|
|
3403
|
-
if (taken.length) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5116
|
+
if (taken.length) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_17/* .SCHEMA_BLOCKER_MESSAGES.TABLE_EXISTS */.M3.TABLE_EXISTS, {
|
|
3404
5117
|
table: tableName
|
|
3405
5118
|
}));
|
|
3406
5119
|
const definitions = ctx.qr.manager.getRepository(_entities_entity_definition_entity_js__rspack_import_4/* .EntityDefinition */.f);
|
|
@@ -3409,21 +5122,41 @@ class SchemaSyncService {
|
|
|
3409
5122
|
code: dto.code
|
|
3410
5123
|
}
|
|
3411
5124
|
});
|
|
3412
|
-
if (known) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5125
|
+
if (known) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_17/* .SCHEMA_BLOCKER_MESSAGES.ENTITY_CODE_EXISTS */.M3.ENTITY_CODE_EXISTS, {
|
|
3413
5126
|
code: dto.code
|
|
3414
5127
|
}));
|
|
3415
|
-
for (const spec of fieldSpecs){
|
|
3416
|
-
if (spec.relationTargetEntityId) {
|
|
3417
|
-
|
|
3418
|
-
where: {
|
|
3419
|
-
id: spec.relationTargetEntityId
|
|
3420
|
-
}
|
|
3421
|
-
});
|
|
3422
|
-
if (!target) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_16/* .SCHEMA_BLOCKER_MESSAGES.RELATION_FIELD_TARGET_MISSING */.M3.RELATION_FIELD_TARGET_MISSING, {
|
|
5128
|
+
for (const spec of fieldSpecs.filter((f)=>f.fieldType === _enums_field_type_enum_js__rspack_import_19/* .FieldType.RELATION */.P.RELATION)){
|
|
5129
|
+
if (!spec.relationTargetEntityId) {
|
|
5130
|
+
ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_17/* .SCHEMA_BLOCKER_MESSAGES.RELATION_TARGET_REQUIRED */.M3.RELATION_TARGET_REQUIRED, {
|
|
3423
5131
|
field: spec.code
|
|
3424
5132
|
}));
|
|
5133
|
+
continue;
|
|
3425
5134
|
}
|
|
5135
|
+
const target = await definitions.findOne({
|
|
5136
|
+
where: {
|
|
5137
|
+
id: spec.relationTargetEntityId
|
|
5138
|
+
}
|
|
5139
|
+
});
|
|
5140
|
+
if (!target) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_17/* .SCHEMA_BLOCKER_MESSAGES.RELATION_FIELD_TARGET_MISSING */.M3.RELATION_FIELD_TARGET_MISSING, {
|
|
5141
|
+
field: spec.code
|
|
5142
|
+
}));
|
|
3426
5143
|
}
|
|
5144
|
+
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)=>[
|
|
5154
|
+
f.code,
|
|
5155
|
+
f.defaultValue
|
|
5156
|
+
])), 'insert');
|
|
5157
|
+
for (const error of defaultErrors)ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_17/* .SCHEMA_BLOCKER_MESSAGES.DEFAULT_INVALID */.M3.DEFAULT_INVALID, {
|
|
5158
|
+
problem: (0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(error.messageKey, error.messageVariables)
|
|
5159
|
+
}));
|
|
3427
5160
|
if (flowEndpoints.length) {
|
|
3428
5161
|
const slug = (0,_entity_flow_scaffold_js__rspack_import_9/* .entityFlowSlug */.x2)(dto.code);
|
|
3429
5162
|
const clash = await ctx.qr.manager.getRepository(_entities_flow_definition_entity_js__rspack_import_6/* .FlowDefinition */.G).findOne({
|
|
@@ -3435,15 +5168,15 @@ class SchemaSyncService {
|
|
|
3435
5168
|
},
|
|
3436
5169
|
withDeleted: true
|
|
3437
5170
|
});
|
|
3438
|
-
if (clash) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5171
|
+
if (clash) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_17/* .SCHEMA_BLOCKER_MESSAGES.FLOW_SLUG_TAKEN */.M3.FLOW_SLUG_TAKEN, {
|
|
3439
5172
|
slug
|
|
3440
5173
|
}));
|
|
3441
5174
|
}
|
|
3442
5175
|
if (ctx.blocked) return {
|
|
3443
|
-
operation:
|
|
5176
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_20/* .DdlOperation.CREATE_TABLE */.i.CREATE_TABLE,
|
|
3444
5177
|
diff: {}
|
|
3445
5178
|
};
|
|
3446
|
-
const columns = fieldSpecs.map((spec)=>(0,
|
|
5179
|
+
const columns = fieldSpecs.map((spec)=>(0,_schema_columns_js__rspack_import_15/* .buildFieldColumn */.fu)({
|
|
3447
5180
|
code: spec.code,
|
|
3448
5181
|
fieldType: spec.fieldType,
|
|
3449
5182
|
dbType: '',
|
|
@@ -3456,33 +5189,34 @@ class SchemaSyncService {
|
|
|
3456
5189
|
const table = new typeorm__rspack_import_3.Table({
|
|
3457
5190
|
name: tableName,
|
|
3458
5191
|
columns: [
|
|
3459
|
-
...(0,
|
|
5192
|
+
...(0,_schema_columns_js__rspack_import_15/* .buildSystemColumns */.Rm)({
|
|
3460
5193
|
isSoftDeleteEnabled,
|
|
3461
5194
|
isAuditEnabled
|
|
3462
5195
|
}, ctx.driver),
|
|
3463
5196
|
...columns
|
|
3464
5197
|
]
|
|
3465
5198
|
});
|
|
3466
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5199
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_17/* .SCHEMA_STEP_MESSAGES.CREATE_TABLE */.EQ.CREATE_TABLE, {
|
|
3467
5200
|
table: tableName
|
|
3468
5201
|
}), async ()=>{
|
|
3469
5202
|
await ctx.qr.createTable(table, false);
|
|
3470
5203
|
});
|
|
3471
5204
|
for (const spec of fieldSpecs.filter((f)=>f.isIndexed && !f.unique)){
|
|
3472
|
-
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5205
|
+
await ctx.ddl((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_17/* .SCHEMA_STEP_MESSAGES.ADD_INDEX */.EQ.ADD_INDEX, {
|
|
3473
5206
|
column: spec.code
|
|
3474
5207
|
}), async ()=>{
|
|
3475
|
-
await ctx.qr.createIndex(table, (0,
|
|
5208
|
+
await ctx.qr.createIndex(table, (0,_schema_columns_js__rspack_import_15/* .plainIndex */.v7)(tableName, spec.code, ctx.driver, this.dialectAdapter));
|
|
3476
5209
|
});
|
|
3477
5210
|
}
|
|
3478
5211
|
await ctx.metadata(async ()=>{
|
|
3479
5212
|
const definitionRepo = ctx.qr.manager.getRepository(_entities_entity_definition_entity_js__rspack_import_4/* .EntityDefinition */.f);
|
|
3480
5213
|
const definition = await definitionRepo.save(definitionRepo.create({
|
|
5214
|
+
...presetId(ids.entityId),
|
|
3481
5215
|
code: dto.code,
|
|
3482
5216
|
label: dto.label,
|
|
3483
5217
|
description: dto.description ?? null,
|
|
3484
5218
|
tableName,
|
|
3485
|
-
status:
|
|
5219
|
+
status: _enums_entity_status_enum_js__rspack_import_21/* .EntityStatus.ACTIVE */.c.ACTIVE,
|
|
3486
5220
|
schemaVersion: 1,
|
|
3487
5221
|
isSoftDeleteEnabled,
|
|
3488
5222
|
isAuditEnabled,
|
|
@@ -3491,6 +5225,7 @@ class SchemaSyncService {
|
|
|
3491
5225
|
const fieldRepo = ctx.qr.manager.getRepository(_entities_field_definition_entity_js__rspack_import_5/* .FieldDefinition */.c);
|
|
3492
5226
|
if (fieldSpecs.length) {
|
|
3493
5227
|
await fieldRepo.save(fieldSpecs.map((spec, index)=>fieldRepo.create({
|
|
5228
|
+
...presetId(ids.fieldIds?.[spec.code]),
|
|
3494
5229
|
entityDefinitionId: definition.id,
|
|
3495
5230
|
code: spec.code,
|
|
3496
5231
|
label: spec.label,
|
|
@@ -3502,7 +5237,7 @@ class SchemaSyncService {
|
|
|
3502
5237
|
defaultValue: spec.defaultValue ?? null,
|
|
3503
5238
|
validationRules: spec.validationRules ?? null,
|
|
3504
5239
|
selectOptions: spec.selectOptions ?? null,
|
|
3505
|
-
relationTargetEntityId: spec.relationTargetEntityId
|
|
5240
|
+
relationTargetEntityId: spec.fieldType === _enums_field_type_enum_js__rspack_import_19/* .FieldType.RELATION */.P.RELATION ? spec.relationTargetEntityId : null,
|
|
3506
5241
|
order: spec.order ?? index,
|
|
3507
5242
|
uiConfig: spec.uiConfig ?? null,
|
|
3508
5243
|
isSearchable: spec.isSearchable ?? false,
|
|
@@ -3513,7 +5248,7 @@ class SchemaSyncService {
|
|
|
3513
5248
|
created.definition = definition;
|
|
3514
5249
|
});
|
|
3515
5250
|
return {
|
|
3516
|
-
operation:
|
|
5251
|
+
operation: _enums_ddl_operation_enum_js__rspack_import_20/* .DdlOperation.CREATE_TABLE */.i.CREATE_TABLE,
|
|
3517
5252
|
entityDefinitionId: created.definition?.id ?? null,
|
|
3518
5253
|
diff: {
|
|
3519
5254
|
fields: fieldSpecs.map((f)=>({
|
|
@@ -3549,7 +5284,7 @@ class SchemaSyncService {
|
|
|
3549
5284
|
} catch (error) {
|
|
3550
5285
|
this.logger.error(`The flow '${flow.slug}' of entity '${dto.code}' could not be created: ${error.message}`);
|
|
3551
5286
|
return [
|
|
3552
|
-
(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(
|
|
5287
|
+
(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_17/* .SCHEMA_WARNING_MESSAGES.ENDPOINT_FLOW_FAILED */.Uu.ENDPOINT_FLOW_FAILED, {
|
|
3553
5288
|
slug: flow.slug,
|
|
3554
5289
|
detail: (0,_flow_engine_flow_errors_js__rspack_import_7/* .errorRef */.O$)(error)
|
|
3555
5290
|
})
|
|
@@ -3562,7 +5297,7 @@ class SchemaSyncService {
|
|
|
3562
5297
|
warnings: []
|
|
3563
5298
|
}));
|
|
3564
5299
|
}
|
|
3565
|
-
async createEntity(dto, user) {
|
|
5300
|
+
async createEntity(dto, user, ids = {}) {
|
|
3566
5301
|
this.validateCreateRequest(dto);
|
|
3567
5302
|
if (dto.flowEndpoints?.length) await this.flowDefinitionService.assertMayCreate(user);
|
|
3568
5303
|
const created = {
|
|
@@ -3570,12 +5305,12 @@ class SchemaSyncService {
|
|
|
3570
5305
|
};
|
|
3571
5306
|
let planWarnings;
|
|
3572
5307
|
try {
|
|
3573
|
-
({ plan: { warnings: planWarnings } } = await this.executor.apply(await this.createTarget(dto, user), this.createRun(dto, user, created)));
|
|
5308
|
+
({ plan: { warnings: planWarnings } } = await this.executor.apply(await this.createTarget(dto, user), this.createRun(dto, user, created, ids)));
|
|
3574
5309
|
} catch (error) {
|
|
3575
|
-
if (error instanceof _nestjs_common__rspack_import_2.ConflictException && error.getResponse().blockers?.some((b)=>b.messageKey ===
|
|
5310
|
+
if (error instanceof _nestjs_common__rspack_import_2.ConflictException && error.getResponse().blockers?.some((b)=>b.messageKey === _config_message_keys_js__rspack_import_17/* .SCHEMA_BLOCKER_MESSAGES.ENTITY_CODE_EXISTS */.M3.ENTITY_CODE_EXISTS || b.messageKey === _config_message_keys_js__rspack_import_17/* .SCHEMA_BLOCKER_MESSAGES.TABLE_EXISTS */.M3.TABLE_EXISTS)) {
|
|
3576
5311
|
throw new _nestjs_common__rspack_import_2.ConflictException({
|
|
3577
5312
|
message: `An entity with the code '${dto.code}' already exists.`,
|
|
3578
|
-
messageKey:
|
|
5313
|
+
messageKey: _config_message_keys_js__rspack_import_17/* .ENTITY_DEFINITION_MESSAGES.CODE_ALREADY_EXISTS */.pL.CODE_ALREADY_EXISTS,
|
|
3579
5314
|
messageVariables: {
|
|
3580
5315
|
code: dto.code
|
|
3581
5316
|
}
|
|
@@ -3597,17 +5332,17 @@ SchemaSyncService = _ts_decorate([
|
|
|
3597
5332
|
scope: _nestjs_common__rspack_import_2.Scope.REQUEST
|
|
3598
5333
|
}),
|
|
3599
5334
|
_ts_param(0, (0,_nestjs_common__rspack_import_2.Inject)(_entity_builder_datasource_provider_js__rspack_import_8/* .EntityBuilderDataSourceProvider */.D)),
|
|
3600
|
-
_ts_param(1, (0,_nestjs_common__rspack_import_2.Inject)(
|
|
3601
|
-
_ts_param(2, (0,_nestjs_common__rspack_import_2.Inject)(
|
|
5335
|
+
_ts_param(1, (0,_nestjs_common__rspack_import_2.Inject)(_schema_dialect_adapter_service_js__rspack_import_16/* .SchemaDialectAdapterService */.I)),
|
|
5336
|
+
_ts_param(2, (0,_nestjs_common__rspack_import_2.Inject)(_schema_change_executor_service_js__rspack_import_14/* .SchemaChangeExecutor */.T)),
|
|
3602
5337
|
_ts_param(3, (0,_nestjs_common__rspack_import_2.Inject)(_entity_permission_service_js__rspack_import_10/* .EntityPermissionService */.u)),
|
|
3603
|
-
_ts_param(4, (0,_nestjs_common__rspack_import_2.Inject)(
|
|
5338
|
+
_ts_param(4, (0,_nestjs_common__rspack_import_2.Inject)(_flow_definition_service_js__rspack_import_12/* .FlowDefinitionService */.Tk)),
|
|
3604
5339
|
_ts_metadata("design:type", Function),
|
|
3605
5340
|
_ts_metadata("design:paramtypes", [
|
|
3606
5341
|
typeof _entity_builder_datasource_provider_js__rspack_import_8/* .EntityBuilderDataSourceProvider */.D === "undefined" ? Object : _entity_builder_datasource_provider_js__rspack_import_8/* .EntityBuilderDataSourceProvider */.D,
|
|
3607
|
-
typeof
|
|
3608
|
-
typeof
|
|
5342
|
+
typeof _schema_dialect_adapter_service_js__rspack_import_16/* .SchemaDialectAdapterService */.I === "undefined" ? Object : _schema_dialect_adapter_service_js__rspack_import_16/* .SchemaDialectAdapterService */.I,
|
|
5343
|
+
typeof _schema_change_executor_service_js__rspack_import_14/* .SchemaChangeExecutor */.T === "undefined" ? Object : _schema_change_executor_service_js__rspack_import_14/* .SchemaChangeExecutor */.T,
|
|
3609
5344
|
typeof _entity_permission_service_js__rspack_import_10/* .EntityPermissionService */.u === "undefined" ? Object : _entity_permission_service_js__rspack_import_10/* .EntityPermissionService */.u,
|
|
3610
|
-
typeof
|
|
5345
|
+
typeof _flow_definition_service_js__rspack_import_12/* .FlowDefinitionService */.Tk === "undefined" ? Object : _flow_definition_service_js__rspack_import_12/* .FlowDefinitionService */.Tk
|
|
3611
5346
|
])
|
|
3612
5347
|
], SchemaSyncService);
|
|
3613
5348
|
|