@izara_project/izara-core-generate-service-code 1.0.86 → 1.0.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/compile/loadSchemas.js +45 -10
- package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +1 -1
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +22 -15
- package/src/emit/crud/crudActionPlan.js +47 -6
- package/src/emit/crud/emitCrudApplicationArtifacts.js +63 -3
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +6 -4
- package/src/emit/crud/templates/CreateAfterHookCallback_Main.ejs +121 -0
- package/src/emit/crud/templates/CreateBeforeHookCallback_Main.ejs +108 -0
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +138 -335
- package/src/emit/crud/templates/CreateLogicalLib.ejs +205 -42
- package/src/emit/crud/templates/CreateNodeCallback_Main.ejs +80 -0
- package/src/emit/crud/templates/DeleteBeforeHookCallback_Main.ejs +99 -0
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +153 -182
- package/src/emit/crud/templates/DeleteLogicalLib.ejs +132 -26
- package/src/emit/crud/templates/UpdateBeforeHookCallback_Main.ejs +112 -0
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +166 -188
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +2 -2
- package/src/emit/custom/customFlows.js +3 -1
- package/src/emit/function/functionYamlArtifact.js +4 -2
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +0 -3
- package/src/emit/rbac/emitRbacApplicationArtifacts.js +1 -116
- package/src/emit/rbac/templates/CancelUsage_Main.ejs +14 -10
- package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +14 -10
- package/src/emit/rbac/templates/CreateTargetRole_Main.ejs +22 -12
- package/src/emit/rbac/templates/GetMyPermissions_Main.ejs +14 -10
- package/src/emit/rbac/templates/ReservedDynamicUsage_Main.ejs +76 -34
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +12 -9
- package/src/emit/resource/emitResourceArtifacts.js +141 -62
- package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +14 -18
- package/src/emit/system/templates/WebSocketComplete_Yaml.ejs +4 -2
- package/test/createTargetRoleHandler.test.js +1 -15
- package/test/crudApplicationArtifacts.test.js +540 -3
- package/test/customFlowApplicationArtifacts.test.js +3 -5
- package/test/dynamicCrudFlowSchemas.test.js +5 -17
- package/test/dynamicRbacFlowSchemas.test.js +0 -3
- package/test/functionYamlArtifact.test.js +4 -2
- package/test/resourceArtifacts.test.js +203 -14
|
@@ -83,12 +83,14 @@ test('filters all SQS functions by their calling flow', () => {
|
|
|
83
83
|
/#<#CreateCompleteHdrSqsFilterPatterns#>[\s\S]*filterPatterns:[\s\S]*\$\{self:custom\.iz_resourcePrefix\}CreateCompleteHdrSqs/
|
|
84
84
|
);
|
|
85
85
|
assert.match(completion, /#<#\/CreateCompleteHdrSqsFilterPatterns#>/);
|
|
86
|
-
assert.match(completion, /exists: false/);
|
|
86
|
+
assert.match(completion, /callingFlow:\s*\n\s*- exists: false/);
|
|
87
|
+
assert.match(completion, /MessageAttributes:\s*\n\s*- exists: false/);
|
|
87
88
|
assert.match(
|
|
88
89
|
ordinary,
|
|
89
90
|
/#<#CreateHdrSqsFilterPatterns#>[\s\S]*filterPatterns:[\s\S]*\$\{self:custom\.iz_resourcePrefix\}CreateHdrSqs/
|
|
90
91
|
);
|
|
91
92
|
assert.match(ordinary, /#<#\/CreateHdrSqsFilterPatterns#>/);
|
|
92
|
-
assert.match(ordinary, /exists: false/);
|
|
93
|
+
assert.match(ordinary, /callingFlow:\s*\n\s*- exists: false/);
|
|
94
|
+
assert.match(ordinary, /MessageAttributes:\s*\n\s*- exists: false/);
|
|
93
95
|
});
|
|
94
96
|
|
|
@@ -76,10 +76,23 @@ test('emits queues, topics, tables, and IAM roles from schema data', async () =>
|
|
|
76
76
|
assert.match(dynamoYaml, /OrdersTable:/);
|
|
77
77
|
assert.match(dynamoYaml, /#<#OrdersTableSetting#>/);
|
|
78
78
|
assert.match(dynamoYaml, /#<#\/OrdersTableSetting#>/);
|
|
79
|
-
assert.match(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
assert.match(
|
|
80
|
+
dynamoYaml,
|
|
81
|
+
/RolesTable:\s+Type: 'AWS::DynamoDB::Table'[\s\S]+TableName: \${self:custom\.iz_resourcePrefix}Roles/
|
|
82
|
+
);
|
|
83
|
+
assert.match(
|
|
84
|
+
dynamoYaml,
|
|
85
|
+
/TargetRolesTable:\s+Type: 'AWS::DynamoDB::Table'[\s\S]+AttributeName: identifiersConcat/
|
|
86
|
+
);
|
|
87
|
+
assert.doesNotMatch(dynamoYaml, /RoleLimitTable:/);
|
|
88
|
+
assert.match(
|
|
89
|
+
dynamoYaml,
|
|
90
|
+
/RunningTotalUsageTable:\s+Type: 'AWS::DynamoDB::Table'[\s\S]+TableName: \${self:custom\.iz_resourcePrefix}RunningTotalUsage/
|
|
91
|
+
);
|
|
92
|
+
assert.match(
|
|
93
|
+
dynamoYaml,
|
|
94
|
+
/RunningTotalReservedUsageTable:\s+Type: 'AWS::DynamoDB::Table'[\s\S]+TableName: \${self:custom\.iz_resourcePrefix}RunningTotalReservedUsage/
|
|
95
|
+
);
|
|
83
96
|
const iam = await readFile(
|
|
84
97
|
join(
|
|
85
98
|
rootPath,
|
|
@@ -108,9 +121,9 @@ test('emits queues, topics, tables, and IAM roles from schema data', async () =>
|
|
|
108
121
|
roleBlock(iam, 'FlowRbacRole'),
|
|
109
122
|
/RolePermissions|ProcessCreateTargetRoleHdrSqs/
|
|
110
123
|
);
|
|
111
|
-
assert.
|
|
124
|
+
assert.doesNotMatch(roleBlock(iam, 'FlowRbacRole'), /RoleLimit/);
|
|
112
125
|
assert.match(roleBlock(iam, 'FlowRbacRole'), /RunningTotalUsage/);
|
|
113
|
-
assert.
|
|
126
|
+
assert.doesNotMatch(roleBlock(iam, 'FlowObjectsRole'), /RoleLimit/);
|
|
114
127
|
// Per-object RBAC flow queue (e.g. ValidatorRbacHdrSqs from Order with rbac add-on)
|
|
115
128
|
assert.match(roleBlock(iam, 'FlowRbacRole'), /ValidatorRbacHdrSqs/);
|
|
116
129
|
|
|
@@ -150,6 +163,7 @@ test('emits queues, topics, tables, and IAM roles from schema data', async () =>
|
|
|
150
163
|
const procFindDataRole = roleBlock(iam, 'ProcFindDataRole');
|
|
151
164
|
assert.match(procFindDataRole, /dynamodb:UpdateItem/);
|
|
152
165
|
assert.match(procFindDataRole, /dynamodb:GetItem/);
|
|
166
|
+
assert.match(procFindDataRole, /dynamodb:PutItem/);
|
|
153
167
|
assert.match(procFindDataRole, /dynamodb:Query/);
|
|
154
168
|
assert.match(procFindDataRole, /sns:Publish/);
|
|
155
169
|
assert.match(procFindDataRole, /FindData_Out/);
|
|
@@ -289,21 +303,21 @@ test('emits DynamoDB table with number sortKey attribute type when field type is
|
|
|
289
303
|
const rootPath = await createProject();
|
|
290
304
|
await writeFile(
|
|
291
305
|
join(rootPath, 'app/src/schemas/ObjectSchemas/CartOrder.js'),
|
|
292
|
-
|
|
306
|
+
'export default { ' +
|
|
293
307
|
"objectType: 'cartOrder', " +
|
|
294
308
|
"generatedBy: 'user', " +
|
|
295
|
-
|
|
309
|
+
'fieldNames: { ' +
|
|
296
310
|
" cartId: { type: 'string' }, " +
|
|
297
311
|
" sortId: { type: 'number' } " +
|
|
298
|
-
|
|
299
|
-
|
|
312
|
+
'}, ' +
|
|
313
|
+
'identifiers: [ ' +
|
|
300
314
|
" { type: 'partitionKey', fieldName: 'cartId' }, " +
|
|
301
315
|
" { type: 'sortKey', fieldName: 'sortId' } " +
|
|
302
|
-
|
|
303
|
-
|
|
316
|
+
'], ' +
|
|
317
|
+
'storageResources: { ' +
|
|
304
318
|
" main: { storageType: 'dynamoDB', tableName: 'CartOrders' } " +
|
|
305
|
-
|
|
306
|
-
|
|
319
|
+
'} ' +
|
|
320
|
+
'};\n'
|
|
307
321
|
);
|
|
308
322
|
|
|
309
323
|
await generateResourceArtifacts(rootPath);
|
|
@@ -370,6 +384,181 @@ test('emits CreateNodeCallbackHdrSqs in FlowObjectsRole when object has graph an
|
|
|
370
384
|
assert.match(role, /Rbac_\$\{self:custom\.iz_stage\}_ValidatorRbac_In/);
|
|
371
385
|
});
|
|
372
386
|
|
|
387
|
+
test('emits CreateAfterHookCallbackHdrSqs in SQS resources and FlowObjectsRole when flow has after hook with ownTopic', async () => {
|
|
388
|
+
const rootPath = await createProject();
|
|
389
|
+
const schemas = join(rootPath, 'app/src/schemas');
|
|
390
|
+
await writeFile(
|
|
391
|
+
join(schemas, 'FlowSchemas/NotifyAfterCreate.js'),
|
|
392
|
+
"export default { flowTag: 'notifyAfterCreate', event: ['ownTopic'], generatedCodeConfig: { generateCodeTag: 'create', codeHookTag: 'after', invocationType: 'ownTopic', objType: { objectType: 'order' } } };\n"
|
|
393
|
+
);
|
|
394
|
+
await generateResourceArtifacts(rootPath);
|
|
395
|
+
|
|
396
|
+
const crudResources = await readFile(
|
|
397
|
+
join(
|
|
398
|
+
rootPath,
|
|
399
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-crud.yml'
|
|
400
|
+
),
|
|
401
|
+
'utf8'
|
|
402
|
+
);
|
|
403
|
+
assert.match(crudResources, /^ CreateAfterHookCallbackHdrSqs:/m);
|
|
404
|
+
assert.match(crudResources, /^ CreateAfterHookCallbackHdrSqsDLQ:/m);
|
|
405
|
+
|
|
406
|
+
const iam = await readFile(
|
|
407
|
+
join(
|
|
408
|
+
rootPath,
|
|
409
|
+
'app/sls_yaml/generatedCode/source/generate-shared-resource.yml'
|
|
410
|
+
),
|
|
411
|
+
'utf8'
|
|
412
|
+
);
|
|
413
|
+
const role = roleBlock(iam, 'FlowObjectsRole');
|
|
414
|
+
assert.match(role, /CreateAfterHookCallbackHdrSqs/);
|
|
415
|
+
assert.match(role, /CreateAfterHookCallbackHdrSqsDLQ/);
|
|
416
|
+
assert.match(role, /NotifyAfterCreate_In/);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
test('emits CreateBeforeHookCallbackHdrSqs in SQS resources and FlowObjectsRole when flow has before hook with ownTopic', async () => {
|
|
420
|
+
const rootPath = await createProject();
|
|
421
|
+
const schemas = join(rootPath, 'app/src/schemas');
|
|
422
|
+
await writeFile(
|
|
423
|
+
join(schemas, 'FlowSchemas/ValidateBeforeCreate.js'),
|
|
424
|
+
"export default { flowTag: 'validateBeforeCreate', event: ['ownTopic'], generatedCodeConfig: { generateCodeTag: 'create', codeHookTag: 'before', invocationType: 'ownTopic' }, objType: { objectType: 'order' } };\n"
|
|
425
|
+
);
|
|
426
|
+
await generateResourceArtifacts(rootPath);
|
|
427
|
+
|
|
428
|
+
const crudResources = await readFile(
|
|
429
|
+
join(
|
|
430
|
+
rootPath,
|
|
431
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-crud.yml'
|
|
432
|
+
),
|
|
433
|
+
'utf8'
|
|
434
|
+
);
|
|
435
|
+
assert.match(crudResources, /^ CreateBeforeHookCallbackHdrSqs:/m);
|
|
436
|
+
assert.match(crudResources, /^ CreateBeforeHookCallbackHdrSqsDLQ:/m);
|
|
437
|
+
|
|
438
|
+
const iam = await readFile(
|
|
439
|
+
join(
|
|
440
|
+
rootPath,
|
|
441
|
+
'app/sls_yaml/generatedCode/source/generate-shared-resource.yml'
|
|
442
|
+
),
|
|
443
|
+
'utf8'
|
|
444
|
+
);
|
|
445
|
+
const role = roleBlock(iam, 'FlowObjectsRole');
|
|
446
|
+
assert.match(role, /CreateBeforeHookCallbackHdrSqs/);
|
|
447
|
+
assert.match(role, /CreateBeforeHookCallbackHdrSqsDLQ/);
|
|
448
|
+
assert.match(role, /ValidateBeforeCreate_In/);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
test('emits UpdateBeforeHookCallbackHdrSqs in SQS resources and FlowObjectsRole when flow has before hook with ownTopic', async () => {
|
|
452
|
+
const rootPath = await createProject();
|
|
453
|
+
const schemas = join(rootPath, 'app/src/schemas');
|
|
454
|
+
await writeFile(
|
|
455
|
+
join(schemas, 'FlowSchemas/ValidateBeforeUpdate.js'),
|
|
456
|
+
"export default { flowTag: 'validateBeforeUpdate', event: ['ownTopic'], generatedCodeConfig: { generateCodeTag: 'update', codeHookTag: 'before', invocationType: 'ownTopic' }, objType: { objectType: 'order' } };\n"
|
|
457
|
+
);
|
|
458
|
+
await generateResourceArtifacts(rootPath);
|
|
459
|
+
|
|
460
|
+
const crudResources = await readFile(
|
|
461
|
+
join(
|
|
462
|
+
rootPath,
|
|
463
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-crud.yml'
|
|
464
|
+
),
|
|
465
|
+
'utf8'
|
|
466
|
+
);
|
|
467
|
+
assert.match(crudResources, /^ UpdateBeforeHookCallbackHdrSqs:/m);
|
|
468
|
+
assert.match(crudResources, /^ UpdateBeforeHookCallbackHdrSqsDLQ:/m);
|
|
469
|
+
|
|
470
|
+
const iam = await readFile(
|
|
471
|
+
join(
|
|
472
|
+
rootPath,
|
|
473
|
+
'app/sls_yaml/generatedCode/source/generate-shared-resource.yml'
|
|
474
|
+
),
|
|
475
|
+
'utf8'
|
|
476
|
+
);
|
|
477
|
+
const role = roleBlock(iam, 'FlowObjectsRole');
|
|
478
|
+
assert.match(role, /UpdateBeforeHookCallbackHdrSqs/);
|
|
479
|
+
assert.match(role, /UpdateBeforeHookCallbackHdrSqsDLQ/);
|
|
480
|
+
assert.match(role, /ValidateBeforeUpdate_In/);
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
test('emits DeleteBeforeHookCallbackHdrSqs in SQS resources and FlowObjectsRole when flow has before hook with ownTopic', async () => {
|
|
484
|
+
const rootPath = await createProject();
|
|
485
|
+
const schemas = join(rootPath, 'app/src/schemas');
|
|
486
|
+
await writeFile(
|
|
487
|
+
join(schemas, 'FlowSchemas/ValidateBeforeDelete.js'),
|
|
488
|
+
"export default { flowTag: 'validateBeforeDelete', event: ['ownTopic'], generatedCodeConfig: { generateCodeTag: 'delete', codeHookTag: 'before', invocationType: 'ownTopic' }, objType: { objectType: 'order' } };\n"
|
|
489
|
+
);
|
|
490
|
+
await generateResourceArtifacts(rootPath);
|
|
491
|
+
|
|
492
|
+
const crudResources = await readFile(
|
|
493
|
+
join(
|
|
494
|
+
rootPath,
|
|
495
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-crud.yml'
|
|
496
|
+
),
|
|
497
|
+
'utf8'
|
|
498
|
+
);
|
|
499
|
+
assert.match(crudResources, /^ DeleteBeforeHookCallbackHdrSqs:/m);
|
|
500
|
+
assert.match(crudResources, /^ DeleteBeforeHookCallbackHdrSqsDLQ:/m);
|
|
501
|
+
|
|
502
|
+
const iam = await readFile(
|
|
503
|
+
join(
|
|
504
|
+
rootPath,
|
|
505
|
+
'app/sls_yaml/generatedCode/source/generate-shared-resource.yml'
|
|
506
|
+
),
|
|
507
|
+
'utf8'
|
|
508
|
+
);
|
|
509
|
+
const role = roleBlock(iam, 'FlowObjectsRole');
|
|
510
|
+
assert.match(role, /DeleteBeforeHookCallbackHdrSqs/);
|
|
511
|
+
assert.match(role, /DeleteBeforeHookCallbackHdrSqsDLQ/);
|
|
512
|
+
assert.match(role, /ValidateBeforeDelete_In/);
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
test('emits lambda:InvokeFunction in FlowObjectsRole when flow has before hook with lambdaSyncInv for update and delete', async () => {
|
|
516
|
+
const rootPath = await createProject();
|
|
517
|
+
const schemas = join(rootPath, 'app/src/schemas');
|
|
518
|
+
await writeFile(
|
|
519
|
+
join(schemas, 'FlowSchemas/CheckBeforeUpdate.js'),
|
|
520
|
+
"export default { flowTag: 'checkBeforeUpdate', event: ['lambdaSyncInv'], generatedCodeConfig: { generateCodeTag: 'update', codeHookTag: 'before', invocationType: 'lambdaSyncInv' }, objType: { objectType: 'order' } };\n"
|
|
521
|
+
);
|
|
522
|
+
await writeFile(
|
|
523
|
+
join(schemas, 'FlowSchemas/CheckBeforeDelete.js'),
|
|
524
|
+
"export default { flowTag: 'checkBeforeDelete', event: ['lambdaSyncInv'], generatedCodeConfig: { generateCodeTag: 'delete', codeHookTag: 'before', invocationType: 'lambdaSyncInv' }, objType: { objectType: 'order' } };\n"
|
|
525
|
+
);
|
|
526
|
+
await generateResourceArtifacts(rootPath);
|
|
527
|
+
|
|
528
|
+
const iam = await readFile(
|
|
529
|
+
join(
|
|
530
|
+
rootPath,
|
|
531
|
+
'app/sls_yaml/generatedCode/source/generate-shared-resource.yml'
|
|
532
|
+
),
|
|
533
|
+
'utf8'
|
|
534
|
+
);
|
|
535
|
+
const role = roleBlock(iam, 'FlowObjectsRole');
|
|
536
|
+
assert.match(role, /lambda:InvokeFunction/);
|
|
537
|
+
assert.match(role, /CheckBeforeUpdate/);
|
|
538
|
+
assert.match(role, /CheckBeforeDelete/);
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
test('emits lambda:InvokeFunction in FlowObjectsRole when flow has after hook with lambdaSyncInv', async () => {
|
|
542
|
+
const rootPath = await createProject();
|
|
543
|
+
const schemas = join(rootPath, 'app/src/schemas');
|
|
544
|
+
await writeFile(
|
|
545
|
+
join(schemas, 'FlowSchemas/AuditAfterCreate.js'),
|
|
546
|
+
"export default { flowTag: 'auditAfterCreate', event: ['lambdaSyncInv'], generatedCodeConfig: { generateCodeTag: 'create', codeHookTag: 'after', invocationType: 'lambdaSyncInv', objType: { objectType: 'order' } } };\n"
|
|
547
|
+
);
|
|
548
|
+
await generateResourceArtifacts(rootPath);
|
|
549
|
+
|
|
550
|
+
const iam = await readFile(
|
|
551
|
+
join(
|
|
552
|
+
rootPath,
|
|
553
|
+
'app/sls_yaml/generatedCode/source/generate-shared-resource.yml'
|
|
554
|
+
),
|
|
555
|
+
'utf8'
|
|
556
|
+
);
|
|
557
|
+
const role = roleBlock(iam, 'FlowObjectsRole');
|
|
558
|
+
assert.match(role, /lambda:InvokeFunction/);
|
|
559
|
+
assert.match(role, /AuditAfterCreate/);
|
|
560
|
+
});
|
|
561
|
+
|
|
373
562
|
function roleBlock(iam, roleName) {
|
|
374
563
|
const match = iam.match(
|
|
375
564
|
new RegExp(
|