@flusys/nestjs-entity-builder 9.1.0-rc.1 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/config/message-keys.d.ts +9 -1
- package/controllers/flow-runtime.controller.d.ts +16 -8
- package/dtos/flow.dto.d.ts +1 -0
- package/fesm/21.js +9 -1
- package/fesm/362.js +6 -6
- package/fesm/606.js +58 -7
- package/fesm/719.js +158 -152
- package/fesm/996.js +175 -52
- package/fesm/guards/index.js +6 -1
- package/fesm/index.js +16 -5
- package/fesm/modules/index.js +3 -2
- package/fesm/services/index.js +5 -3
- package/flow-engine/flow-graph.validator.d.ts +2 -3
- package/flow-engine/flow-run.types.d.ts +2 -1
- package/flow-engine/flow.types.d.ts +16 -0
- package/package.json +3 -3
- package/services/entity-flow-scaffold.d.ts +3 -2
- package/services/flow-definition.service.d.ts +1 -0
- package/services/flow-executor.service.d.ts +1 -0
- package/services/flow-runtime.service.d.ts +2 -1
- package/services/schema-sync.service.d.ts +1 -1
package/fesm/719.js
CHANGED
|
@@ -153,7 +153,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
153
153
|
|
|
154
154
|
|
|
155
155
|
|
|
156
|
-
const
|
|
156
|
+
/** The path of each endpoint's Request step: `api-flows/<entity>/<path>`. */ const ENTITY_FLOW_PATHS = {
|
|
157
157
|
insert: 'insert',
|
|
158
158
|
insertMany: 'insert-many',
|
|
159
159
|
getById: 'get-by-id',
|
|
@@ -165,7 +165,7 @@ const SLUG_SUFFIX = {
|
|
|
165
165
|
bulkUpsert: 'bulk-upsert',
|
|
166
166
|
delete: 'delete'
|
|
167
167
|
};
|
|
168
|
-
const
|
|
168
|
+
const DEFAULT_ENDPOINT_NAME = {
|
|
169
169
|
insert: 'Insert',
|
|
170
170
|
insertMany: 'Insert many',
|
|
171
171
|
getById: 'Get by id',
|
|
@@ -183,7 +183,7 @@ const DEFAULT_INPUT_LABEL = {
|
|
|
183
183
|
search: 'Search'
|
|
184
184
|
};
|
|
185
185
|
const DEFAULT_NO_MATCH_MESSAGE = 'No record matches the filter.';
|
|
186
|
-
const
|
|
186
|
+
const MAX_NAME_LENGTH = 255;
|
|
187
187
|
/** A supplied text when it has content, the English default otherwise. */ const textOr = (value, fallback)=>value?.trim() || fallback;
|
|
188
188
|
const INPUT_TYPE = {
|
|
189
189
|
[_enums_field_type_enum_js__rspack_import_1/* .FieldType.TEXT */.P.TEXT]: 'string',
|
|
@@ -200,8 +200,13 @@ const INPUT_TYPE = {
|
|
|
200
200
|
[_enums_field_type_enum_js__rspack_import_1/* .FieldType.JSON */.P.JSON]: 'object',
|
|
201
201
|
[_enums_field_type_enum_js__rspack_import_1/* .FieldType.FILE */.P.FILE]: 'string'
|
|
202
202
|
};
|
|
203
|
-
const MAX_SLUG_LENGTH = 63;
|
|
204
203
|
const LIST_LIMIT = 50;
|
|
204
|
+
const READ_ENDPOINTS = new Set([
|
|
205
|
+
'getById',
|
|
206
|
+
'getByIds',
|
|
207
|
+
'getAll',
|
|
208
|
+
'getByFilter'
|
|
209
|
+
]);
|
|
205
210
|
/** A bulk flow runs up to three steps per item (bulkUpsert: check, write, keep), well inside FLOW_LIMITS.MAX_STEPS_PER_RUN. */ const BULK_MAX_ITEMS = 200;
|
|
206
211
|
const COLUMN = {
|
|
207
212
|
x: 40,
|
|
@@ -219,11 +224,7 @@ const lit = (value)=>({
|
|
|
219
224
|
type: 'literal',
|
|
220
225
|
value
|
|
221
226
|
});
|
|
222
|
-
/** `customer_ticket`
|
|
223
|
-
const suffix = SLUG_SUFFIX[endpoint];
|
|
224
|
-
const base = entityCode.replace(/_/g, '-').slice(0, MAX_SLUG_LENGTH - suffix.length - 1).replace(/-+$/, '');
|
|
225
|
-
return `${base}-${suffix}`;
|
|
226
|
-
}
|
|
227
|
+
/** `customer_ticket` -> `customer-ticket`: an entity code always fits a flow URL name. */ const entityFlowSlug = (entityCode)=>entityCode.replace(/_/g, '-');
|
|
227
228
|
function optionValues(options) {
|
|
228
229
|
return (options ?? []).map((o)=>o && typeof o === 'object' && 'value' in o ? String(o.value) : String(o));
|
|
229
230
|
}
|
|
@@ -275,56 +276,59 @@ const respond = (id, column, statusCode, body, row)=>({
|
|
|
275
276
|
body
|
|
276
277
|
}
|
|
277
278
|
});
|
|
278
|
-
/**
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
id: 'each',
|
|
285
|
-
type: 'foreach',
|
|
286
|
-
column: 1,
|
|
287
|
-
config: {
|
|
288
|
-
items: ref('input'),
|
|
289
|
-
maxItems: BULK_MAX_ITEMS,
|
|
290
|
-
collect
|
|
291
|
-
}
|
|
292
|
-
},
|
|
293
|
-
...body,
|
|
294
|
-
respond('respond', 2, statusCode, ref('context.each.results'))
|
|
295
|
-
],
|
|
296
|
-
edges: [
|
|
297
|
-
[
|
|
298
|
-
'each',
|
|
299
|
-
'each',
|
|
300
|
-
body[0].id
|
|
301
|
-
],
|
|
302
|
-
...bodyEdges,
|
|
303
|
-
[
|
|
304
|
-
'each',
|
|
305
|
-
'done',
|
|
306
|
-
'respond'
|
|
307
|
-
]
|
|
308
|
-
],
|
|
309
|
-
isTransactional: true
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
function endpointGraph(entity, endpoint, texts) {
|
|
279
|
+
/**
|
|
280
|
+
* 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
|
+
* foreach `input` -> `body` (per item) ... done -> respond with the collected results.
|
|
283
|
+
*/ function endpointGraph(entity, endpoint, texts) {
|
|
284
|
+
const id = (step)=>`${endpoint}_${step}`;
|
|
313
285
|
const entityCode = entity.code;
|
|
314
286
|
const single = (inputSchema, step, statusCode = 200)=>({
|
|
315
287
|
inputSchema,
|
|
316
288
|
steps: [
|
|
317
289
|
{
|
|
318
290
|
...step,
|
|
291
|
+
id: id('record'),
|
|
319
292
|
column: 1
|
|
320
293
|
},
|
|
321
|
-
respond('respond', 2, statusCode, ref(`context.${
|
|
294
|
+
respond(id('respond'), 2, statusCode, ref(`context.${id('record')}`))
|
|
322
295
|
],
|
|
323
296
|
edges: [
|
|
324
297
|
[
|
|
325
|
-
|
|
298
|
+
id('record'),
|
|
326
299
|
'out',
|
|
327
|
-
'respond'
|
|
300
|
+
id('respond')
|
|
301
|
+
]
|
|
302
|
+
]
|
|
303
|
+
});
|
|
304
|
+
const bulk = (itemSchema, body, bodyEdges, collect, statusCode)=>({
|
|
305
|
+
bodyType: 'list',
|
|
306
|
+
inputSchema: itemSchema,
|
|
307
|
+
steps: [
|
|
308
|
+
{
|
|
309
|
+
id: id('each'),
|
|
310
|
+
type: 'foreach',
|
|
311
|
+
column: 1,
|
|
312
|
+
config: {
|
|
313
|
+
items: ref('input'),
|
|
314
|
+
maxItems: BULK_MAX_ITEMS,
|
|
315
|
+
collect
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
...body,
|
|
319
|
+
respond(id('respond'), 2, statusCode, ref(`context.${id('each')}.results`))
|
|
320
|
+
],
|
|
321
|
+
edges: [
|
|
322
|
+
[
|
|
323
|
+
id('each'),
|
|
324
|
+
'each',
|
|
325
|
+
body[0].id
|
|
326
|
+
],
|
|
327
|
+
...bodyEdges,
|
|
328
|
+
[
|
|
329
|
+
id('each'),
|
|
330
|
+
'done',
|
|
331
|
+
id('respond')
|
|
328
332
|
]
|
|
329
333
|
]
|
|
330
334
|
});
|
|
@@ -333,7 +337,6 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
333
337
|
switch(endpoint){
|
|
334
338
|
case 'insert':
|
|
335
339
|
return single(insertInputs, {
|
|
336
|
-
id: 'record',
|
|
337
340
|
type: 'entity_insert',
|
|
338
341
|
config: {
|
|
339
342
|
entityCode,
|
|
@@ -341,9 +344,9 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
341
344
|
}
|
|
342
345
|
}, 201);
|
|
343
346
|
case 'insertMany':
|
|
344
|
-
return
|
|
347
|
+
return bulk(insertInputs, [
|
|
345
348
|
{
|
|
346
|
-
id: 'record',
|
|
349
|
+
id: id('record'),
|
|
347
350
|
type: 'entity_insert',
|
|
348
351
|
column: 1,
|
|
349
352
|
row: 1,
|
|
@@ -352,12 +355,11 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
352
355
|
fields: fieldMap(entity.fields, 'loop.item')
|
|
353
356
|
}
|
|
354
357
|
}
|
|
355
|
-
], [], ref('
|
|
358
|
+
], [], ref(`context.${id('record')}`), 201);
|
|
356
359
|
case 'getById':
|
|
357
360
|
return single([
|
|
358
361
|
idInput(texts)
|
|
359
362
|
], {
|
|
360
|
-
id: 'record',
|
|
361
363
|
type: 'entity_get',
|
|
362
364
|
config: {
|
|
363
365
|
entityCode,
|
|
@@ -368,7 +370,6 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
368
370
|
return single([
|
|
369
371
|
idsInput(texts)
|
|
370
372
|
], {
|
|
371
|
-
id: 'records',
|
|
372
373
|
type: 'entity_query',
|
|
373
374
|
config: {
|
|
374
375
|
entityCode,
|
|
@@ -390,7 +391,6 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
390
391
|
},
|
|
391
392
|
...optionalFieldInputs(filterFields)
|
|
392
393
|
], {
|
|
393
|
-
id: 'records',
|
|
394
394
|
type: 'entity_query',
|
|
395
395
|
config: {
|
|
396
396
|
entityCode,
|
|
@@ -410,7 +410,7 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
410
410
|
],
|
|
411
411
|
steps: [
|
|
412
412
|
{
|
|
413
|
-
id: 'records',
|
|
413
|
+
id: id('records'),
|
|
414
414
|
type: 'entity_query',
|
|
415
415
|
column: 1,
|
|
416
416
|
config: {
|
|
@@ -423,7 +423,7 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
423
423
|
}
|
|
424
424
|
},
|
|
425
425
|
{
|
|
426
|
-
id: 'found',
|
|
426
|
+
id: id('found'),
|
|
427
427
|
type: 'condition',
|
|
428
428
|
column: 2,
|
|
429
429
|
config: {
|
|
@@ -431,15 +431,15 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
431
431
|
operator: 'AND',
|
|
432
432
|
conditions: [
|
|
433
433
|
{
|
|
434
|
-
field: '
|
|
434
|
+
field: `context.${id('records')}.items`,
|
|
435
435
|
comparison: 'is_not_empty'
|
|
436
436
|
}
|
|
437
437
|
]
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
},
|
|
441
|
-
respond('respond', 3, 200, ref('
|
|
442
|
-
respond('not_found', 3, 404, {
|
|
441
|
+
respond(id('respond'), 3, 200, ref(`context.${id('records')}.items.0`)),
|
|
442
|
+
respond(id('not_found'), 3, 404, {
|
|
443
443
|
success: lit(false),
|
|
444
444
|
message: lit(texts.noMatchMessage),
|
|
445
445
|
messageKey: lit(_config_message_keys_js__rspack_import_2/* .GENERIC_RECORD_MESSAGES.NO_MATCH */.j4.NO_MATCH)
|
|
@@ -447,19 +447,19 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
447
447
|
],
|
|
448
448
|
edges: [
|
|
449
449
|
[
|
|
450
|
-
'records',
|
|
450
|
+
id('records'),
|
|
451
451
|
'out',
|
|
452
|
-
'found'
|
|
452
|
+
id('found')
|
|
453
453
|
],
|
|
454
454
|
[
|
|
455
|
-
'found',
|
|
455
|
+
id('found'),
|
|
456
456
|
'true',
|
|
457
|
-
'respond'
|
|
457
|
+
id('respond')
|
|
458
458
|
],
|
|
459
459
|
[
|
|
460
|
-
'found',
|
|
460
|
+
id('found'),
|
|
461
461
|
'false',
|
|
462
|
-
'not_found'
|
|
462
|
+
id('not_found')
|
|
463
463
|
]
|
|
464
464
|
]
|
|
465
465
|
};
|
|
@@ -468,7 +468,6 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
468
468
|
idInput(texts),
|
|
469
469
|
...optionalFieldInputs(entity.fields)
|
|
470
470
|
], {
|
|
471
|
-
id: 'record',
|
|
472
471
|
type: 'entity_update',
|
|
473
472
|
config: {
|
|
474
473
|
entityCode,
|
|
@@ -477,12 +476,12 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
477
476
|
}
|
|
478
477
|
});
|
|
479
478
|
case 'updateMany':
|
|
480
|
-
return
|
|
479
|
+
return bulk([
|
|
481
480
|
idInput(texts),
|
|
482
481
|
...optionalFieldInputs(entity.fields)
|
|
483
482
|
], [
|
|
484
483
|
{
|
|
485
|
-
id: 'record',
|
|
484
|
+
id: id('record'),
|
|
486
485
|
type: 'entity_update',
|
|
487
486
|
column: 1,
|
|
488
487
|
row: 1,
|
|
@@ -492,9 +491,9 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
492
491
|
fields: fieldMap(entity.fields, 'loop.item')
|
|
493
492
|
}
|
|
494
493
|
}
|
|
495
|
-
], [], ref('
|
|
494
|
+
], [], ref(`context.${id('record')}`), 200);
|
|
496
495
|
case 'bulkUpsert':
|
|
497
|
-
return
|
|
496
|
+
return bulk([
|
|
498
497
|
{
|
|
499
498
|
...idInput(texts),
|
|
500
499
|
required: false
|
|
@@ -502,7 +501,7 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
502
501
|
...optionalFieldInputs(entity.fields)
|
|
503
502
|
], [
|
|
504
503
|
{
|
|
505
|
-
id: 'has_id',
|
|
504
|
+
id: id('has_id'),
|
|
506
505
|
type: 'condition',
|
|
507
506
|
column: 1,
|
|
508
507
|
row: 1,
|
|
@@ -519,7 +518,7 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
519
518
|
}
|
|
520
519
|
},
|
|
521
520
|
{
|
|
522
|
-
id: 'updated',
|
|
521
|
+
id: id('updated'),
|
|
523
522
|
type: 'entity_update',
|
|
524
523
|
column: 2,
|
|
525
524
|
row: 1,
|
|
@@ -530,7 +529,7 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
530
529
|
}
|
|
531
530
|
},
|
|
532
531
|
{
|
|
533
|
-
id: 'inserted',
|
|
532
|
+
id: id('inserted'),
|
|
534
533
|
type: 'entity_insert',
|
|
535
534
|
column: 2,
|
|
536
535
|
row: 2,
|
|
@@ -540,54 +539,53 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
540
539
|
}
|
|
541
540
|
},
|
|
542
541
|
{
|
|
543
|
-
id: 'keep_updated',
|
|
542
|
+
id: id('keep_updated'),
|
|
544
543
|
type: 'set',
|
|
545
544
|
column: 3,
|
|
546
545
|
row: 1,
|
|
547
546
|
config: {
|
|
548
547
|
values: {
|
|
549
|
-
saved: ref('
|
|
548
|
+
saved: ref(`context.${id('updated')}`)
|
|
550
549
|
}
|
|
551
550
|
}
|
|
552
551
|
},
|
|
553
552
|
{
|
|
554
|
-
id: 'keep_inserted',
|
|
553
|
+
id: id('keep_inserted'),
|
|
555
554
|
type: 'set',
|
|
556
555
|
column: 3,
|
|
557
556
|
row: 2,
|
|
558
557
|
config: {
|
|
559
558
|
values: {
|
|
560
|
-
saved: ref('
|
|
559
|
+
saved: ref(`context.${id('inserted')}`)
|
|
561
560
|
}
|
|
562
561
|
}
|
|
563
562
|
}
|
|
564
563
|
], [
|
|
565
564
|
[
|
|
566
|
-
'has_id',
|
|
565
|
+
id('has_id'),
|
|
567
566
|
'true',
|
|
568
|
-
'updated'
|
|
567
|
+
id('updated')
|
|
569
568
|
],
|
|
570
569
|
[
|
|
571
|
-
'has_id',
|
|
570
|
+
id('has_id'),
|
|
572
571
|
'false',
|
|
573
|
-
'inserted'
|
|
572
|
+
id('inserted')
|
|
574
573
|
],
|
|
575
574
|
[
|
|
576
|
-
'updated',
|
|
575
|
+
id('updated'),
|
|
577
576
|
'out',
|
|
578
|
-
'keep_updated'
|
|
577
|
+
id('keep_updated')
|
|
579
578
|
],
|
|
580
579
|
[
|
|
581
|
-
'inserted',
|
|
580
|
+
id('inserted'),
|
|
582
581
|
'out',
|
|
583
|
-
'keep_inserted'
|
|
582
|
+
id('keep_inserted')
|
|
584
583
|
]
|
|
585
584
|
], ref('vars.saved'), 200);
|
|
586
585
|
case 'delete':
|
|
587
586
|
return single([
|
|
588
587
|
idInput(texts)
|
|
589
588
|
], {
|
|
590
|
-
id: 'record',
|
|
591
589
|
type: 'entity_delete',
|
|
592
590
|
config: {
|
|
593
591
|
entityCode,
|
|
@@ -597,11 +595,13 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
597
595
|
}
|
|
598
596
|
}
|
|
599
597
|
/**
|
|
600
|
-
*
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
|
|
598
|
+
* The ready-made flow of an entity: `api-flows/<entity>` with one Request step per endpoint of the
|
|
599
|
+
* generic API controller, each on its own path (`ENTITY_FLOW_PATHS`) with its own body, laid out
|
|
600
|
+
* one below the other. It runs as the caller, so the entity permissions still decide who may use
|
|
601
|
+
* it, and it is an ordinary flow afterwards - the user can change or delete it like any other. A
|
|
602
|
+
* flow with a write endpoint is transactional: a bulk endpoint loops over its list in one
|
|
603
|
+
* transaction, so a failing item rolls back the whole request.
|
|
604
|
+
*/ function buildEntityFlow(entity, endpoints, texts = {}) {
|
|
605
605
|
const resolved = {
|
|
606
606
|
inputLabels: {
|
|
607
607
|
id: textOr(texts.inputLabels?.id, DEFAULT_INPUT_LABEL.id),
|
|
@@ -610,57 +610,65 @@ function endpointGraph(entity, endpoint, texts) {
|
|
|
610
610
|
},
|
|
611
611
|
noMatchMessage: textOr(texts.noMatchMessage, DEFAULT_NO_MATCH_MESSAGE)
|
|
612
612
|
};
|
|
613
|
-
const
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
|
|
613
|
+
const nodes = [];
|
|
614
|
+
const edges = [];
|
|
615
|
+
let band = 0;
|
|
616
|
+
for (const endpoint of endpoints){
|
|
617
|
+
const graph = endpointGraph(entity, endpoint, resolved);
|
|
618
|
+
const at = (column, row = 0)=>({
|
|
619
|
+
x: COLUMN.x + column * COLUMN.gap,
|
|
620
|
+
y: ROW.y + (band + row) * ROW.gap
|
|
621
|
+
});
|
|
622
|
+
const config = {
|
|
623
|
+
path: ENTITY_FLOW_PATHS[endpoint],
|
|
624
|
+
bodyType: graph.bodyType ?? 'object',
|
|
625
|
+
inputSchema: graph.inputSchema
|
|
626
|
+
};
|
|
627
|
+
nodes.push({
|
|
628
|
+
id: endpoint,
|
|
617
629
|
type: 'trigger',
|
|
618
|
-
name:
|
|
619
|
-
position:
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
},
|
|
623
|
-
config: {}
|
|
624
|
-
},
|
|
625
|
-
...graph.steps.map(({ column, row, ...step })=>({
|
|
630
|
+
name: textOr(texts.names?.[endpoint], DEFAULT_ENDPOINT_NAME[endpoint]).slice(0, MAX_NAME_LENGTH),
|
|
631
|
+
position: at(0),
|
|
632
|
+
config
|
|
633
|
+
}, ...graph.steps.map(({ column, row, ...step })=>({
|
|
626
634
|
...step,
|
|
627
635
|
name: '',
|
|
628
|
-
position:
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
to
|
|
646
|
-
}));
|
|
636
|
+
position: at(column, row)
|
|
637
|
+
})));
|
|
638
|
+
edges.push(...[
|
|
639
|
+
[
|
|
640
|
+
endpoint,
|
|
641
|
+
'out',
|
|
642
|
+
graph.steps[0].id
|
|
643
|
+
],
|
|
644
|
+
...graph.edges
|
|
645
|
+
].map(([from, port, to])=>({
|
|
646
|
+
id: `e_${from}_${port}_${to}`,
|
|
647
|
+
from,
|
|
648
|
+
port,
|
|
649
|
+
to
|
|
650
|
+
})));
|
|
651
|
+
band += 1 + Math.max(0, ...graph.steps.map((step)=>step.row ?? 0));
|
|
652
|
+
}
|
|
647
653
|
return {
|
|
648
|
-
name:
|
|
649
|
-
slug: entityFlowSlug(entity.code
|
|
654
|
+
name: entity.label.slice(0, MAX_NAME_LENGTH),
|
|
655
|
+
slug: entityFlowSlug(entity.code),
|
|
650
656
|
isActive: true,
|
|
651
657
|
authMode: 'jwt',
|
|
652
658
|
runAs: 'caller',
|
|
653
|
-
isTransactional:
|
|
654
|
-
bodyType:
|
|
655
|
-
inputSchema:
|
|
659
|
+
isTransactional: endpoints.some((endpoint)=>!READ_ENDPOINTS.has(endpoint)),
|
|
660
|
+
bodyType: 'object',
|
|
661
|
+
inputSchema: [],
|
|
656
662
|
nodes,
|
|
657
663
|
edges
|
|
658
664
|
};
|
|
659
665
|
}
|
|
660
666
|
|
|
661
667
|
__webpack_require__.d(__webpack_exports__, {
|
|
662
|
-
|
|
663
|
-
|
|
668
|
+
CO: () => (buildEntityFlow)
|
|
669
|
+
}, {
|
|
670
|
+
IP: ENTITY_FLOW_PATHS,
|
|
671
|
+
x2: entityFlowSlug
|
|
664
672
|
});
|
|
665
673
|
|
|
666
674
|
|
|
@@ -3417,18 +3425,18 @@ class SchemaSyncService {
|
|
|
3417
3425
|
}
|
|
3418
3426
|
}
|
|
3419
3427
|
if (flowEndpoints.length) {
|
|
3420
|
-
const
|
|
3421
|
-
const
|
|
3428
|
+
const slug = (0,_entity_flow_scaffold_js__rspack_import_9/* .entityFlowSlug */.x2)(dto.code);
|
|
3429
|
+
const clash = await ctx.qr.manager.getRepository(_entities_flow_definition_entity_js__rspack_import_6/* .FlowDefinition */.G).findOne({
|
|
3422
3430
|
select: {
|
|
3423
3431
|
slug: true
|
|
3424
3432
|
},
|
|
3425
3433
|
where: {
|
|
3426
|
-
slug
|
|
3434
|
+
slug
|
|
3427
3435
|
},
|
|
3428
3436
|
withDeleted: true
|
|
3429
3437
|
});
|
|
3430
|
-
|
|
3431
|
-
slug
|
|
3438
|
+
if (clash) ctx.block((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_16/* .SCHEMA_BLOCKER_MESSAGES.FLOW_SLUG_TAKEN */.M3.FLOW_SLUG_TAKEN, {
|
|
3439
|
+
slug
|
|
3432
3440
|
}));
|
|
3433
3441
|
}
|
|
3434
3442
|
if (ctx.blocked) return {
|
|
@@ -3519,36 +3527,34 @@ class SchemaSyncService {
|
|
|
3519
3527
|
try {
|
|
3520
3528
|
await this.entityPermissionService.provisionForEntity(created.definition);
|
|
3521
3529
|
} finally{
|
|
3522
|
-
created.warnings.push(...await this.
|
|
3530
|
+
if (flowEndpoints.length) created.warnings.push(...await this.createEndpointFlow(dto, flowEndpoints, user));
|
|
3523
3531
|
}
|
|
3524
3532
|
}
|
|
3525
3533
|
};
|
|
3526
3534
|
};
|
|
3527
3535
|
}
|
|
3528
3536
|
/**
|
|
3529
|
-
*
|
|
3530
|
-
* validated like any other flow.
|
|
3531
|
-
*
|
|
3532
|
-
*/ async
|
|
3533
|
-
const
|
|
3537
|
+
* The entity's ready-made flow, one Request step per requested endpoint, saved through
|
|
3538
|
+
* FlowDefinitionService so it is validated like any other flow. The entity is already committed,
|
|
3539
|
+
* so a flow that cannot be saved is reported as a warning.
|
|
3540
|
+
*/ async createEndpointFlow(dto, endpoints, user) {
|
|
3541
|
+
const flow = (0,_entity_flow_scaffold_js__rspack_import_9/* .buildEntityFlow */.CO)({
|
|
3534
3542
|
code: dto.code,
|
|
3535
3543
|
label: dto.label,
|
|
3536
3544
|
fields: dto.fields ?? []
|
|
3537
|
-
};
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_16/* .SCHEMA_WARNING_MESSAGES.ENDPOINT_FLOW_FAILED */.Uu.ENDPOINT_FLOW_FAILED, {
|
|
3545
|
+
}, endpoints, dto.flowTexts);
|
|
3546
|
+
try {
|
|
3547
|
+
await this.flowDefinitionService.insert(flow, user);
|
|
3548
|
+
return [];
|
|
3549
|
+
} catch (error) {
|
|
3550
|
+
this.logger.error(`The flow '${flow.slug}' of entity '${dto.code}' could not be created: ${error.message}`);
|
|
3551
|
+
return [
|
|
3552
|
+
(0,_flusys_nestjs_shared_utils__rspack_import_1.messageRef)(_config_message_keys_js__rspack_import_16/* .SCHEMA_WARNING_MESSAGES.ENDPOINT_FLOW_FAILED */.Uu.ENDPOINT_FLOW_FAILED, {
|
|
3546
3553
|
slug: flow.slug,
|
|
3547
3554
|
detail: (0,_flow_engine_flow_errors_js__rspack_import_7/* .errorRef */.O$)(error)
|
|
3548
|
-
})
|
|
3549
|
-
|
|
3555
|
+
})
|
|
3556
|
+
];
|
|
3550
3557
|
}
|
|
3551
|
-
return warnings;
|
|
3552
3558
|
}
|
|
3553
3559
|
/** Preview of `createEntity`: the CREATE TABLE / CREATE INDEX statements, nothing is created. */ async planCreateEntity(dto, user) {
|
|
3554
3560
|
this.validateCreateRequest(dto);
|