@izara_project/izara-core-generate-service-code 1.0.87 → 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/crud/crudActionPlan.js +46 -5
- package/src/emit/crud/emitCrudApplicationArtifacts.js +63 -3
- 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 +126 -332
- package/src/emit/crud/templates/CreateLogicalLib.ejs +120 -22
- 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 +141 -179
- 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 +154 -185
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +2 -2
- package/src/emit/custom/customFlows.js +3 -1
- package/src/emit/resource/emitResourceArtifacts.js +110 -57
- package/test/crudApplicationArtifacts.test.js +531 -0
- package/test/resourceArtifacts.test.js +200 -12
|
@@ -76,11 +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
|
-
|
|
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
|
+
);
|
|
81
87
|
assert.doesNotMatch(dynamoYaml, /RoleLimitTable:/);
|
|
82
|
-
assert.match(
|
|
83
|
-
|
|
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
|
+
);
|
|
84
96
|
const iam = await readFile(
|
|
85
97
|
join(
|
|
86
98
|
rootPath,
|
|
@@ -151,6 +163,7 @@ test('emits queues, topics, tables, and IAM roles from schema data', async () =>
|
|
|
151
163
|
const procFindDataRole = roleBlock(iam, 'ProcFindDataRole');
|
|
152
164
|
assert.match(procFindDataRole, /dynamodb:UpdateItem/);
|
|
153
165
|
assert.match(procFindDataRole, /dynamodb:GetItem/);
|
|
166
|
+
assert.match(procFindDataRole, /dynamodb:PutItem/);
|
|
154
167
|
assert.match(procFindDataRole, /dynamodb:Query/);
|
|
155
168
|
assert.match(procFindDataRole, /sns:Publish/);
|
|
156
169
|
assert.match(procFindDataRole, /FindData_Out/);
|
|
@@ -290,21 +303,21 @@ test('emits DynamoDB table with number sortKey attribute type when field type is
|
|
|
290
303
|
const rootPath = await createProject();
|
|
291
304
|
await writeFile(
|
|
292
305
|
join(rootPath, 'app/src/schemas/ObjectSchemas/CartOrder.js'),
|
|
293
|
-
|
|
306
|
+
'export default { ' +
|
|
294
307
|
"objectType: 'cartOrder', " +
|
|
295
308
|
"generatedBy: 'user', " +
|
|
296
|
-
|
|
309
|
+
'fieldNames: { ' +
|
|
297
310
|
" cartId: { type: 'string' }, " +
|
|
298
311
|
" sortId: { type: 'number' } " +
|
|
299
|
-
|
|
300
|
-
|
|
312
|
+
'}, ' +
|
|
313
|
+
'identifiers: [ ' +
|
|
301
314
|
" { type: 'partitionKey', fieldName: 'cartId' }, " +
|
|
302
315
|
" { type: 'sortKey', fieldName: 'sortId' } " +
|
|
303
|
-
|
|
304
|
-
|
|
316
|
+
'], ' +
|
|
317
|
+
'storageResources: { ' +
|
|
305
318
|
" main: { storageType: 'dynamoDB', tableName: 'CartOrders' } " +
|
|
306
|
-
|
|
307
|
-
|
|
319
|
+
'} ' +
|
|
320
|
+
'};\n'
|
|
308
321
|
);
|
|
309
322
|
|
|
310
323
|
await generateResourceArtifacts(rootPath);
|
|
@@ -371,6 +384,181 @@ test('emits CreateNodeCallbackHdrSqs in FlowObjectsRole when object has graph an
|
|
|
371
384
|
assert.match(role, /Rbac_\$\{self:custom\.iz_stage\}_ValidatorRbac_In/);
|
|
372
385
|
});
|
|
373
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
|
+
|
|
374
562
|
function roleBlock(iam, roleName) {
|
|
375
563
|
const match = iam.match(
|
|
376
564
|
new RegExp(
|