@izara_project/izara-core-generate-service-code 1.0.67 → 1.0.69

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.
Files changed (128) hide show
  1. package/.prettierrc +11 -0
  2. package/package.json +16 -12
  3. package/scripts/format-ejs.js +104 -0
  4. package/src/compile/compileProject.js +40 -9
  5. package/src/compile/loadSchemas.js +120 -11
  6. package/src/emit/crud/emitCrudApplicationArtifacts.js +188 -41
  7. package/src/emit/crud/emitDynamicCrudFlowSchemas.js +34 -18
  8. package/src/emit/crud/generateCrudApplicationArtifacts.js +14 -6
  9. package/src/emit/crud/generateDynamicCrudFlowSchemas.js +4 -1
  10. package/src/emit/crud/templates/CreateEndpoint_Main.ejs +296 -105
  11. package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +222 -144
  12. package/src/emit/crud/templates/FlowEndpointBeforeLogical_Main.ejs +22 -6
  13. package/src/emit/crud/templates/FlowEndpointComplete_Main.ejs +134 -43
  14. package/src/emit/crud/templates/FlowEndpoint_HdrWbs.ejs +51 -31
  15. package/src/emit/crud/templates/FlowHandler_HdrApi.ejs +53 -45
  16. package/src/emit/crud/templates/FlowHandler_HdrInv.ejs +28 -26
  17. package/src/emit/crud/templates/FlowHandler_HdrSqs.ejs +15 -11
  18. package/src/emit/crud/templates/FlowMain_Wbs.ejs +53 -38
  19. package/src/emit/crud/templates/GetEndpoint_Main.ejs +6 -3
  20. package/src/emit/crud/templates/GetRangeEndpoint_Main.ejs +2 -2
  21. package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +402 -249
  22. package/src/emit/custom/customFlows.js +68 -28
  23. package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +520 -123
  24. package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +28 -8
  25. package/src/emit/custom/templates/FlowEndpoint_Main.ejs +48 -36
  26. package/src/emit/custom/templates/FlowStep_Main.ejs +7 -9
  27. package/src/emit/custom/templates/s3/ConfirmReserved_HdrSqs.ejs +59 -54
  28. package/src/emit/custom/templates/s3/ConfirmReserved_Main.ejs +33 -23
  29. package/src/emit/custom/templates/s3/CreateObject_HdrWbs.ejs +30 -23
  30. package/src/emit/custom/templates/s3/CreateObject_Main.ejs +56 -39
  31. package/src/emit/custom/templates/s3/CreatePreSignUrl_HdrSqs.ejs +56 -51
  32. package/src/emit/custom/templates/s3/CreatePreSignUrl_Main.ejs +112 -75
  33. package/src/emit/custom/templates/s3/FlowHandler_HdrS3.ejs +14 -9
  34. package/src/emit/custom/templates/s3/ProcessS3File_Main.ejs +11 -8
  35. package/src/emit/custom/templates/s3/ReservedLimit_HdrSqs.ejs +65 -56
  36. package/src/emit/custom/templates/s3/ReservedLimit_Main.ejs +74 -52
  37. package/src/emit/custom/templates/triggerCache/CheckTriggerCache_HdrSqs.ejs +58 -14
  38. package/src/emit/custom/templates/triggerCache/CheckTriggerCache_Main.ejs +12 -17
  39. package/src/emit/custom/templates/triggerCache/TriggerCacheComplete_Main.ejs +20 -13
  40. package/src/emit/custom/templates/triggerCache/TriggerCache_Main.ejs +4 -1
  41. package/src/emit/function/functionYamlArtifact.js +272 -79
  42. package/src/emit/function/templates/ApiFunction_Yaml.ejs +7 -0
  43. package/src/emit/function/templates/EventBridgeFunction_Yaml.ejs +6 -0
  44. package/src/emit/function/templates/InvFunction_Yaml.ejs +5 -0
  45. package/src/emit/function/templates/S3Function_Yaml.ejs +16 -0
  46. package/src/emit/function/templates/SqsFunction_Yaml.ejs +10 -0
  47. package/src/emit/function/templates/WbsFunction_Yaml.ejs +10 -0
  48. package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +40 -29
  49. package/src/emit/rbac/emitRbacApplicationArtifacts.js +171 -72
  50. package/src/emit/rbac/generateCreateTargetRoleHandler.js +6 -4
  51. package/src/emit/rbac/generateDynamicRbacFlowSchemas.js +8 -2
  52. package/src/emit/rbac/rbacFlowTag.js +3 -1
  53. package/src/emit/rbac/templates/CreateTargetRole_HdrSqs.ejs +41 -18
  54. package/src/emit/rbac/templates/CreateTargetRole_Main.ejs +23 -3
  55. package/src/emit/rbac/templates/ListRbac_HdrApi.ejs +27 -5
  56. package/src/emit/rbac/templates/ListRbac_HdrSqs.ejs +41 -8
  57. package/src/emit/rbac/templates/ListRbac_Main.ejs +26 -6
  58. package/src/emit/rbac/templates/RbacMutation_Main.ejs +23 -3
  59. package/src/emit/rbac/templates/UserRbacFlow_HdrSqs.ejs +46 -0
  60. package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +152 -33
  61. package/src/emit/rbac/templates/UserRoleMutation_Main.ejs +24 -4
  62. package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +26 -11
  63. package/src/emit/relationship/emitRelationshipApplicationArtifacts.js +179 -37
  64. package/src/emit/relationship/generateDynamicRelationshipFlowSchemas.js +8 -2
  65. package/src/emit/relationship/generateRelationshipApplicationArtifacts.js +15 -6
  66. package/src/emit/relationship/templates/ChangeRelationshipComplete_Main.ejs +64 -37
  67. package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +258 -142
  68. package/src/emit/relationship/templates/CreateRelationshipComplete_Main.ejs +68 -43
  69. package/src/emit/relationship/templates/CreateRelationship_Main.ejs +315 -171
  70. package/src/emit/relationship/templates/DeleteRelationshipComplete_Main.ejs +67 -41
  71. package/src/emit/relationship/templates/DeleteRelationship_Main.ejs +226 -115
  72. package/src/emit/relationship/templates/FlowHandler_HdrApi.ejs +41 -33
  73. package/src/emit/relationship/templates/FlowHandler_HdrDsq.ejs +15 -11
  74. package/src/emit/relationship/templates/FlowHandler_HdrInv.ejs +28 -26
  75. package/src/emit/relationship/templates/FlowHandler_HdrSqs.ejs +15 -11
  76. package/src/emit/relationship/templates/GetRelationshipComplete_Main.ejs +46 -26
  77. package/src/emit/relationship/templates/GetRelationship_Main.ejs +233 -126
  78. package/src/emit/relationship/templates/MoveRelationshipComplete_Main.ejs +72 -44
  79. package/src/emit/relationship/templates/MoveRelationship_Main.ejs +266 -150
  80. package/src/emit/relationship/templates/UpdateRelationshipComplete_Main.ejs +74 -45
  81. package/src/emit/relationship/templates/UpdateRelationship_Main.ejs +285 -152
  82. package/src/emit/resource/emitResourceArtifacts.js +274 -105
  83. package/src/emit/resource/generateResourceArtifacts.js +15 -6
  84. package/src/emit/resource/templates/GeneratedLambdaRoleServiceConfig.ejs +139 -0
  85. package/src/emit/resource/templates/S3Bucket_Yaml.ejs +19 -0
  86. package/src/emit/resource/templates/S3Subscription_Yaml.ejs +7 -0
  87. package/src/emit/resource/templates/WebSocketSubscription_Yaml.ejs +7 -0
  88. package/src/emit/system/emitSystemWebSocketArtifacts.js +61 -165
  89. package/src/emit/system/templates/WebSocketComplete_HdrSqs.ejs +32 -0
  90. package/src/emit/system/templates/WebSocketComplete_Main.ejs +46 -0
  91. package/src/emit/system/templates/WebSocketComplete_Yaml.ejs +19 -0
  92. package/src/emit/system/templates/WebSocketConnect.ejs +25 -0
  93. package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +11 -0
  94. package/src/generate.js +141 -34
  95. package/src/generateIntTest.js +76 -28
  96. package/src/generateResourceIntTest.js +35 -12
  97. package/src/generateResources/IntTest/generateResources/generateResources.js +5 -2
  98. package/src/generateResources/IntTest/generateResources/templateResources.ejs +18 -30
  99. package/src/generateResources/IntTest/generateTests/events/events.js +1 -1
  100. package/src/generateResources/IntTest/generateTests/events/templateEvents.ejs +13 -10
  101. package/src/generateResources/IntTest/generateTests/generateTemplate.js +2 -2
  102. package/src/generateResources/IntTest/generateTests/pathIntTest/pathIntTest.js +2 -1
  103. package/src/generateResources/IntTest/generateTests/pathIntTest/template.ejs +1 -3
  104. package/src/generateResources/IntTest/generateTests/tests/templateTests.ejs +1 -1
  105. package/src/generateResources/IntTest/generateTests/tests/tests.js +7 -3
  106. package/src/generateResources/IntTest/libs/{libs.js → IntTestGenerateLib.js} +34 -23
  107. package/src/generateResources/IntTest/upload/uploadIntTest.js +33 -19
  108. package/src/intTestGeneratorShared.js +15 -10
  109. package/src/output/commitArtifacts.js +99 -39
  110. package/src/output/mergeHooks.js +24 -10
  111. package/src/output/validateArtifacts.js +37 -27
  112. package/src/plan/buildGenerationPlan.js +24 -13
  113. package/test/core.test.js +116 -49
  114. package/test/createTargetRoleHandler.test.js +63 -14
  115. package/test/crudApplicationArtifacts.test.js +128 -23
  116. package/test/customFlowApplicationArtifacts.test.js +391 -84
  117. package/test/dynamicCrudFlowSchemas.test.js +74 -26
  118. package/test/dynamicRbacFlowSchemas.test.js +63 -20
  119. package/test/dynamicRelationshipFlowSchemas.test.js +65 -18
  120. package/test/functionYamlArtifact.test.js +67 -10
  121. package/test/intTestApi.test.js +9 -10
  122. package/test/publicApi.test.js +184 -44
  123. package/test/relationshipApplicationArtifacts.test.js +90 -19
  124. package/test/resourceArtifacts.test.js +183 -33
  125. package/docs/test.png +0 -0
  126. package/src/emit/rbac/templates/UserRbacFlow_HdrInv.ejs +0 -10
  127. package/src/emit/relationship/dynamicRelationshipFlowSchemaTemplate.js +0 -11
  128. /package/docs/{test.mmd → TriggeredCacheFlow.mmd} +0 -0
