@izara_project/izara-core-generate-service-code 1.0.102 → 1.0.103

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@izara_project/izara-core-generate-service-code",
3
- "version": "1.0.102",
3
+ "version": "1.0.103",
4
4
  "description": "Code for locally generating per service files",
5
5
  "homepage": "https://bitbucket.org/izara-core-support-services/izara-core-support-services-generate-service-code#readme",
6
6
  "repository": {
@@ -1,4 +1,11 @@
1
1
  import initialSetupLib from '@izara_project/izara-core-library-initial-setup';
2
+ import { basicValidatorSchema } from '@izara_project/izara-shared-service-schemas';
3
+
4
+ if (basicValidatorSchema?.basicFlowSchema?.properties?.event?.items?.enum) {
5
+ if (!basicValidatorSchema.basicFlowSchema.properties.event.items.enum.includes('dss')) {
6
+ basicValidatorSchema.basicFlowSchema.properties.event.items.enum.push('dss');
7
+ }
8
+ }
2
9
 
3
10
  const SERVICE_TAG = {
4
11
  TRANSLATIONS: 'Translations',
@@ -16,6 +16,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  */
17
17
 
18
18
  import initialSetupSharedLib from '@izara_project/izara-core-library-initial-setup';
19
+ import { basicValidatorSchema } from '@izara_project/izara-shared-service-schemas';
20
+
21
+ if (basicValidatorSchema?.basicFlowSchema?.properties?.event?.items?.enum) {
22
+ if (!basicValidatorSchema.basicFlowSchema.properties.event.items.enum.includes('dss')) {
23
+ basicValidatorSchema.basicFlowSchema.properties.event.items.enum.push('dss');
24
+ }
25
+ }
19
26
 
20
27
  const SERVICE_TAG = {
21
28
  TRANSLATIONS: 'Translations',
@@ -153,6 +153,10 @@ export default async function <%- flowTag %>(
153
153
  requestParams.billable = true;
154
154
  }
155
155
 
156
+ //(<rbacUsageValue_<%- flowTag %>>)
157
+ let usageValue = requestParams.value || requestParams.usageValue || 1;
158
+ //(</rbacUsageValue_<%- flowTag %>>)
159
+
156
160
  const resultPermissionCheck = await checkRbacPermission(
157
161
  _izContext,
158
162
  {
@@ -168,6 +172,7 @@ export default async function <%- flowTag %>(
168
172
  serviceTag: <%- rbacServiceTags.length === 1 ? rbacServiceTags[0] : `{ ${Object.entries(rbacServiceTagMap).map(([k, v]) => `'${k}': ${v}`).join(', ')} }[requestParams.objectType] || process.env.iz_serviceTag` %>
169
173
  },
170
174
  requestParams: requestParams,
175
+ value: usageValue,
171
176
  sync: true
172
177
  }
173
178
  );
@@ -187,6 +192,14 @@ export default async function <%- flowTag %>(
187
192
  );
188
193
  }
189
194
 
195
+ if (resultPermissionCheck?.uniqueIdentify) {
196
+ requestParams.reservedUsageId = resultPermissionCheck.uniqueIdentify;
197
+ }
198
+ if (resultPermissionCheck?.runningTotalReservedId) {
199
+ requestParams.runningTotalReservedId =
200
+ resultPermissionCheck.runningTotalReservedId;
201
+ }
202
+
190
203
  //(<rbacPublish_<%- flowTag %>>)
191
204
  //(</rbacPublish_<%- flowTag %>>)
192
205
  }
@@ -275,6 +288,7 @@ export default async function <%- flowTag %>(
275
288
  //(</afterBeforeLogical_<%= objectType %>>)
276
289
 
277
290
  <%_ if (hasOwnTopic) { _%>
291
+ /*
278
292
  // ── ownTopic (async — dispatch to before-hook and await callback) ──────────
279
293
  <%_ configs.filter(c => c?.generatedCodeConfig?.invocationType === 'ownTopic' || c?.event?.includes('ownTopic')).forEach(config => { _%>
280
294
  let hookPayload_<%= config.flowTag %> = {
@@ -341,6 +355,13 @@ export default async function <%- flowTag %>(
341
355
  status: 'pending',
342
356
  message: 'Dispatched to BeforeHook'
343
357
  };
358
+ */
359
+ return await <%- flowTag %>LogicalLib(
360
+ _izContext,
361
+ requestParams,
362
+ callingFlowConfig,
363
+ foundErrors
364
+ );
344
365
  <%_ } else { _%>
345
366
  return await <%- flowTag %>LogicalLib(
346
367
  _izContext,
@@ -154,7 +154,7 @@ export default async function CancelUsage(_izContext, requestParams) {
154
154
  };
155
155
 
156
156
  const eventSourceTag =
157
- _izContext.izEventSource?.eventSourceTag ||
157
+ _izContext?.izEventSource?.eventSourceTag ||
158
158
  requestParams?.izEventSource?.eventSourceTag;
159
159
 
160
160
  let isSync = false;
@@ -162,16 +162,17 @@ export default async function CancelUsage(_izContext, requestParams) {
162
162
  eventSourceTag === 'DirectInvoke' ||
163
163
  eventSourceTag === 'ApiGateway' ||
164
164
  eventSourceTag === 'ApiGatewayV2' ||
165
- requestParams?.hasOwnProperty('__context__')
165
+ requestParams?.hasOwnProperty('__context__') ||
166
+ _izContext?.functionName?.endsWith('HdrInv') ||
167
+ _izContext?.functionName?.endsWith('HdrApi') ||
168
+ eventSourceTag !== 'Sqs'
166
169
  ) {
167
170
  isSync = true;
168
171
  }
169
172
 
170
173
  if (!isSync) {
171
- await sns.publishMessage(_izContext, {
172
- message: {
173
- returnResult
174
- },
174
+ await sns.publishAsync(_izContext, {
175
+ Message: JSON.stringify({ returnResult }),
175
176
  TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
176
177
  _izContext,
177
178
  'CancelUsage_Out'
@@ -178,7 +178,7 @@ export default async function ConfirmUsage(_izContext, requestParams) {
178
178
  };
179
179
 
180
180
  const eventSourceTag =
181
- _izContext.izEventSource?.eventSourceTag ||
181
+ _izContext?.izEventSource?.eventSourceTag ||
182
182
  requestParams?.izEventSource?.eventSourceTag;
183
183
 
184
184
  let isSync = false;
@@ -186,16 +186,17 @@ export default async function ConfirmUsage(_izContext, requestParams) {
186
186
  eventSourceTag === 'DirectInvoke' ||
187
187
  eventSourceTag === 'ApiGateway' ||
188
188
  eventSourceTag === 'ApiGatewayV2' ||
189
- requestParams?.hasOwnProperty('__context__')
189
+ requestParams?.hasOwnProperty('__context__') ||
190
+ _izContext?.functionName?.endsWith('HdrInv') ||
191
+ _izContext?.functionName?.endsWith('HdrApi') ||
192
+ eventSourceTag !== 'Sqs'
190
193
  ) {
191
194
  isSync = true;
192
195
  }
193
196
 
194
197
  if (!isSync) {
195
- await sns.publishMessage(_izContext, {
196
- message: {
197
- returnResult
198
- },
198
+ await sns.publishAsync(_izContext, {
199
+ Message: JSON.stringify({ returnResult }),
199
200
  TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
200
201
  _izContext,
201
202
  'ConfirmUsage_Out'
@@ -133,8 +133,8 @@ export default async function CreateTargetRole(_izContext, requestParams) {
133
133
  }
134
134
  }
135
135
 
136
- await sns.publishMessage(_izContext, {
137
- message: { returnResult: { roleId, roleIdKey } },
136
+ await sns.publishAsync(_izContext, {
137
+ Message: JSON.stringify({ returnResult: { roleId, roleIdKey } }),
138
138
  TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
139
139
  _izContext,
140
140
  'CreateTargetRole_Out'
@@ -82,8 +82,8 @@ export default async function DeleteTargetRole(_izContext, requestParams) {
82
82
  }
83
83
  }
84
84
 
85
- await sns.publishMessage(_izContext, {
86
- message: { returnResult: { identifiersConcat, roleIdKey, status: 'deleted' } },
85
+ await sns.publishAsync(_izContext, {
86
+ Message: JSON.stringify({ returnResult: { identifiersConcat, roleIdKey, status: 'deleted' } }),
87
87
  TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
88
88
  _izContext,
89
89
  'DeleteTargetRole_Out'
@@ -95,8 +95,8 @@ export default async function GetMyPermissions(_izContext, requestParams) {
95
95
  permissions: permissionsMap
96
96
  };
97
97
 
98
- await sns.publishMessage(_izContext, {
99
- message: { returnResult: result },
98
+ await sns.publishAsync(_izContext, {
99
+ Message: JSON.stringify({ returnResult: result }),
100
100
  TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
101
101
  _izContext,
102
102
  'GetMyPermissions_Out'
@@ -47,8 +47,8 @@ export default async function GetTargetRole(_izContext, requestParams) {
47
47
  users: usersResult?.Items || []
48
48
  };
49
49
 
50
- await sns.publishMessage(_izContext, {
51
- message: { returnResult: result },
50
+ await sns.publishAsync(_izContext, {
51
+ Message: JSON.stringify({ returnResult: result }),
52
52
  TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
53
53
  _izContext,
54
54
  'GetTargetRole_Out'
@@ -41,8 +41,8 @@ export default async function <%- flowTag %>(_izContext, requestParams) {
41
41
  dynamodbSharedLib.tableName(_izContext, '<%- tableName %>'),
42
42
  queryParams
43
43
  );
44
- await sns.publishMessage(_izContext, {
45
- message: { returnResult: { records: resultQuery.Items || [] } },
44
+ await sns.publishAsync(_izContext, {
45
+ Message: JSON.stringify({ returnResult: { records: resultQuery.Items || [] } }),
46
46
  TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
47
47
  _izContext,
48
48
  '<%- flowTag %>_Out'
@@ -28,8 +28,8 @@ export default async function <%- flowTag %>(_izContext, requestParams) {
28
28
  dynamodbSharedLib.tableName(_izContext, '<%- tableName %>'),
29
29
  { <%- fieldList %> }
30
30
  );
31
- await sns.publishMessage(_izContext, {
32
- message: { returnResult: { <%- fieldList %> } },
31
+ await sns.publishAsync(_izContext, {
32
+ Message: JSON.stringify({ returnResult: { <%- fieldList %> } }),
33
33
  TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
34
34
  _izContext,
35
35
  '<%- flowTag %>_Out'
@@ -197,7 +197,7 @@ export default async function ReservedDynamicUsage(_izContext, requestParams) {
197
197
  };
198
198
 
199
199
  const eventSourceTag =
200
- _izContext.izEventSource?.eventSourceTag ||
200
+ _izContext?.izEventSource?.eventSourceTag ||
201
201
  requestParams?.izEventSource?.eventSourceTag;
202
202
 
203
203
  let isSync = false;
@@ -205,14 +205,17 @@ export default async function ReservedDynamicUsage(_izContext, requestParams) {
205
205
  eventSourceTag === 'DirectInvoke' ||
206
206
  eventSourceTag === 'ApiGateway' ||
207
207
  eventSourceTag === 'ApiGatewayV2' ||
208
- requestParams?.hasOwnProperty('__context__')
208
+ requestParams?.hasOwnProperty('__context__') ||
209
+ _izContext?.functionName?.endsWith('HdrInv') ||
210
+ _izContext?.functionName?.endsWith('HdrApi') ||
211
+ eventSourceTag !== 'Sqs'
209
212
  ) {
210
213
  isSync = true;
211
214
  }
212
215
 
213
216
  if (!isSync) {
214
- await sns.publishMessage(_izContext, {
215
- message: { returnResult },
217
+ await sns.publishAsync(_izContext, {
218
+ Message: JSON.stringify({ returnResult }),
216
219
  TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
217
220
  _izContext,
218
221
  'ReservedDynamicUsage_Out'
@@ -93,8 +93,8 @@ export default async function UpdateTargetRole(_izContext, requestParams) {
93
93
  }
94
94
  }
95
95
 
96
- await sns.publishMessage(_izContext, {
97
- message: { returnResult: { roleIdKey, status: 'updated' } },
96
+ await sns.publishAsync(_izContext, {
97
+ Message: JSON.stringify({ returnResult: { roleIdKey, status: 'updated' } }),
98
98
  TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
99
99
  _izContext,
100
100
  'UpdateTargetRole_Out'
@@ -54,8 +54,8 @@ export default async function <%- flowTag %>(_izContext, requestParams) {
54
54
  }
55
55
  }
56
56
  ]);
57
- await sns.publishMessage(_izContext, {
58
- message: { returnResult: { userId, roleIdKey } },
57
+ await sns.publishAsync(_izContext, {
58
+ Message: JSON.stringify({ returnResult: { userId, roleIdKey } }),
59
59
  TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
60
60
  _izContext,
61
61
  '<%- flowTag %>_Out'
@@ -102,7 +102,8 @@ export async function renderOut(state) {
102
102
  renderResourceTemplate('FlowOut_Yaml.ejs', { topicName })
103
103
  )
104
104
  );
105
- const body = renderedTopics.join('\n');
105
+ const fileHook = '#<#customTopicOut#>\n#<#/customTopicOut#>';
106
+ const body = [...renderedTopics, fileHook].filter(Boolean).join('\n');
106
107
  return `Resources:\n${indentYaml(body, 2)}`;
107
108
  }
108
109
 
@@ -4,3 +4,5 @@ Out<%- topicName %>:
4
4
  Properties:
5
5
  DisplayName: 'SNS Message out'
6
6
  TopicName: ${self:custom.iz_serviceTag}_${self:custom.iz_stage}_<%- topicName %>_Out
7
+ #<#Out<%- topicName %>TopicSetting#>
8
+ #<#/Out<%- topicName %>TopicSetting#>
@@ -964,3 +964,23 @@ test('roleStatements emits s3:GetObject for custom S3 flow bucket', async () =>
964
964
  assert.match(uploadRole, /arn:aws:s3:::UploadBucket\/\*/);
965
965
  });
966
966
 
967
+ test('emits per-topic hook tags in generated-sns-out.yml', async () => {
968
+ const rootPath = await createProject();
969
+ await generateResourceArtifacts(rootPath);
970
+ const snsOut = await readFile(
971
+ join(rootPath, 'resource/sls_yaml/generatedCode/source/generated-sns-out.yml'),
972
+ 'utf8'
973
+ );
974
+ assert.match(snsOut, /#<#Out\w+TopicSetting#>\s*#<#\/Out\w+TopicSetting#>/);
975
+ });
976
+
977
+ test('emits customTopicOut file-level hook in generated-sns-out.yml', async () => {
978
+ const rootPath = await createProject();
979
+ await generateResourceArtifacts(rootPath);
980
+ const snsOut = await readFile(
981
+ join(rootPath, 'resource/sls_yaml/generatedCode/source/generated-sns-out.yml'),
982
+ 'utf8'
983
+ );
984
+ assert.match(snsOut, /#<#customTopicOut#>\s*#<#\/customTopicOut#>/);
985
+ });
986
+
@@ -402,4 +402,53 @@ test('warns when source content contains custom code in hook missing from templa
402
402
  }
403
403
  });
404
404
 
405
+ test('preserves custom settings inside Out<topicName>TopicSetting and customTopicOut in generated-sns-out.yml', async () => {
406
+ const tmpDir = await mkdtemp(path.join(os.tmpdir(), 'mergeHooks-test-'));
407
+ try {
408
+ const filePath = 'resource/sls_yaml/generatedCode/source/generated-sns-out.yml';
409
+ const diskContent = [
410
+ 'Resources:',
411
+ ' ##===== [Topic Out]',
412
+ ' OutCreate:',
413
+ ' Type: AWS::SNS::Topic',
414
+ ' Properties:',
415
+ " DisplayName: 'SNS Message out'",
416
+ ' TopicName: ${self:custom.iz_serviceTag}_${self:custom.iz_stage}_Create_Out',
417
+ ' #<#OutCreateTopicSetting#>',
418
+ ' FifoTopic: true',
419
+ ' #<#/OutCreateTopicSetting#>',
420
+ '',
421
+ ' #<#customTopicOut#>',
422
+ ' OutCustomNotification:',
423
+ ' Type: AWS::SNS::Topic',
424
+ ' #<#/customTopicOut#>'
425
+ ].join('\n') + '\n';
426
+ await writeTestFile(tmpDir, filePath, diskContent);
427
+
428
+ const generatedArtifact = {
429
+ path: filePath,
430
+ content: [
431
+ 'Resources:',
432
+ ' ##===== [Topic Out]',
433
+ ' OutCreate:',
434
+ ' Type: AWS::SNS::Topic',
435
+ ' Properties:',
436
+ " DisplayName: 'SNS Message out'",
437
+ ' TopicName: ${self:custom.iz_serviceTag}_${self:custom.iz_stage}_Create_Out',
438
+ ' #<#OutCreateTopicSetting#>',
439
+ ' #<#/OutCreateTopicSetting#>',
440
+ '',
441
+ ' #<#customTopicOut#>',
442
+ ' #<#/customTopicOut#>'
443
+ ].join('\n') + '\n'
444
+ };
445
+
446
+ const [result] = await mergeHooks(tmpDir, [generatedArtifact]);
447
+ assert.match(result.content, /FifoTopic: true/);
448
+ assert.match(result.content, /OutCustomNotification:/);
449
+ } finally {
450
+ await rm(tmpDir, { recursive: true, force: true });
451
+ }
452
+ });
453
+
405
454