@izara_project/izara-core-generate-service-code 1.0.83 → 1.0.84
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 +4 -4
- package/src/compile/flowValidator.js +13 -2
- package/src/compile/loadSchemas.js +116 -7
- package/src/emit/attributeTree/emitAttributeTreeSchemas.js +388 -0
- package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +29 -1
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +16 -3
- package/src/emit/crud/crudActionPlan.js +38 -5
- package/src/emit/crud/emitCrudApplicationArtifacts.js +19 -4
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +27 -6
- package/src/emit/crud/generateCrudApplicationArtifacts.js +3 -2
- package/src/emit/crud/generateDynamicCrudFlowSchemas.js +3 -2
- package/src/emit/crud/loadLocalSchemaArrays.js +3 -3
- package/src/emit/crud/templates/CreateComplete_Main.ejs +1 -1
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +50 -19
- package/src/emit/crud/templates/CreateLogicalLib.ejs +73 -8
- package/src/emit/crud/templates/DeleteComplete_Main.ejs +1 -1
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +33 -8
- package/src/emit/crud/templates/DeleteLogicalLib.ejs +6 -3
- package/src/emit/crud/templates/FlowEndpointRbacCallback_Main.ejs +2 -2
- package/src/emit/crud/templates/FlowEndpoint_HdrWbs.ejs +7 -0
- package/src/emit/crud/templates/FlowMain_Wbs.ejs +1 -1
- package/src/emit/crud/templates/GetEndpoint_Main.ejs +13 -0
- package/src/emit/crud/templates/UpdateComplete_Main.ejs +1 -1
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +52 -3
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +4 -3
- package/src/emit/custom/customFlows.js +47 -0
- package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +168 -49
- package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +1 -1
- package/src/emit/custom/templates/FlowEndpointRbacCallback_Main.ejs +194 -0
- package/src/emit/custom/templates/FlowEndpoint_Main.ejs +14 -22
- package/src/emit/custom/templates/FlowStep_Main.ejs +1 -1
- package/src/emit/function/templates/WbsFunction_Yaml.ejs +0 -2
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +33 -8
- package/src/emit/rbac/emitRbacApplicationArtifacts.js +204 -7
- package/src/emit/rbac/templates/CancelUsage_Main.ejs +103 -0
- package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +71 -0
- package/src/emit/rbac/templates/CreateTargetRole_Main.ejs +49 -6
- package/src/emit/rbac/templates/ListRbac_Main.ejs +9 -3
- package/src/emit/rbac/templates/RbacMutation_Main.ejs +1 -1
- package/src/emit/rbac/templates/ReservedDynamicUsage_Main.ejs +147 -0
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +59 -23
- package/src/emit/rbac/templates/UserRoleMutation_Main.ejs +1 -1
- package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +1 -1
- package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +4 -4
- package/src/emit/resource/emitResourceArtifacts.js +342 -108
- package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +53 -2
- package/src/emit/system/emitSystemWebSocketArtifacts.js +6 -5
- package/src/emit/system/templates/WebSocketConnect.ejs +71 -12
- package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +7 -0
- package/src/emit/systemText/emitSystemTextSchemas.js +1 -1
- package/src/generate.js +41 -10
- package/test/attributeTreeSchemas.test.js +219 -0
- package/test/createTargetRoleHandler.test.js +59 -4
- package/test/crudApplicationArtifacts.test.js +20 -3
- package/test/customFlowApplicationArtifacts.test.js +5 -5
- package/test/dynamicCrudFlowSchemas.test.js +91 -4
- package/test/dynamicRbacFlowSchemas.test.js +15 -2
- package/test/publicApi.test.js +6 -6
- package/test/resourceArtifacts.test.js +68 -27
|
@@ -340,7 +340,7 @@ test('emits and removes ext-topic handlers declared by custom flow steps', async
|
|
|
340
340
|
await readFile(
|
|
341
341
|
join(
|
|
342
342
|
rootPath,
|
|
343
|
-
'resource/sls_yaml/generatedCode/source/generated-sns-
|
|
343
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-custom-flows.yml'
|
|
344
344
|
),
|
|
345
345
|
'utf8'
|
|
346
346
|
),
|
|
@@ -350,7 +350,7 @@ test('emits and removes ext-topic handlers declared by custom flow steps', async
|
|
|
350
350
|
await readFile(
|
|
351
351
|
join(
|
|
352
352
|
rootPath,
|
|
353
|
-
'resource/sls_yaml/generatedCode/source/generated-sns-
|
|
353
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-custom-flows.yml'
|
|
354
354
|
),
|
|
355
355
|
'utf8'
|
|
356
356
|
),
|
|
@@ -398,7 +398,7 @@ test('emits and removes ext-topic handlers declared by custom flow steps', async
|
|
|
398
398
|
await readFile(
|
|
399
399
|
join(
|
|
400
400
|
rootPath,
|
|
401
|
-
'resource/sls_yaml/generatedCode/source/generated-sns-
|
|
401
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-custom-flows.yml'
|
|
402
402
|
),
|
|
403
403
|
'utf8'
|
|
404
404
|
),
|
|
@@ -437,7 +437,7 @@ test('emits and removes the trigger-cache artifact suite when triggerFlowTypes i
|
|
|
437
437
|
const resources = await readFile(
|
|
438
438
|
join(
|
|
439
439
|
rootPath,
|
|
440
|
-
'resource/sls_yaml/generatedCode/source/generated-sns-
|
|
440
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-custom-flows.yml'
|
|
441
441
|
),
|
|
442
442
|
'utf8'
|
|
443
443
|
);
|
|
@@ -864,7 +864,7 @@ test('registers SQS queue, SNS subscription, and SNS out topic for custom flowSc
|
|
|
864
864
|
const snsInSqs = await readFile(
|
|
865
865
|
join(
|
|
866
866
|
rootPath,
|
|
867
|
-
'resource/sls_yaml/generatedCode/source/generated-sns-
|
|
867
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-custom-flows.yml'
|
|
868
868
|
),
|
|
869
869
|
'utf8'
|
|
870
870
|
);
|
|
@@ -6,6 +6,7 @@ import test from 'node:test';
|
|
|
6
6
|
import { pathToFileURL } from 'node:url';
|
|
7
7
|
|
|
8
8
|
import { generateDynamicCrudFlowSchemas } from '../src/emit/crud/generateDynamicCrudFlowSchemas.js';
|
|
9
|
+
import { createCrudActionPlans } from '../src/emit/crud/crudActionPlan.js';
|
|
9
10
|
|
|
10
11
|
test('generates dynamic CRUD schemas from local schema modules', async () => {
|
|
11
12
|
const rootPath = await createProject({
|
|
@@ -141,7 +142,7 @@ test('generates a direct Complete step for RBAC-only Update flows', async () =>
|
|
|
141
142
|
assert.equal(update.flowSteps[1].properties.length, 0);
|
|
142
143
|
});
|
|
143
144
|
|
|
144
|
-
test('
|
|
145
|
+
test('generates RbacCallback and Complete for Create when RBAC and Graph are present', async () => {
|
|
145
146
|
const rootPath = await createProject({
|
|
146
147
|
generatedBy: 'user',
|
|
147
148
|
});
|
|
@@ -159,6 +160,7 @@ test('ignores RBAC for Create even when Graph storage is present', async () => {
|
|
|
159
160
|
const create = await readGeneratedFlow(rootPath, 'Create');
|
|
160
161
|
assert.deepEqual(create.flowSteps.map((step) => step.stepName), [
|
|
161
162
|
'Start',
|
|
163
|
+
'RbacCallback',
|
|
162
164
|
'Complete'
|
|
163
165
|
]);
|
|
164
166
|
});
|
|
@@ -183,9 +185,10 @@ test('uses the renamed RBAC callback step when Graph storage is present', async
|
|
|
183
185
|
const create = await readGeneratedFlow(rootPath, 'Create');
|
|
184
186
|
assert.deepEqual(create.flowSteps.map((step) => step.stepName), [
|
|
185
187
|
'Start',
|
|
188
|
+
'RbacCallback',
|
|
186
189
|
'Complete'
|
|
187
190
|
]);
|
|
188
|
-
assert.deepEqual(create.flowSteps[
|
|
191
|
+
assert.deepEqual(create.flowSteps[2].properties, [
|
|
189
192
|
'returnValue',
|
|
190
193
|
'parentFlowId',
|
|
191
194
|
'status',
|
|
@@ -258,6 +261,57 @@ test('omits Complete step when no graph storage resources exist', async () => {
|
|
|
258
261
|
assert.equal(create.flowSteps[0].nextSteps, undefined);
|
|
259
262
|
});
|
|
260
263
|
|
|
264
|
+
test('evaluates hasQuotaReservation based on billable flag in belongTo and addOnDataStructure', () => {
|
|
265
|
+
const billableObj = {
|
|
266
|
+
objectType: 'unitType',
|
|
267
|
+
generatedBy: 'user',
|
|
268
|
+
addOnDataStructure: [{ type: 'rbac', billable: true }]
|
|
269
|
+
};
|
|
270
|
+
const plans1 = createCrudActionPlans([billableObj]);
|
|
271
|
+
assert.equal(plans1.Create.hasQuotaReservation, true);
|
|
272
|
+
|
|
273
|
+
const nonBillableObj1 = {
|
|
274
|
+
objectType: 'internalTag',
|
|
275
|
+
generatedBy: 'user',
|
|
276
|
+
addOnDataStructure: [{ type: 'rbac', billable: false }]
|
|
277
|
+
};
|
|
278
|
+
const plans2 = createCrudActionPlans([nonBillableObj1]);
|
|
279
|
+
assert.equal(plans2.Create.hasQuotaReservation, false);
|
|
280
|
+
|
|
281
|
+
const nonBillableObj2 = {
|
|
282
|
+
objectType: 'deliveryMethod',
|
|
283
|
+
generatedBy: 'user',
|
|
284
|
+
belongTo: {
|
|
285
|
+
objectType: 'supplyNetwork',
|
|
286
|
+
serviceTag: 'SupplyNetwork',
|
|
287
|
+
billable: false
|
|
288
|
+
},
|
|
289
|
+
belongToSchema: {
|
|
290
|
+
objectType: 'supplyNetwork',
|
|
291
|
+
addOnDataStructure: [{ type: 'rbac' }]
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
const plans3 = createCrudActionPlans([nonBillableObj2]);
|
|
295
|
+
assert.equal(plans3.Create.hasQuotaReservation, false);
|
|
296
|
+
assert.equal(plans3.Update.hasRbac, true);
|
|
297
|
+
|
|
298
|
+
const billableObj2 = {
|
|
299
|
+
objectType: 'unitType',
|
|
300
|
+
generatedBy: 'user',
|
|
301
|
+
belongTo: {
|
|
302
|
+
objectType: 'supplyNetwork',
|
|
303
|
+
serviceTag: 'SupplyNetwork',
|
|
304
|
+
billable: true
|
|
305
|
+
},
|
|
306
|
+
belongToSchema: {
|
|
307
|
+
objectType: 'supplyNetwork',
|
|
308
|
+
addOnDataStructure: [{ type: 'rbac' }]
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
const plans4 = createCrudActionPlans([billableObj2]);
|
|
312
|
+
assert.equal(plans4.Create.hasQuotaReservation, true);
|
|
313
|
+
});
|
|
314
|
+
|
|
261
315
|
async function createProject({ generatedBy, flow, singletonExports = false }) {
|
|
262
316
|
const rootPath = await mkdtemp(
|
|
263
317
|
join(tmpdir(), 'generate-service-code-v2-crud-')
|
|
@@ -319,8 +373,8 @@ function readGeneratedFile(rootPath, action) {
|
|
|
319
373
|
);
|
|
320
374
|
}
|
|
321
375
|
|
|
322
|
-
test('supports
|
|
323
|
-
for (const generatedBy of ['user', 'systemWithUser', '
|
|
376
|
+
test('supports standard generatedBy values (user, systemWithUser, systemNoUser)', async () => {
|
|
377
|
+
for (const generatedBy of ['user', 'systemWithUser', 'systemNoUser']) {
|
|
324
378
|
const rootPath = await createProject({ generatedBy });
|
|
325
379
|
await generateDynamicCrudFlowSchemas(rootPath);
|
|
326
380
|
const create = await readGeneratedFlow(rootPath, 'Create');
|
|
@@ -328,3 +382,36 @@ test('supports new standard generatedBy values (user, systemWithUser, systemWith
|
|
|
328
382
|
assert.deepEqual(create.flowSteps.map((s) => s.stepName), ['Start', 'Complete']);
|
|
329
383
|
}
|
|
330
384
|
});
|
|
385
|
+
|
|
386
|
+
test('logs warning when ObjectSchema has invalid or non-CRUD generatedBy', async () => {
|
|
387
|
+
const rootPath = await createProject({ generatedBy: 'user' });
|
|
388
|
+
await writeFile(
|
|
389
|
+
join(rootPath, 'app/src/schemas/ObjectSchemas/Order.js'),
|
|
390
|
+
"export default [{ objectType: 'order', generatedBy: 'invalidGeneratedBy' }];\n"
|
|
391
|
+
);
|
|
392
|
+
|
|
393
|
+
const warnings = [];
|
|
394
|
+
const logger = {
|
|
395
|
+
warn: (msg) => warnings.push(msg)
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
const result = await generateDynamicCrudFlowSchemas(rootPath, { logger });
|
|
399
|
+
assert.deepEqual(result.files, []);
|
|
400
|
+
assert.equal(warnings.length, 1);
|
|
401
|
+
assert.match(warnings[0], /\[WARN\] \[CRUD FlowSchemas\] Skipped FlowObjects FlowSchemas generation/);
|
|
402
|
+
assert.match(warnings[0], /invalidGeneratedBy/);
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
test('throws error when ObjectSchema validation fails with validateSchemas: true', async () => {
|
|
406
|
+
const rootPath = await createProject({ generatedBy: 'user' });
|
|
407
|
+
await writeFile(
|
|
408
|
+
join(rootPath, 'app/src/schemas/ObjectSchemas/Order.js'),
|
|
409
|
+
"export default [{ objectType: 'order', fieldNames: {}, identifiers: [] }];\n"
|
|
410
|
+
);
|
|
411
|
+
|
|
412
|
+
await assert.rejects(
|
|
413
|
+
generateDynamicCrudFlowSchemas(rootPath, { validateSchemas: true }),
|
|
414
|
+
/\[SCHEMA_VALIDATION_ERROR\] Schema validation failed for ObjectSchemas\/Order\.js/
|
|
415
|
+
);
|
|
416
|
+
});
|
|
417
|
+
|
|
@@ -8,7 +8,7 @@ import { pathToFileURL } from 'node:url';
|
|
|
8
8
|
import { generateDynamicRbacFlowSchemas } from '../src/emit/rbac/generateDynamicRbacFlowSchemas.js';
|
|
9
9
|
|
|
10
10
|
const projectRoots = new Set();
|
|
11
|
-
const
|
|
11
|
+
const STATIC_RBAC_ACTIONS = [
|
|
12
12
|
'CreateTargetRole',
|
|
13
13
|
'ListTargetRole',
|
|
14
14
|
'DeleteTargetRole',
|
|
@@ -20,6 +20,15 @@ const STATIC_ACTIONS = [
|
|
|
20
20
|
'DeleteUserFromRole'
|
|
21
21
|
];
|
|
22
22
|
|
|
23
|
+
const STATIC_LIMIT_ACTIONS = [
|
|
24
|
+
'CreateRoleLimit',
|
|
25
|
+
'ListRoleLimits',
|
|
26
|
+
'DeleteRoleLimit',
|
|
27
|
+
'ReservedDynamicUsage',
|
|
28
|
+
'ConfirmUsage',
|
|
29
|
+
'CancelUsage'
|
|
30
|
+
];
|
|
31
|
+
|
|
23
32
|
after(async () => {
|
|
24
33
|
await Promise.all(
|
|
25
34
|
[...projectRoots].map((rootPath) =>
|
|
@@ -38,10 +47,14 @@ test('generates shared and object-specific RBAC flow schemas', async () => {
|
|
|
38
47
|
assert.deepEqual(
|
|
39
48
|
result.files.map((file) => file.path),
|
|
40
49
|
[
|
|
41
|
-
...
|
|
50
|
+
...STATIC_RBAC_ACTIONS.map(
|
|
42
51
|
(action) =>
|
|
43
52
|
`app/src/schemas/FlowSchemas/generateCode/FlowRbac/${action}.js`
|
|
44
53
|
),
|
|
54
|
+
...STATIC_LIMIT_ACTIONS.map(
|
|
55
|
+
(action) =>
|
|
56
|
+
`app/src/schemas/FlowSchemas/generateCode/FlowLimit/${action}.js`
|
|
57
|
+
),
|
|
45
58
|
'app/src/schemas/FlowSchemas/generateCode/FlowRbac/ValidatorRbac.js'
|
|
46
59
|
]
|
|
47
60
|
);
|
package/test/publicApi.test.js
CHANGED
|
@@ -23,7 +23,7 @@ test('generate commits schemas, application artifacts, and resources in one publ
|
|
|
23
23
|
const rootPath = await createCrudProject();
|
|
24
24
|
const result = await generate(rootPath);
|
|
25
25
|
|
|
26
|
-
assert.strictEqual(result.files.length,
|
|
26
|
+
assert.strictEqual(result.files.length, 74);
|
|
27
27
|
assert.equal(result.project.rootPath, rootPath);
|
|
28
28
|
assert.match(
|
|
29
29
|
await readFile(
|
|
@@ -155,7 +155,7 @@ test('generate commits the system WebSocket completion path for own-topic flows'
|
|
|
155
155
|
await readFile(
|
|
156
156
|
join(
|
|
157
157
|
rootPath,
|
|
158
|
-
'resource/sls_yaml/generatedCode/source/generated-sns-
|
|
158
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-system.yml'
|
|
159
159
|
),
|
|
160
160
|
'utf8'
|
|
161
161
|
),
|
|
@@ -165,7 +165,7 @@ test('generate commits the system WebSocket completion path for own-topic flows'
|
|
|
165
165
|
await readFile(
|
|
166
166
|
join(
|
|
167
167
|
rootPath,
|
|
168
|
-
'resource/sls_yaml/generatedCode/source/generated-sns-
|
|
168
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-system.yml'
|
|
169
169
|
),
|
|
170
170
|
'utf8'
|
|
171
171
|
),
|
|
@@ -235,7 +235,7 @@ test('generate commits the trigger-cache suite with its queues when triggerFlowT
|
|
|
235
235
|
await readFile(
|
|
236
236
|
join(
|
|
237
237
|
rootPath,
|
|
238
|
-
'resource/sls_yaml/generatedCode/source/generated-sns-
|
|
238
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-custom-flows.yml'
|
|
239
239
|
),
|
|
240
240
|
'utf8'
|
|
241
241
|
),
|
|
@@ -273,7 +273,7 @@ test('generate removes the system WebSocket path when the last own-topic flow is
|
|
|
273
273
|
await readFile(
|
|
274
274
|
join(
|
|
275
275
|
rootPath,
|
|
276
|
-
'resource/sls_yaml/generatedCode/source/generated-sns-
|
|
276
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-system.yml'
|
|
277
277
|
),
|
|
278
278
|
'utf8'
|
|
279
279
|
),
|
|
@@ -309,7 +309,7 @@ test('generate removes stale CRUD schemas and application artifacts', async () =
|
|
|
309
309
|
|
|
310
310
|
const result = await generate(rootPath);
|
|
311
311
|
|
|
312
|
-
assert.equal(result.files.length,
|
|
312
|
+
assert.equal(result.files.length, 38);
|
|
313
313
|
await assert.rejects(
|
|
314
314
|
readFile(
|
|
315
315
|
join(
|
|
@@ -19,28 +19,52 @@ test('emits queues, topics, tables, and IAM roles from schema data', async () =>
|
|
|
19
19
|
const rootPath = await createProject();
|
|
20
20
|
const result = await generateResourceArtifacts(rootPath);
|
|
21
21
|
|
|
22
|
-
assert.equal(result.files.length,
|
|
23
|
-
const
|
|
22
|
+
assert.equal(result.files.length, 10);
|
|
23
|
+
const crudResources = await readFile(
|
|
24
24
|
join(
|
|
25
25
|
rootPath,
|
|
26
|
-
'resource/sls_yaml/generatedCode/source/generated-sns-
|
|
26
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-crud.yml'
|
|
27
27
|
),
|
|
28
28
|
'utf8'
|
|
29
29
|
);
|
|
30
|
-
assert.match(
|
|
31
|
-
assert.match(
|
|
30
|
+
assert.match(crudResources, /InCreate:/);
|
|
31
|
+
assert.match(crudResources, /^ CreateCompleteHdrSqs:/m);
|
|
32
|
+
assert.match(crudResources, /^ UpdateCompleteHdrSqs:/m);
|
|
33
|
+
assert.match(crudResources, /^ DeleteCompleteHdrSqs:/m);
|
|
34
|
+
assert.doesNotMatch(crudResources, /RbacCallbackHdrSqs/);
|
|
35
|
+
assert.doesNotMatch(crudResources, /FlowHook|beforeLogical/);
|
|
36
|
+
|
|
37
|
+
const customResources = await readFile(
|
|
38
|
+
join(
|
|
39
|
+
rootPath,
|
|
40
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-custom-flows.yml'
|
|
41
|
+
),
|
|
42
|
+
'utf8'
|
|
43
|
+
);
|
|
44
|
+
assert.match(
|
|
45
|
+
customResources,
|
|
46
|
+
/SubscriptionOutCreateToUploadReservedLimitHdrSqs:/
|
|
47
|
+
);
|
|
48
|
+
assert.match(customResources, /TopicArn: !Ref OutCreate/);
|
|
32
49
|
assert.match(
|
|
33
|
-
|
|
50
|
+
customResources,
|
|
34
51
|
/Endpoint: 'arn:aws:sqs:\${self:custom\.iz_region}:\${self:custom\.iz_accountId}:\${self:custom\.iz_resourcePrefix}UploadReservedLimitHdrSqs'/
|
|
35
52
|
);
|
|
36
|
-
|
|
53
|
+
|
|
54
|
+
const systemResources = await readFile(
|
|
55
|
+
join(
|
|
56
|
+
rootPath,
|
|
57
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-system.yml'
|
|
58
|
+
),
|
|
59
|
+
'utf8'
|
|
60
|
+
);
|
|
37
61
|
for (const queueName of [
|
|
38
62
|
'FindDataHdrSqs',
|
|
39
63
|
'ProcessLogicalHdrSqs',
|
|
40
64
|
'PaginateProcessLogicalHdrDsq',
|
|
41
65
|
'PaginateProcessLogicalHdrSqs'
|
|
42
66
|
]) {
|
|
43
|
-
assert.match(
|
|
67
|
+
assert.match(systemResources, new RegExp(`^ ${queueName}:`, 'm'));
|
|
44
68
|
}
|
|
45
69
|
const dynamoYaml = await readFile(
|
|
46
70
|
join(
|
|
@@ -52,6 +76,10 @@ test('emits queues, topics, tables, and IAM roles from schema data', async () =>
|
|
|
52
76
|
assert.match(dynamoYaml, /OrdersTable:/);
|
|
53
77
|
assert.match(dynamoYaml, /#<#OrdersTableSetting#>/);
|
|
54
78
|
assert.match(dynamoYaml, /#<#\/OrdersTableSetting#>/);
|
|
79
|
+
assert.match(dynamoYaml, /TargetRolesTable:\s+Type: 'AWS::DynamoDB::Table'[\s\S]+AttributeName: identifiersConcat/);
|
|
80
|
+
assert.match(dynamoYaml, /RoleLimitTable:\s+Type: 'AWS::DynamoDB::Table'[\s\S]+TableName: \${self:custom\.iz_resourcePrefix}RoleLimit/);
|
|
81
|
+
assert.match(dynamoYaml, /RunningTotalUsageTable:\s+Type: 'AWS::DynamoDB::Table'[\s\S]+TableName: \${self:custom\.iz_resourcePrefix}RunningTotalUsage/);
|
|
82
|
+
assert.match(dynamoYaml, /RunningTotalReservedUsageTable:\s+Type: 'AWS::DynamoDB::Table'[\s\S]+TableName: \${self:custom\.iz_resourcePrefix}RunningTotalReservedUsage/);
|
|
55
83
|
const iam = await readFile(
|
|
56
84
|
join(
|
|
57
85
|
rootPath,
|
|
@@ -80,22 +108,28 @@ test('emits queues, topics, tables, and IAM roles from schema data', async () =>
|
|
|
80
108
|
roleBlock(iam, 'FlowRbacRole'),
|
|
81
109
|
/RolePermissions|ProcessCreateTargetRoleHdrSqs/
|
|
82
110
|
);
|
|
111
|
+
assert.match(roleBlock(iam, 'FlowRbacRole'), /RoleLimit/);
|
|
112
|
+
assert.match(roleBlock(iam, 'FlowRbacRole'), /RunningTotalUsage/);
|
|
113
|
+
assert.match(roleBlock(iam, 'FlowObjectsRole'), /RoleLimit/);
|
|
83
114
|
// Per-object RBAC flow queue (e.g. ValidatorRbacHdrSqs from Order with rbac add-on)
|
|
84
115
|
assert.match(roleBlock(iam, 'FlowRbacRole'), /ValidatorRbacHdrSqs/);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
116
|
+
|
|
117
|
+
const relResources = await readFile(
|
|
118
|
+
join(
|
|
119
|
+
rootPath,
|
|
120
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-relationship.yml'
|
|
121
|
+
),
|
|
122
|
+
'utf8'
|
|
123
|
+
);
|
|
124
|
+
assert.match(relResources, /^ CreateRelationshipHdrSqs:/m);
|
|
91
125
|
assert.equal(
|
|
92
|
-
(
|
|
126
|
+
(relResources.match(/^ CreateRelationshipHdrSqs:/gm) ?? []).length,
|
|
93
127
|
1
|
|
94
128
|
);
|
|
95
|
-
assert.match(
|
|
96
|
-
assert.match(
|
|
129
|
+
assert.match(relResources, /^ CreateRelationshipCompleteHdrSqs:/m);
|
|
130
|
+
assert.match(relResources, /^ GetRelationshipHdrDsq:/m);
|
|
97
131
|
assert.doesNotMatch(
|
|
98
|
-
|
|
132
|
+
relResources,
|
|
99
133
|
/Process(?:Create|Update|Delete|Get|Change|Move)Relationship/
|
|
100
134
|
);
|
|
101
135
|
const relationshipRole = roleBlock(iam, 'FlowRelationshipRole');
|
|
@@ -107,9 +141,12 @@ test('emits queues, topics, tables, and IAM roles from schema data', async () =>
|
|
|
107
141
|
/Process(?:Create|Update|Delete|Get|Change|Move)Relationship/
|
|
108
142
|
);
|
|
109
143
|
assert.match(roleBlock(iam, 'RegisterRole'), /s3:GetObject/);
|
|
144
|
+
assert.match(roleBlock(iam, 'RegisterRole'), /s3:ListBucket/);
|
|
110
145
|
assert.match(roleBlock(iam, 'RegisterRole'), /RegisterComplete/);
|
|
111
146
|
assert.match(roleBlock(iam, 'RegisterRole'), /dynamodb:/);
|
|
112
147
|
assert.match(roleBlock(iam, 'RegisterRole'), /execute-api:ManageConnections/);
|
|
148
|
+
assert.match(roleBlock(iam, 'FlowObjectsRole'), /s3:GetObject/);
|
|
149
|
+
assert.match(roleBlock(iam, 'FlowObjectsRole'), /s3:ListBucket/);
|
|
113
150
|
const procFindDataRole = roleBlock(iam, 'ProcFindDataRole');
|
|
114
151
|
assert.match(procFindDataRole, /dynamodb:UpdateItem/);
|
|
115
152
|
assert.match(procFindDataRole, /dynamodb:GetItem/);
|
|
@@ -118,12 +155,16 @@ test('emits queues, topics, tables, and IAM roles from schema data', async () =>
|
|
|
118
155
|
assert.match(procFindDataRole, /FindData_Out/);
|
|
119
156
|
assert.doesNotMatch(
|
|
120
157
|
iam,
|
|
121
|
-
/s3:GetObjectVersion|
|
|
158
|
+
/s3:GetObjectVersion|sqs:DeleteMessageBatch|sqs:GetQueueUrl/
|
|
122
159
|
);
|
|
123
160
|
assert.match(iam, /#<#\/\w+StatementHookCode#>\n\n \w+Role:/);
|
|
124
161
|
|
|
125
162
|
for (const filePath of [
|
|
126
|
-
'resource/sls_yaml/generatedCode/source/generated-sns-
|
|
163
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-crud.yml',
|
|
164
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-relationship.yml',
|
|
165
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-rbac.yml',
|
|
166
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-custom-flows.yml',
|
|
167
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-system.yml',
|
|
127
168
|
'resource/sls_yaml/generatedCode/source/generated-sns-out.yml',
|
|
128
169
|
'resource/sls_yaml/generatedCode/source/generated-dynamoDB-table.yml',
|
|
129
170
|
'app/sls_yaml/generatedCode/source/generate-shared-resource.yml'
|
|
@@ -153,16 +194,16 @@ test('emits the shared WebSocket completion queue and output-topic subscriptions
|
|
|
153
194
|
const rootPath = await createProject();
|
|
154
195
|
await generateResourceArtifacts(rootPath);
|
|
155
196
|
|
|
156
|
-
const
|
|
197
|
+
const systemResources = await readFile(
|
|
157
198
|
join(
|
|
158
199
|
rootPath,
|
|
159
|
-
'resource/sls_yaml/generatedCode/source/generated-sns-
|
|
200
|
+
'resource/sls_yaml/generatedCode/source/generated-sns-sqs-system.yml'
|
|
160
201
|
),
|
|
161
202
|
'utf8'
|
|
162
203
|
);
|
|
163
|
-
assert.match(
|
|
164
|
-
assert.match(
|
|
165
|
-
assert.match(
|
|
204
|
+
assert.match(systemResources, /^ WebSocketCompleteHdrSqs:/m);
|
|
205
|
+
assert.match(systemResources, /SubscriptionToOutCustomWebSocketComplete:/);
|
|
206
|
+
assert.match(systemResources, /SubscriptionToOutCustomRegisterComplete:/);
|
|
166
207
|
const iam = await readFile(
|
|
167
208
|
join(
|
|
168
209
|
rootPath,
|
|
@@ -186,11 +227,11 @@ test('emits the shared WebSocket completion queue and output-topic subscriptions
|
|
|
186
227
|
);
|
|
187
228
|
}
|
|
188
229
|
assert.match(
|
|
189
|
-
|
|
230
|
+
systemResources,
|
|
190
231
|
/SubscriptionToOutCreateRelationshipWebSocketComplete:/
|
|
191
232
|
);
|
|
192
233
|
assert.match(
|
|
193
|
-
|
|
234
|
+
systemResources,
|
|
194
235
|
/SubscriptionToOutCreateRelationshipRegisterComplete:/
|
|
195
236
|
);
|
|
196
237
|
});
|