@@ -1,6 +1,13 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import { execFile } from 'node:child_process';
3
- import { access, mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
3
+ import {
4
+ access,
5
+ mkdir,
6
+ mkdtemp,
7
+ readFile,
8
+ rm,
9
+ writeFile
10
+ } from 'node:fs/promises';
4
11
  import { tmpdir } from 'node:os';
5
12
  import { dirname, join, resolve } from 'node:path';
6
13
  import { promisify } from 'node:util';
@@ -18,7 +25,11 @@ const parseEsmSource = `
18
25
  const path = process.argv[1];
19
26
  new SourceTextModule(await readFile(path, 'utf8'), { identifier: path });
20
27
  `;
21
- after(() => Promise.all([...roots].map(root => rm(root, { recursive: true, force: true }))));
28
+ after(() =>
29
+ Promise.all(
30
+ [...roots].map((root) => rm(root, { recursive: true, force: true }))
31
+ )
32
+ );
22
33
 
23
34
  test('emits handlers, function YAML, and IAM roles for supported custom flow events', async () => {
24
35
  const rootPath = await createProject();
@@ -26,46 +37,137 @@ test('emits handlers, function YAML, and IAM roles for supported custom flow eve
26
37
  await generateResourceArtifacts(rootPath);
27
38
 
28
39
  assert.equal(result.files.length, 38);
29
- assert.match(await readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Ext/source/Ext_HdrSqs.js'), 'utf8'), /dummyId/);
30
- assert.match(await readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Api/source/Api_HdrApi.js'), 'utf8'), /Api/);
31
- const yaml = await readFile(join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml'), 'utf8');
40
+ assert.match(
41
+ await readFile(
42
+ join(
43
+ rootPath,
44
+ 'app/src/generatedCode/FlowSchemas/Ext/source/Ext_HdrSqs.js'
45
+ ),
46
+ 'utf8'
47
+ ),
48
+ /dummyId/
49
+ );
50
+ assert.match(
51
+ await readFile(
52
+ join(
53
+ rootPath,
54
+ 'app/src/generatedCode/FlowSchemas/Api/source/Api_HdrApi.js'
55
+ ),
56
+ 'utf8'
57
+ ),
58
+ /Api/
59
+ );
60
+ const yaml = await readFile(
61
+ join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml'),
62
+ 'utf8'
63
+ );
32
64
  assert.match(yaml, /EventHdrInv:/);
33
65
  assert.match(yaml, /rate\(1 minute\)/);
34
66
  assert.match(yaml, /ExtHdrSqs:/);
35
- const iam = await readFile(join(rootPath, 'app/sls_yaml/generatedCode/source/generate-shared-resource.yml'), 'utf8');
67
+ const iam = await readFile(
68
+ join(
69
+ rootPath,
70
+ 'app/sls_yaml/generatedCode/source/generate-shared-resource.yml'
71
+ ),
72
+ 'utf8'
73
+ );
36
74
  assert.match(iam, /EventRole:/);
37
75
  assert.match(iam, /ExtRole:/);
38
76
  assert.match(iam, /InvRole:/);
39
77
  assert.match(iam, /ApiRole:/);
40
78
  assert.match(iam, /OwnRole:/);
41
79
  assert.match(iam, /UploadRole:/);
42
- assert.match(await readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Generated/source/Generated_HdrWbs.js'), 'utf8'), /Generated_WbsMain/);
43
- assert.match(await readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Own/source/Own_HdrSqs.js'), 'utf8'), /Own_Main/);
44
80
  assert.match(
45
- await readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Own/source/Own_Main.js'), 'utf8'),
81
+ await readFile(
82
+ join(
83
+ rootPath,
84
+ 'app/src/generatedCode/FlowSchemas/Generated/source/Generated_HdrWbs.js'
85
+ ),
86
+ 'utf8'
87
+ ),
88
+ /Generated_WbsMain/
89
+ );
90
+ assert.match(
91
+ await readFile(
92
+ join(
93
+ rootPath,
94
+ 'app/src/generatedCode/FlowSchemas/Own/source/Own_HdrSqs.js'
95
+ ),
96
+ 'utf8'
97
+ ),
98
+ /Own_Main/
99
+ );
100
+ assert.match(
101
+ await readFile(
102
+ join(
103
+ rootPath,
104
+ 'app/src/generatedCode/FlowSchemas/Own/source/Own_Main.js'
105
+ ),
106
+ 'utf8'
107
+ ),
46
108
  /asyncFlowSharedLib/
47
109
  );
48
110
  assert.match(
49
- await readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Cache/source/Cache_Main.js'), 'utf8'),
50
- /"CurrentOrderTable"/
111
+ await readFile(
112
+ join(
113
+ rootPath,
114
+ 'app/src/generatedCode/FlowSchemas/Cache/source/Cache_Main.js'
115
+ ),
116
+ 'utf8'
117
+ ),
118
+ /CurrentOrderTable/
119
+ );
120
+ await assert.rejects(
121
+ readFile(
122
+ join(
123
+ rootPath,
124
+ 'app/src/generatedCode/FlowSchemas/Own/source/ProcessOwn_Main.js'
125
+ )
126
+ )
127
+ );
128
+ assert.match(
129
+ await readFile(
130
+ join(
131
+ rootPath,
132
+ 'app/src/generatedCode/FlowSchemas/Mixed/source/Mixed_HdrSqs.js'
133
+ ),
134
+ 'utf8'
135
+ ),
136
+ /Mixed/
51
137
  );
52
- await assert.rejects(readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Own/source/ProcessOwn_Main.js')));
53
- assert.match(await readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Mixed/source/Mixed_HdrSqs.js'), 'utf8'), /Mixed/);
54
138
  assert.match(yaml, /OwnHdrWbs:/);
55
139
  assert.match(yaml, /OwnHdrSqs:/);
56
140
  assert.ok(yaml.indexOf('OwnHdrWbs:') < yaml.indexOf('OwnHdrSqs:'));
57
141
  assert.match(yaml, /MixedHdrSqs:/);
58
142
  assert.match(yaml, /UploadProcessAfterUploadHdrS3:/);
59
143
  assert.match(
60
- await readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Upload/source/UploadProcessAfterUpload_Main.js'), 'utf8'),
144
+ await readFile(
145
+ join(
146
+ rootPath,
147
+ 'app/src/generatedCode/FlowSchemas/Upload/source/UploadProcessAfterUpload_Main.js'
148
+ ),
149
+ 'utf8'
150
+ ),
61
151
  /S3Client/
62
152
  );
63
153
  assert.match(
64
- await readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Upload/source/UploadCreatePreSignUrl_Main.js'), 'utf8'),
154
+ await readFile(
155
+ join(
156
+ rootPath,
157
+ 'app/src/generatedCode/FlowSchemas/Upload/source/UploadCreatePreSignUrl_Main.js'
158
+ ),
159
+ 'utf8'
160
+ ),
65
161
  /createPresignedPost/
66
162
  );
67
163
  assert.match(
68
- await readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Upload/source/UploadConfirmAfterUpload_Main.js'), 'utf8'),
164
+ await readFile(
165
+ join(
166
+ rootPath,
167
+ 'app/src/generatedCode/FlowSchemas/Upload/source/UploadConfirmAfterUpload_Main.js'
168
+ ),
169
+ 'utf8'
170
+ ),
69
171
  /confirmUsageMessage/
70
172
  );
71
173
  for (const path of [
@@ -75,12 +177,24 @@ test('emits handlers, function YAML, and IAM roles for supported custom flow eve
75
177
  'UploadConfirmAfterUpload_Main.js'
76
178
  ]) {
77
179
  assert.doesNotMatch(
78
- await readFile(join(rootPath, `app/src/generatedCode/FlowSchemas/Upload/source/${path}`), 'utf8'),
180
+ await readFile(
181
+ join(
182
+ rootPath,
183
+ `app/src/generatedCode/FlowSchemas/Upload/source/${path}`
184
+ ),
185
+ 'utf8'
186
+ ),
79
187
  /@izara_project\/izara-core-generate-service-code/
80
188
  );
81
189
  }
82
190
  assert.match(
83
- await readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Upload/source/UploadProcessAfterUpload_HdrS3.js'), 'utf8'),
191
+ await readFile(
192
+ join(
193
+ rootPath,
194
+ 'app/src/generatedCode/FlowSchemas/Upload/source/UploadProcessAfterUpload_HdrS3.js'
195
+ ),
196
+ 'utf8'
197
+ ),
84
198
  /s3Record\.bucket,\n\s*s3Record\.object/
85
199
  );
86
200
  for (const path of [
@@ -95,12 +209,23 @@ test('emits handlers, function YAML, and IAM roles for supported custom flow eve
95
209
  'UploadConfirmAfterUpload_Main.js',
96
210
  'UploadConfirmAfterUpload_HdrSqs.js'
97
211
  ]) {
98
- await parseAsEsm(join(rootPath, `app/src/generatedCode/FlowSchemas/Upload/source/${path}`));
212
+ await parseAsEsm(
213
+ join(rootPath, `app/src/generatedCode/FlowSchemas/Upload/source/${path}`)
214
+ );
99
215
  }
100
- for (const path of ['UploadReservedLimit_Main.js', 'UploadCreatePreSignUrl_Main.js', 'UploadConfirmAfterUpload_Main.js']) {
101
- const filePath = join(rootPath, `app/src/generatedCode/FlowSchemas/Upload/source/${path}`);
216
+ for (const path of [
217
+ 'UploadReservedLimit_Main.js',
218
+ 'UploadCreatePreSignUrl_Main.js',
219
+ 'UploadConfirmAfterUpload_Main.js'
220
+ ]) {
221
+ const filePath = join(
222
+ rootPath,
223
+ `app/src/generatedCode/FlowSchemas/Upload/source/${path}`
224
+ );
102
225
  const source = await readFile(filePath, 'utf8');
103
- const helperPath = source.match(/from '((?:\.\.\/)+libs\/source\/GenerateCodeLibs\.js)'/)?.[1];
226
+ const helperPath = source.match(
227
+ /from '((?:\.\.\/)+libs\/source\/GenerateCodeLibs\.js)'/
228
+ )?.[1];
104
229
  assert.ok(helperPath, `${path} imports GenerateCodeLibs`);
105
230
  await access(resolve(dirname(filePath), helperPath));
106
231
  }
@@ -109,12 +234,36 @@ test('emits handlers, function YAML, and IAM roles for supported custom flow eve
109
234
  test('removes only V2-owned custom-flow application artifacts when supported events are removed', async () => {
110
235
  const rootPath = await createProject();
111
236
  await generateCustomFlowApplicationArtifacts(rootPath);
112
- await writeFile(join(rootPath, 'app/src/schemas/FlowSchemas/Flows.js'), "export default [{ flowTag: 'later', event: ['unsupported'] }];\n");
237
+ await writeFile(
238
+ join(rootPath, 'app/src/schemas/FlowSchemas/Flows.js'),
239
+ "export default [{ flowTag: 'later', event: ['unsupported'] }];\n"
240
+ );
113
241
 
114
- assert.deepEqual((await generateCustomFlowApplicationArtifacts(rootPath)).files, []);
115
- await assert.rejects(readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Ext/source/Ext_HdrSqs.js')));
116
- await assert.rejects(readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Own/source/Own_HdrWbs.js')));
117
- await assert.rejects(readFile(join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml')));
242
+ assert.deepEqual(
243
+ (await generateCustomFlowApplicationArtifacts(rootPath)).files,
244
+ []
245
+ );
246
+ await assert.rejects(
247
+ readFile(
248
+ join(
249
+ rootPath,
250
+ 'app/src/generatedCode/FlowSchemas/Ext/source/Ext_HdrSqs.js'
251
+ )
252
+ )
253
+ );
254
+ await assert.rejects(
255
+ readFile(
256
+ join(
257
+ rootPath,
258
+ 'app/src/generatedCode/FlowSchemas/Own/source/Own_HdrWbs.js'
259
+ )
260
+ )
261
+ );
262
+ await assert.rejects(
263
+ readFile(
264
+ join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml')
265
+ )
266
+ );
118
267
  });
119
268
 
120
269
  test('emits and removes ext-topic handlers declared by custom flow steps', async () => {
@@ -122,121 +271,270 @@ test('emits and removes ext-topic handlers declared by custom flow steps', async
122
271
  const result = await generateCustomFlowApplicationArtifacts(rootPath);
123
272
  await generateResourceArtifacts(rootPath);
124
273
 
125
- assert.ok(result.files.some(file => file.path === 'app/src/generatedCode/FlowSchemas/Stepped/source/SteppedComplete_HdrSqs.js'));
126
- assert.ok(result.files.some(file => file.path === 'app/src/generatedCode/FlowSchemas/Generated/source/GeneratedComplete_HdrSqs.js'));
127
- assert.ok(result.files.some(file => file.path === 'app/src/generatedCode/FlowSchemas/DsqStep/source/DsqStepRetryDsq_HdrDsq.js'));
274
+ assert.ok(
275
+ result.files.some(
276
+ (file) =>
277
+ file.path ===
278
+ 'app/src/generatedCode/FlowSchemas/Stepped/source/SteppedComplete_HdrSqs.js'
279
+ )
280
+ );
281
+ assert.ok(
282
+ result.files.some(
283
+ (file) =>
284
+ file.path ===
285
+ 'app/src/generatedCode/FlowSchemas/Generated/source/GeneratedComplete_HdrSqs.js'
286
+ )
287
+ );
288
+ assert.ok(
289
+ result.files.some(
290
+ (file) =>
291
+ file.path ===
292
+ 'app/src/generatedCode/FlowSchemas/DsqStep/source/DsqStepRetryDsq_HdrDsq.js'
293
+ )
294
+ );
128
295
  assert.match(
129
- await readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Stepped/source/SteppedComplete_Main.js'), 'utf8'),
296
+ await readFile(
297
+ join(
298
+ rootPath,
299
+ 'app/src/generatedCode/FlowSchemas/Stepped/source/SteppedComplete_Main.js'
300
+ ),
301
+ 'utf8'
302
+ ),
130
303
  /identifierUuid/
131
304
  );
132
305
  assert.match(
133
- await readFile(join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml'), 'utf8'),
306
+ await readFile(
307
+ join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml'),
308
+ 'utf8'
309
+ ),
134
310
  /SteppedCompleteHdrSqs:\n handler: src\/generatedCode\/FlowSchemas\/Stepped\/source\/SteppedComplete_HdrSqs.main/
135
311
  );
136
312
  assert.match(
137
- await readFile(join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml'), 'utf8'),
313
+ await readFile(
314
+ join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml'),
315
+ 'utf8'
316
+ ),
138
317
  /DsqStepRetryDsqHdrDsq:\n handler: src\/generatedCode\/FlowSchemas\/DsqStep\/source\/DsqStepRetryDsq_HdrDsq.main/
139
318
  );
140
319
  assert.match(
141
- await readFile(join(rootPath, 'resource/sls_yaml/generatedCode/source/generated-sns-in-sqs.yml'), 'utf8'),
320
+ await readFile(
321
+ join(
322
+ rootPath,
323
+ 'resource/sls_yaml/generatedCode/source/generated-sns-in-sqs.yml'
324
+ ),
325
+ 'utf8'
326
+ ),
142
327
  /^ SteppedCompleteHdrSqs:/m
143
328
  );
144
329
  assert.match(
145
- await readFile(join(rootPath, 'resource/sls_yaml/generatedCode/source/generated-sns-in-sqs.yml'), 'utf8'),
330
+ await readFile(
331
+ join(
332
+ rootPath,
333
+ 'resource/sls_yaml/generatedCode/source/generated-sns-in-sqs.yml'
334
+ ),
335
+ 'utf8'
336
+ ),
146
337
  /^ DsqStepRetryDsqHdrDsq:/m
147
338
  );
148
339
  assert.match(
149
- await readFile(join(rootPath, 'app/sls_yaml/generatedCode/source/generate-shared-resource.yml'), 'utf8'),
340
+ await readFile(
341
+ join(
342
+ rootPath,
343
+ 'app/sls_yaml/generatedCode/source/generate-shared-resource.yml'
344
+ ),
345
+ 'utf8'
346
+ ),
150
347
  /GeneratedRole:/
151
348
  );
152
349
 
153
- await writeFile(join(rootPath, 'app/src/schemas/FlowSchemas/Stepped.js'), "export default { flowTag: 'stepped', event: ['ownTopic'] };\n");
154
- await writeFile(join(rootPath, 'app/src/schemas/FlowSchemas/Generated.js'), "export default { flowTag: 'generated', event: ['ownTopic'], generatedCodeConfig: { generatedCodeTag: 'create' } };\n");
350
+ await writeFile(
351
+ join(rootPath, 'app/src/schemas/FlowSchemas/Stepped.js'),
352
+ "export default { flowTag: 'stepped', event: ['ownTopic'] };\n"
353
+ );
354
+ await writeFile(
355
+ join(rootPath, 'app/src/schemas/FlowSchemas/Generated.js'),
356
+ "export default { flowTag: 'generated', event: ['ownTopic'], generatedCodeConfig: { generatedCodeTag: 'create' } };\n"
357
+ );
155
358
  await generateCustomFlowApplicationArtifacts(rootPath);
156
359
  await generateResourceArtifacts(rootPath);
157
360
 
158
- await assert.rejects(readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Stepped/source/SteppedComplete_HdrSqs.js')));
159
- await assert.rejects(readFile(join(rootPath, 'app/src/generatedCode/FlowSchemas/Generated/source/GeneratedComplete_HdrSqs.js')));
361
+ await assert.rejects(
362
+ readFile(
363
+ join(
364
+ rootPath,
365
+ 'app/src/generatedCode/FlowSchemas/Stepped/source/SteppedComplete_HdrSqs.js'
366
+ )
367
+ )
368
+ );
369
+ await assert.rejects(
370
+ readFile(
371
+ join(
372
+ rootPath,
373
+ 'app/src/generatedCode/FlowSchemas/Generated/source/GeneratedComplete_HdrSqs.js'
374
+ )
375
+ )
376
+ );
160
377
  assert.doesNotMatch(
161
- await readFile(join(rootPath, 'resource/sls_yaml/generatedCode/source/generated-sns-in-sqs.yml'), 'utf8'),
378
+ await readFile(
379
+ join(
380
+ rootPath,
381
+ 'resource/sls_yaml/generatedCode/source/generated-sns-in-sqs.yml'
382
+ ),
383
+ 'utf8'
384
+ ),
162
385
  /^ SteppedCompleteHdrSqs:/m
163
386
  );
164
387
  });
165
388
 
166
- test('emits and removes the legacy trigger-cache artifact suite', async () => {
167
- const rootPath = await createTriggerCacheProject();
389
+ test('emits and removes the trigger-cache artifact suite when triggerFlowTypes is set', async () => {
390
+ const rootPath = await createTriggerCacheProject(['OrderCheckout']);
168
391
  await generateCustomFlowApplicationArtifacts(rootPath);
169
392
  await generateResourceArtifacts(rootPath);
170
393
 
171
394
  const source = 'app/src/generatedCode/FlowSchemas/Cart/source';
172
395
  for (const fileName of [
173
- 'CartCheckTriggerCacheCartComplete_Main.js',
174
- 'CartCheckTriggerCacheCartComplete_HdrSqs.js',
175
- 'CartTriggerCacheCartComplete_Main.js',
176
- 'CartTriggerCacheCartComplete_HdrSqs.js'
396
+ 'CartCheckTriggerFlows_Main.js',
397
+ 'CartCheckTriggerFlows_HdrSqs.js'
177
398
  ]) {
178
399
  const path = join(rootPath, source, fileName);
179
400
  await access(path);
180
401
  await parseAsEsm(path);
181
402
  }
182
403
 
183
- const flowYaml = await readFile(join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml'), 'utf8');
184
- for (const functionName of [
185
- 'CartCheckTriggerCacheCartCompleteHdrSqs',
186
- 'CartTriggerCacheCartCompleteHdrSqs'
187
- ]) {
188
- assert.match(flowYaml, new RegExp(`^${functionName}:`, 'm'));
189
- }
404
+ const flowYaml = await readFile(
405
+ join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml'),
406
+ 'utf8'
407
+ );
408
+ assert.match(flowYaml, /^CartCheckTriggerFlowsHdrSqs:/m);
190
409
  assert.match(
191
- await readFile(join(rootPath, `${source}/CartCheckTriggerCacheCartComplete_HdrSqs.js`), 'utf8'),
192
- /record\.body\.Message\.identifiers/
410
+ await readFile(
411
+ join(rootPath, `${source}/CartCheckTriggerFlows_HdrSqs.js`),
412
+ 'utf8'
413
+ ),
414
+ /CartCheckTriggerFlowsHdrSqs/
193
415
  );
194
416
 
195
- const resources = await readFile(join(rootPath, 'resource/sls_yaml/generatedCode/source/generated-sns-in-sqs.yml'), 'utf8');
417
+ const resources = await readFile(
418
+ join(
419
+ rootPath,
420
+ 'resource/sls_yaml/generatedCode/source/generated-sns-in-sqs.yml'
421
+ ),
422
+ 'utf8'
423
+ );
196
424
  assert.match(resources, /^ CartHdrSqs:/m);
197
- for (const queueName of [
198
- 'CartHdrSqs',
199
- 'CartCheckTriggerCacheCartCompleteHdrSqs',
200
- 'CartTriggerCacheCartCompleteHdrSqs',
201
- 'CartTriggerCacheCartCompleteHdrDsq'
202
- ]) assert.match(resources, new RegExp('QueueName: \\$\\{self:custom\\.iz_resourcePrefix\\}' + queueName));
203
- const iam = await readFile(join(rootPath, 'app/sls_yaml/generatedCode/source/generate-shared-resource.yml'), 'utf8');
425
+ for (const queueName of ['CartHdrSqs', 'CartCheckTriggerFlowsHdrSqs'])
426
+ assert.match(
427
+ resources,
428
+ new RegExp(
429
+ 'QueueName: \\$\\{self:custom\\.iz_resourcePrefix\\}' + queueName
430
+ )
431
+ );
204
432
 
205
- await writeFile(join(rootPath, 'app/src/schemas/FlowSchemas/Cart.js'), "export default { flowTag: 'cart', event: ['ownTopic'], statusType: 'none' };\n");
433
+ await writeFile(
434
+ join(rootPath, 'app/src/schemas/FlowSchemas/Cart.js'),
435
+ "export default { flowTag: 'cart', event: ['ownTopic'], statusType: 'none' };\n"
436
+ );
206
437
  await generateCustomFlowApplicationArtifacts(rootPath);
207
438
  await generateResourceArtifacts(rootPath);
208
439
 
209
- await assert.rejects(readFile(join(rootPath, `${source}/CartCheckTriggerCacheCartComplete_Main.js`)));
210
- assert.doesNotMatch(await readFile(join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml'), 'utf8'), /CartCheckTriggerCacheCartCompleteHdrSqs/);
211
- assert.doesNotMatch(await readFile(join(rootPath, 'resource/sls_yaml/generatedCode/source/generated-sns-in-sqs.yml'), 'utf8'), /CartTriggerCacheCartCompleteHdrDsq/);
440
+ await assert.rejects(
441
+ readFile(join(rootPath, `${source}/CartCheckTriggerFlows_Main.js`))
442
+ );
443
+ assert.doesNotMatch(
444
+ await readFile(
445
+ join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml'),
446
+ 'utf8'
447
+ ),
448
+ /CartCheckTriggerFlowsHdrSqs/
449
+ );
450
+ });
451
+
452
+ test('uses custom CheckTrigger step if provided by developer in flowSteps', async () => {
453
+ const rootPath = await mkdtemp(
454
+ join(tmpdir(), 'generate-service-code-v2-trigger-cache-custom-')
455
+ );
456
+ roots.add(rootPath);
457
+ const schemaRoot = join(rootPath, 'app/src/schemas/FlowSchemas');
458
+ await mkdir(schemaRoot, { recursive: true });
459
+ await writeFile(
460
+ join(schemaRoot, 'Cart.js'),
461
+ "export default { flowTag: 'cart', event: ['ownTopic'], statusType: 'triggerCache', triggerFlowTypes: ['OrderCheckout'], objType: { serviceTag: 'Order' }, flowSteps: [{ stepName: 'start' }, { stepName: 'CheckTriggerCustomStep', event: ['extTopic'] }] };\n"
462
+ );
463
+
464
+ await generateCustomFlowApplicationArtifacts(rootPath);
465
+ const source = 'app/src/generatedCode/FlowSchemas/Cart/source';
466
+ const path = join(rootPath, source, 'CartCheckTriggerCustomStep_Main.js');
467
+ await access(path);
468
+ await parseAsEsm(path);
469
+
470
+ const flowYaml = await readFile(
471
+ join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml'),
472
+ 'utf8'
473
+ );
474
+ assert.match(flowYaml, /^CartCheckTriggerCustomStepHdrSqs:/m);
475
+ });
476
+
477
+ test('does not emit check trigger-cache artifacts when triggerFlowTypes is empty, null, undefined, or missing', async () => {
478
+ for (const emptyTriggerFlowTypes of [[], null, undefined]) {
479
+ const rootPath = await createTriggerCacheProject(emptyTriggerFlowTypes);
480
+ await generateCustomFlowApplicationArtifacts(rootPath);
481
+ await generateResourceArtifacts(rootPath);
482
+
483
+ const source = 'app/src/generatedCode/FlowSchemas/Cart/source';
484
+ await assert.rejects(
485
+ readFile(join(rootPath, `${source}/CartCheckTriggerFlows_Main.js`))
486
+ );
487
+ await assert.rejects(
488
+ readFile(join(rootPath, `${source}/CartCheckTriggerFlows_HdrSqs.js`))
489
+ );
490
+
491
+ const flowYaml = await readFile(
492
+ join(rootPath, 'app/sls_yaml/generatedCode/source/flow-schema.yml'),
493
+ 'utf8'
494
+ );
495
+ assert.doesNotMatch(flowYaml, /CartCheckTriggerFlowsHdrSqs/);
496
+ }
212
497
  });
213
498
 
214
499
  test('rejects an EventBridge schedule without a deployable name and rate', () => {
215
500
  assert.throws(
216
- () => renderEventBridgeFunctionYaml({
217
- functionName: 'ProcessEventHdrInv',
218
- handlerPath: 'src/generatedCode/FlowSchemas/Event/source/ProcessEvent_HdrInv.main',
219
- roleName: 'EventRole',
220
- flowTag: 'Event',
221
- schedules: [{ name: 'missing-rate' }]
222
- }),
501
+ () =>
502
+ renderEventBridgeFunctionYaml({
503
+ functionName: 'ProcessEventHdrInv',
504
+ handlerPath:
505
+ 'src/generatedCode/FlowSchemas/Event/source/ProcessEvent_HdrInv.main',
506
+ roleName: 'EventRole',
507
+ flowTag: 'Event',
508
+ schedules: [{ name: 'missing-rate' }]
509
+ }),
223
510
  /Each EventBridge schedule/
224
511
  );
225
512
  });
226
513
 
227
514
  async function createProject() {
228
- const rootPath = await mkdtemp(join(tmpdir(), 'generate-service-code-v2-custom-flow-'));
515
+ const rootPath = await mkdtemp(
516
+ join(tmpdir(), 'generate-service-code-v2-custom-flow-')
517
+ );
229
518
  roots.add(rootPath);
230
519
  const schemaRoot = join(rootPath, 'app/src/schemas/FlowSchemas');
231
520
  const objectSchemaRoot = join(rootPath, 'app/src/schemas/ObjectSchemas');
232
521
  const helperRoot = join(rootPath, 'app/src/generatedCode/libs/source');
233
- await Promise.all([mkdir(schemaRoot, { recursive: true }), mkdir(objectSchemaRoot, { recursive: true }), mkdir(helperRoot, { recursive: true })]);
234
- await writeFile(join(helperRoot, 'GenerateCodeLibs.js'), 'export const getNestObject = () => {};\nexport const processStaticLimit = () => {};\nexport const postToConnection = () => {};\n');
522
+ await Promise.all([
523
+ mkdir(schemaRoot, { recursive: true }),
524
+ mkdir(objectSchemaRoot, { recursive: true }),
525
+ mkdir(helperRoot, { recursive: true })
526
+ ]);
527
+ await writeFile(
528
+ join(helperRoot, 'GenerateCodeLibs.js'),
529
+ 'export const getNestObject = () => {};\nexport const processStaticLimit = () => {};\nexport const postToConnection = () => {};\n'
530
+ );
235
531
  await writeFile(
236
532
  join(objectSchemaRoot, 'Order.js'),
237
533
  "export default [{ objectType: 'order', serviceTag: 'Other', storageResources: { main: { storageType: 'dynamoDB', tableName: 'OtherOrderTable' } } }, { objectType: 'order', serviceTag: 'Current', storageResources: { main: { storageType: 'dynamoDB', tableName: 'CurrentOrderTable' } } }];\n"
238
534
  );
239
- await writeFile(join(schemaRoot, 'Flows.js'), `
535
+ await writeFile(
536
+ join(schemaRoot, 'Flows.js'),
537
+ `
240
538
  const base = { flowSteps: [{ stepName: 'start', properties: ['dummyId'] }], stepProperties: { dummyId: { type: 'string' } } };
241
539
  export default [
242
540
  { ...base, flowTag: 'event', event: ['eventBridge'], schedules: [{ name: 'every-minute', rate: ['rate(1 minute)'] }] },
@@ -249,7 +547,8 @@ export default [
249
547
  { ...base, flowTag: 'generated', event: ['ownTopic'], generatedCodeConfig: { generatedCodeTag: 'create' } },
250
548
  { ...base, flowTag: 'upload', event: ['s3'] }
251
549
  ];
252
- `);
550
+ `
551
+ );
253
552
  return rootPath;
254
553
  }
255
554
 
@@ -265,7 +564,9 @@ async function parseAsEsm(path) {
265
564
  }
266
565
 
267
566
  async function createStepProject() {
268
- const rootPath = await mkdtemp(join(tmpdir(), 'generate-service-code-v2-custom-step-'));
567
+ const rootPath = await mkdtemp(
568
+ join(tmpdir(), 'generate-service-code-v2-custom-step-')
569
+ );
269
570
  roots.add(rootPath);
270
571
  const schemaRoot = join(rootPath, 'app/src/schemas/FlowSchemas');
271
572
  await mkdir(schemaRoot, { recursive: true });
@@ -284,14 +585,20 @@ async function createStepProject() {
284
585
  return rootPath;
285
586
  }
286
587
 
287
- async function createTriggerCacheProject() {
288
- const rootPath = await mkdtemp(join(tmpdir(), 'generate-service-code-v2-trigger-cache-'));
588
+ async function createTriggerCacheProject(triggerFlowTypes) {
589
+ const rootPath = await mkdtemp(
590
+ join(tmpdir(), 'generate-service-code-v2-trigger-cache-')
591
+ );
289
592
  roots.add(rootPath);
290
593
  const schemaRoot = join(rootPath, 'app/src/schemas/FlowSchemas');
291
594
  await mkdir(schemaRoot, { recursive: true });
595
+ const triggerFlowTypesAttr =
596
+ Array.isArray(triggerFlowTypes) && triggerFlowTypes.length > 0
597
+ ? `triggerFlowTypes: ${JSON.stringify(triggerFlowTypes)}, `
598
+ : '';
292
599
  await writeFile(
293
600
  join(schemaRoot, 'Cart.js'),
294
- "export default { flowTag: 'cart', event: ['ownTopic'], statusType: 'triggerCache', objType: { serviceTag: 'Order' }, flowSteps: [{ stepName: 'start' }, { stepName: 'CheckTriggerCacheCartComplete', checkTriggerType: 'flowType', event: ['extTopic'] }, { stepName: 'TriggerCacheCartComplete', checkTriggerType: 'complete', event: ['extTopic', 'dsq'] }] };\n"
601
+ `export default { flowTag: 'cart', event: ['ownTopic'], statusType: 'triggerCache', ${triggerFlowTypesAttr}objType: { serviceTag: 'Order' }, flowSteps: [{ stepName: 'start' }] };\n`
295
602
  );
296
603
  return rootPath;
297
604
  }