@izara_project/izara-core-generate-service-code 1.0.99 → 1.0.100

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 (50) hide show
  1. package/package.json +1 -1
  2. package/src/compile/compileProject.js +16 -5
  3. package/src/compile/flowValidator.js +3 -1
  4. package/src/compile/loadSchemas.js +18 -4
  5. package/src/compile/schemaValidatorSetup.js +16 -0
  6. package/src/emit/application/coreFunction/emitCoreFunctionArtifacts.js +108 -108
  7. package/src/emit/application/coreFunction/templates/InitialSetupRunner.ejs +2 -2
  8. package/src/emit/application/crud/templates/CreateComplete_Main.ejs +2 -0
  9. package/src/emit/application/crud/templates/CreateLogicalLib.ejs +14 -7
  10. package/src/emit/application/crud/templates/DeleteComplete_Main.ejs +2 -0
  11. package/src/emit/application/crud/templates/FlowEndpoint_HdrWbs.ejs +7 -5
  12. package/src/emit/application/crud/templates/UpdateComplete_Main.ejs +2 -0
  13. package/src/emit/application/custom/customFlowPaths.js +13 -16
  14. package/src/emit/application/custom/customFlowS3.js +274 -63
  15. package/src/emit/application/custom/customFlows.js +131 -0
  16. package/src/emit/application/custom/emitCustomFlowApplicationArtifacts.js +3 -1
  17. package/src/emit/application/custom/templates/s3/ConfirmAfterUpload_HdrSqs.ejs +110 -0
  18. package/src/emit/application/custom/templates/s3/ConfirmAfterUpload_Main.ejs +89 -0
  19. package/src/emit/application/custom/templates/s3/ConfirmComplete_HdrSqs.ejs +110 -0
  20. package/src/emit/application/custom/templates/s3/ConfirmComplete_Main.ejs +89 -0
  21. package/src/emit/application/custom/templates/s3/CreateObject_HdrWbs.ejs +2 -1
  22. package/src/emit/application/custom/templates/s3/CreateObject_Main.ejs +4 -0
  23. package/src/emit/application/custom/templates/s3/CreatePreSignUrl_HdrSqs.ejs +42 -0
  24. package/src/emit/application/custom/templates/s3/CreatePreSignUrl_Main.ejs +23 -0
  25. package/src/emit/application/custom/templates/s3/ProcessS3File_Main.ejs +135 -27
  26. package/src/emit/application/custom/templates/s3/Start_Main.ejs +197 -0
  27. package/src/emit/application/rbac/emitDynamicRbacFlowSchemas.js +5 -1
  28. package/src/emit/application/rbac/emitRbacApplicationArtifacts.js +67 -60
  29. package/src/emit/application/rbac/templates/ReservedDynamicUsage_Main.ejs +27 -9
  30. package/src/emit/application/rbac/templates/UserRbacFlow_Main.ejs +4 -3
  31. package/src/emit/application/system/templates/Register_HdrWbs.ejs +2 -1
  32. package/src/emit/infrastructure/functions/functionYamlArtifact.js +3 -8
  33. package/src/emit/infrastructure/functions/templates/S3Function_Yaml.ejs +2 -3
  34. package/src/emit/infrastructure/resources/iamResourceArtifacts.js +22 -0
  35. package/src/emit/infrastructure/resources/resourceState.js +15 -5
  36. package/src/emit/infrastructure/resources/s3ResourceArtifacts.js +19 -3
  37. package/src/emit/infrastructure/resources/templates/S3Bucket_Yaml.ejs +1 -1
  38. package/src/emit/infrastructure/resources/templates/SystemDynamoDB_Yaml.ejs +2 -2
  39. package/src/emit/schemas/error/emitErrorSchemas.js +120 -10
  40. package/src/emit/schemas/error/templates/errorConsts.ejs +12 -0
  41. package/src/generate.js +32 -30
  42. package/test/integration/publicApi.test.js +33 -24
  43. package/test/unit/application/createTargetRoleHandler.test.js +33 -10
  44. package/test/unit/application/customFlowApplicationArtifacts.test.js +6 -6
  45. package/test/unit/application/customFlowS3.test.js +730 -0
  46. package/test/unit/infrastructure/functionYamlArtifact.test.js +6 -4
  47. package/test/unit/infrastructure/resourceArtifacts.test.js +51 -0
  48. package/test/unit/schemas/dynamicRbacFlowSchemas.test.js +8 -6
  49. package/test/unit/schemas/dynamicRelationshipFlowSchemas.test.js +51 -0
  50. package/test/unit/schemas/errorSchemas.test.js +84 -5
@@ -0,0 +1,89 @@
1
+ /*
2
+ Copyright (C) 2026 Sven Mason <http://izara.io>
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU Affero General Public License as
6
+ published by the Free Software Foundation, either version 3 of the
7
+ License, or (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU Affero General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Affero General Public License
15
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
19
+ import { webSocket } from '@izara_project/izara-core-library-external-request';
20
+ const { postToConnection } = webSocket;
21
+ import { utils } from '@izara_project/izara-core-library-service-schemas';
22
+ const { createFlowTypeConcat } = utils;
23
+
24
+ //(<optionalRequired>)
25
+ //(</optionalRequired>)
26
+
27
+ /**
28
+ * Step 3: ConfirmAfterUpload (Deferred-Node S3 Pipeline - ADR-016)
29
+ * SQS handler receiving objInstanceFull from OutCreate SNS topic.
30
+ * Confirms storage quota, queries WebSocketTask, and notifies client via WebSocket.
31
+ *
32
+ * @param {Object} _izContext
33
+ * @param {Object} objType
34
+ * @param {Object} objInstanceFull
35
+ * @param {Object} passBackProperties
36
+ * @returns {Promise<Object>}
37
+ */
38
+ export default async function <%- functionName %>(
39
+ _izContext,
40
+ objType,
41
+ objInstanceFull,
42
+ //(<additionalProperties>)
43
+ //(</additionalProperties>)
44
+ passBackProperties = {}
45
+ ) {
46
+ try {
47
+ _izContext.logger.debug('----- <%- functionName %> started -----', {
48
+ objType,
49
+ objInstanceFull,
50
+ passBackProperties
51
+ });
52
+
53
+ const targetId =
54
+ objInstanceFull.identifiers?.<%- objectType %>Id ||
55
+ Object.values(objInstanceFull.identifiers || {})[0];
56
+
57
+ //(<confirmUsageHook>)
58
+ //(</confirmUsageHook>)
59
+
60
+ const taskKey = `${createFlowTypeConcat(_izContext, { flowTag: '<%- flowTag %>', serviceTag: process.env.iz_serviceTag })}${targetId}`;
61
+ const taskRecord = await dynamodbSharedLib.getItem(
62
+ _izContext,
63
+ await dynamodbSharedLib.tableName(_izContext, 'WebSocketTask'),
64
+ { taskKey: taskKey }
65
+ );
66
+
67
+ if (taskRecord && taskRecord.connectionId) {
68
+ await postToConnection(
69
+ _izContext,
70
+ {
71
+ status: 'completed',
72
+ data: {
73
+ <%- objectType %>Id: targetId,
74
+ objInstanceFull: objInstanceFull
75
+ }
76
+ },
77
+ taskRecord.connectionId
78
+ );
79
+ }
80
+
81
+ return {
82
+ status: 'completed',
83
+ objInstanceFull: objInstanceFull
84
+ };
85
+ } catch (err) {
86
+ _izContext.logger.error('Error in <%- functionName %>: ', err);
87
+ throw err;
88
+ }
89
+ }
@@ -0,0 +1,110 @@
1
+ /*
2
+ Copyright (C) 2026 Sven Mason <http://izara.io>
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU Affero General Public License as
6
+ published by the Free Software Foundation, either version 3 of the
7
+ License, or (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU Affero General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Affero General Public License
15
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ import { middlewareHandler as middleware } from '@izara_project/izara-middleware';
19
+ import { recordHandlerSharedLib } from '@izara_project/izara-core-library-record-handler';
20
+ import Logger from '@izara_project/izara-core-library-logger';
21
+ import callingFlowSharedLib from '@izara_project/izara-core-library-calling-flow';
22
+
23
+ import <%= functionName %> from './<%= functionName %>_Main.js';
24
+
25
+ middleware.setValidatorSchema(recordHandlerSharedLib.baseValidatorSchema());
26
+
27
+ let perRecordsValidatorSchema = {
28
+ type: 'object',
29
+ required: ['objType', 'objInstanceFull'],
30
+ properties: {
31
+ objType: {
32
+ type: 'object',
33
+ required: ['objectType', 'serviceTag'],
34
+ properties: {
35
+ objectType: {
36
+ type: 'string',
37
+ pattern: '^[a-zA-Z0-9_-]+$'
38
+ },
39
+ serviceTag: {
40
+ type: 'string',
41
+ pattern: '^[a-zA-Z0-9_-]+$'
42
+ }
43
+ }
44
+ },
45
+ objInstanceFull: {
46
+ type: 'object',
47
+ properties: {
48
+ identifiers: {
49
+ type: 'object',
50
+ minProperties: 1
51
+ },
52
+ fields: {
53
+ type: 'object'
54
+ }
55
+ }
56
+ }
57
+ }
58
+ };
59
+
60
+ perRecordsValidatorSchema =
61
+ callingFlowSharedLib.addOptionalPassBackPropertiesToValidatorSchema(
62
+ perRecordsValidatorSchema
63
+ );
64
+
65
+ export const main = middleware.wrap(async (event, context) => {
66
+ try {
67
+ let recordPromises = [];
68
+
69
+ await Promise.all(
70
+ event.Records.map(async (record) => {
71
+ let passOnProperties = [];
72
+ record._izContext.logger.debug('record <%= functionName %><%= handlerType %>', record);
73
+
74
+ await recordHandlerSharedLib.validateRecord(
75
+ record,
76
+ '<%= functionName %><%= handlerType %>',
77
+ perRecordsValidatorSchema
78
+ );
79
+
80
+ passOnProperties.push(record.body.Message.objType);
81
+ passOnProperties.push(record.body.Message.objInstanceFull);
82
+ //(<additionalProperties>)
83
+ //(</additionalProperties>)
84
+ passOnProperties.push(
85
+ callingFlowSharedLib.addPassBackPropertiesToPassOnProperties(
86
+ record.body.Message
87
+ )
88
+ );
89
+
90
+ record._izContext.logger.debug(
91
+ 'passOnProperties in <%= functionName %><%= handlerType %>',
92
+ passOnProperties
93
+ );
94
+
95
+ let returnPromise = await recordHandlerSharedLib.recordHandler(
96
+ record,
97
+ <%= functionName %>,
98
+ passOnProperties
99
+ );
100
+
101
+ recordPromises.push(returnPromise);
102
+ })
103
+ );
104
+
105
+ return await Promise.all(recordPromises);
106
+ } catch (err) {
107
+ Logger.error('Error <%= functionName %><%= handlerType %>: ', err);
108
+ throw err;
109
+ }
110
+ });
@@ -0,0 +1,89 @@
1
+ /*
2
+ Copyright (C) 2026 Sven Mason <http://izara.io>
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU Affero General Public License as
6
+ published by the Free Software Foundation, either version 3 of the
7
+ License, or (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU Affero General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Affero General Public License
15
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
19
+ import { webSocket } from '@izara_project/izara-core-library-external-request';
20
+ const { postToConnection } = webSocket;
21
+ import { utils } from '@izara_project/izara-core-library-service-schemas';
22
+ const { createFlowTypeConcat } = utils;
23
+
24
+ //(<optionalRequired>)
25
+ //(</optionalRequired>)
26
+
27
+ /**
28
+ * Step 3: ConfirmComplete (Deferred-Node S3 Pipeline - ADR-016)
29
+ * SQS handler receiving objInstanceFull from OutCreate SNS topic.
30
+ * Confirms storage quota, queries WebSocketTask, and notifies client via WebSocket.
31
+ *
32
+ * @param {Object} _izContext
33
+ * @param {Object} objType
34
+ * @param {Object} objInstanceFull
35
+ * @param {Object} passBackProperties
36
+ * @returns {Promise<Object>}
37
+ */
38
+ export default async function <%- functionName %>(
39
+ _izContext,
40
+ objType,
41
+ objInstanceFull,
42
+ //(<additionalProperties>)
43
+ //(</additionalProperties>)
44
+ passBackProperties = {}
45
+ ) {
46
+ try {
47
+ _izContext.logger.debug('----- <%- functionName %> started -----', {
48
+ objType,
49
+ objInstanceFull,
50
+ passBackProperties
51
+ });
52
+
53
+ const targetId =
54
+ objInstanceFull.identifiers?.<%- objectType %>Id ||
55
+ Object.values(objInstanceFull.identifiers || {})[0];
56
+
57
+ //(<confirmUsageHook>)
58
+ //(</confirmUsageHook>)
59
+
60
+ const taskKey = `${createFlowTypeConcat(_izContext, { flowTag: '<%- flowTag %>', serviceTag: process.env.iz_serviceTag })}${targetId}`;
61
+ const taskRecord = await dynamodbSharedLib.getItem(
62
+ _izContext,
63
+ await dynamodbSharedLib.tableName(_izContext, 'WebSocketTask'),
64
+ { taskKey: taskKey }
65
+ );
66
+
67
+ if (taskRecord && taskRecord.connectionId) {
68
+ await postToConnection(
69
+ _izContext,
70
+ {
71
+ status: 'completed',
72
+ data: {
73
+ <%- objectType %>Id: targetId,
74
+ objInstanceFull: objInstanceFull
75
+ }
76
+ },
77
+ taskRecord.connectionId
78
+ );
79
+ }
80
+
81
+ return {
82
+ status: 'completed',
83
+ objInstanceFull: objInstanceFull
84
+ };
85
+ } catch (err) {
86
+ _izContext.logger.error('Error in <%- functionName %>: ', err);
87
+ throw err;
88
+ }
89
+ }
@@ -57,7 +57,8 @@ export const main = middleware.wrap(async (event, context) => {
57
57
  ),
58
58
  {
59
59
  taskKey: `${createFlowTypeConcat(event._izContext, { flowTag: '<%- route %>', serviceTag: process.env.iz_serviceTag })}${identifiers}`,
60
- connectionId: connectionId
60
+ connectionId: connectionId,
61
+ expirationTime: Math.floor(Date.now() / 1000) + 7200
61
62
  }
62
63
  );
63
64
 
@@ -127,7 +127,11 @@ export default async function createObject(
127
127
  callingFlowSharedLib.createCallingFlowConfig(
128
128
  await lambdaSharedLib.lambdaFunctionName(
129
129
  _izContext,
130
+ <% if (typeof nextStepFunctionName === 'string' && nextStepFunctionName) { -%>
131
+ '<%- nextStepFunctionName %>'
132
+ <% } else { -%>
130
133
  TOPIC_NAME_GENERATE_CODE.createNodeComplete
134
+ <% } -%>
131
135
  ),
132
136
  {}
133
137
  )
@@ -26,6 +26,40 @@ import <%= functionName %> from './<%= functionName %>_Main.js';
26
26
  middleware.setValidatorSchema(recordHandlerSharedLib.baseValidatorSchema());
27
27
 
28
28
  // set schema for record.body.Message
29
+ <% if (isSimplifiedS3) { -%>
30
+ let perRecordsValidatorSchema = {
31
+ type: 'object',
32
+ required: ['objType', 'objInstanceFull'],
33
+ properties: {
34
+ objType: {
35
+ type: 'object',
36
+ required: ['objectType', 'serviceTag'],
37
+ properties: {
38
+ objectType: {
39
+ type: 'string',
40
+ pattern: '^[a-zA-Z0-9_-]+$'
41
+ },
42
+ serviceTag: {
43
+ type: 'string',
44
+ pattern: '^[a-zA-Z0-9_-]+$'
45
+ }
46
+ }
47
+ },
48
+ objInstanceFull: {
49
+ type: 'object',
50
+ properties: {
51
+ identifiers: {
52
+ type: 'object',
53
+ minProperties: 1
54
+ },
55
+ fields: {
56
+ type: 'object'
57
+ }
58
+ }
59
+ }
60
+ }
61
+ };
62
+ <% } else { -%>
29
63
  let perRecordsValidatorSchema = {
30
64
  type: 'object',
31
65
  required: ['returnMessage', 'foundErrors', 'passStatus'],
@@ -41,6 +75,7 @@ let perRecordsValidatorSchema = {
41
75
  }
42
76
  }
43
77
  };
78
+ <% } -%>
44
79
 
45
80
  // set schema for record.body.MessageAttributes
46
81
  // const messageAttributeValidatorSchema = {
@@ -82,9 +117,16 @@ export const main = middleware.wrap(async (event, context) => {
82
117
  );
83
118
 
84
119
  // add argument (to invoke lambda) to passOnProperties[]
120
+ <% if (isSimplifiedS3) { -%>
121
+ passOnProperties.push(record.body.Message.objType);
122
+ passOnProperties.push(record.body.Message.objInstanceFull);
123
+ passOnProperties.push(record.body.Message.status || 'complete');
124
+ passOnProperties.push(record.body.Message.foundErrors || []);
125
+ <% } else { -%>
85
126
  passOnProperties.push(record.body.Message.returnMessage);
86
127
  passOnProperties.push(record.body.Message.foundErrors);
87
128
  passOnProperties.push(record.body.Message.passStatus);
129
+ <% } -%>
88
130
  //(<additionalProperties>)
89
131
  //(</additionalProperties>)
90
132
  passOnProperties.push(
@@ -60,14 +60,30 @@ const { createFlowTypeConcat } = utils;
60
60
 
61
61
  export default async function createPreSignUrl(
62
62
  _izContext,
63
+ <% if (isSimplifiedS3) { -%>
64
+ objType,
65
+ objInstanceFull,
66
+ status = 'complete',
67
+ foundErrors = [],
68
+ <% } else { -%>
63
69
  returnMessage,
64
70
  foundErrors,
65
71
  passStatus,
72
+ <% } -%>
66
73
  //(<additionalProperties>)
67
74
  //(</additionalProperties>)
68
75
  passBackProperties = {}
69
76
  ) {
70
77
  try {
78
+ <% if (isSimplifiedS3) { -%>
79
+ _izContext.logger.debug('----- createPreSignUrl event params -----', {
80
+ objType: objType,
81
+ objInstanceFull: objInstanceFull,
82
+ status: status,
83
+ foundErrors: foundErrors,
84
+ passBackProperties: passBackProperties
85
+ });
86
+ <% } else { -%>
71
87
  _izContext.logger.debug('----- createPreSignUrl event params -----', {
72
88
  returnMessage: returnMessage,
73
89
  foundErrors: foundErrors,
@@ -80,6 +96,7 @@ export default async function createPreSignUrl(
80
96
  const reservedDataId =
81
97
  passBackProperties.passBackProperties.identifier.reservedDataId;
82
98
  const objType = passBackProperties.passBackProperties.objType;
99
+ <% } -%>
83
100
 
84
101
  const correlationId = _izContext.correlationIds.get(
85
102
  consts.X_CORRELATION_ID
@@ -100,6 +117,7 @@ export default async function createPreSignUrl(
100
117
  //(<afterGetResult>)
101
118
  //(</afterGetResult>)
102
119
 
120
+ <% if (!isSimplifiedS3) { -%>
103
121
  let uniqueIdentify = getNestObject(_izContext, returnMessage, [
104
122
  'limitFound',
105
123
  'runningTotal',
@@ -194,6 +212,7 @@ export default async function createPreSignUrl(
194
212
 
195
213
  return 'reserved not pass';
196
214
  }
215
+ <% } -%>
197
216
 
198
217
  //(<createKeyForUploadFile>)
199
218
  const Key = `${fileName}.${importType}`;
@@ -250,7 +269,11 @@ export default async function createPreSignUrl(
250
269
  callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
251
270
  messageObject,
252
271
  callingFlowSharedLib.addParentCallingFlowConfig(
272
+ <% if (isSimplifiedS3) { -%>
273
+ passBackProperties,
274
+ <% } else { -%>
253
275
  returnMessage, // resive parent callingFlowConfig.
276
+ <% } -%>
254
277
  callingFlowSharedLib.createCallingFlowConfig(
255
278
  // calling flow own service
256
279
  await lambdaSharedLib.lambdaFunctionName(
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (C) 2021 Sven Mason <http://izara.io>
2
+ Copyright (C) 2026 Sven Mason <http://izara.io>
3
3
 
4
4
  This program is free software: you can redistribute it and/or modify
5
5
  it under the terms of the GNU Affero General Public License as
@@ -8,42 +8,40 @@ License, or (at your option) any later version.
8
8
 
9
9
  This program is distributed in the hope that it will be useful,
10
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
12
  GNU Affero General Public License for more details.
13
13
 
14
14
  You should have received a copy of the GNU Affero General Public License
15
- along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  */
17
17
 
18
18
  import {
19
19
  S3Client,
20
20
  GetObjectCommand,
21
- DeleteObjectCommand,
22
- PutObjectCommand,
23
- CopyObjectCommand
21
+ HeadObjectCommand
24
22
  } from '@aws-sdk/client-s3';
25
23
  const s3 = new S3Client({ region: process.env.AWS_REGION });
26
24
 
25
+ import snsSharedLib from '@izara_project/izara-core-library-sns';
26
+ import callingFlowSharedLib from '@izara_project/izara-core-library-calling-flow';
27
+ import lambdaSharedLib from '@izara_project/izara-core-library-lambda';
28
+ import { sns } from '@izara_project/izara-core-library-external-request';
29
+
27
30
  //(<optionalRequired>)
28
31
  //(</optionalRequired>)
29
32
 
30
33
  /**
31
- * description of function.
32
- * @param {Object} _izContext
33
- * @param {CorrelationIds} _izContext.correlationIds - property of _izContext
34
- * @param {Logger} _izContext.logger - property of _izContext
35
- * @param {Logger} _izContext.logger.debug - property of _izContext
36
- * @param {Object} bucket - bucket's data
37
- * @param {Array} field - image's data
38
- * @param {Array} importBy - 'webSocket' || 'importData'
39
- * @param {Array} imageImportId - from importData
40
- * @param {Array} realImageSize - from importData
41
- * @param {Array} passBackProperties - from importData
34
+ * Step 2: ProcessAfterUpload (Deferred-Node S3 Pipeline - ADR-016)
35
+ * Triggered by S3 ObjectCreated event. Inspects file, prepares entity payload,
36
+ * and publishes to Create_In SNS topic with callingFlow targeting ConfirmAfterUpload.
42
37
  *
43
- * @returns {object} returnResponse
38
+ * @param {Object} _izContext
39
+ * @param {Object} bucket - S3 bucket record
40
+ * @param {Object} field - S3 object record ({ key, size, eTag })
41
+ * @param {Object} passBackProperties
42
+ * @returns {Promise<Object>}
44
43
  */
45
-
46
- export default async function processAfterUpload(
44
+ export default async function <%- functionName %>(
47
45
  _izContext,
48
46
  bucket,
49
47
  field,
@@ -52,18 +50,128 @@ export default async function processAfterUpload(
52
50
  passBackProperties = {}
53
51
  ) {
54
52
  try {
55
- _izContext.logger.debug('----- process AfterUpload event params ----- ', {
56
- bucket: bucket,
57
- field: field,
58
- //(<loggerAdditionalParams>)
59
- //(</loggerAdditionalParams>)
60
- passBackProperties: passBackProperties
53
+ _izContext.logger.debug('----- <%- functionName %> started -----', {
54
+ bucket,
55
+ field,
56
+ passBackProperties
61
57
  });
62
58
 
59
+ const s3Key = field.key;
60
+ const actualByteSize = field.size;
61
+ const actualSizeMb = actualByteSize / (1024 * 1024);
62
+
63
+ let s3Metadata = {};
64
+ try {
65
+ const headResult = await s3.send(
66
+ new HeadObjectCommand({
67
+ Bucket: bucket.name,
68
+ Key: s3Key
69
+ })
70
+ );
71
+ s3Metadata = headResult.Metadata || {};
72
+ } catch (headErr) {
73
+ _izContext.logger.warn('Could not retrieve S3 object metadata via HeadObjectCommand:', {
74
+ bucket: bucket.name,
75
+ key: s3Key,
76
+ error: headErr.message
77
+ });
78
+ }
79
+
80
+ //(<extractIdentifiersFromKeyOrMetadata>)
81
+ const keyParts = s3Key.split('/');
82
+ let fileNameWithExt = '';
83
+ if (keyParts.length > 0) {
84
+ fileNameWithExt = keyParts[keyParts.length - 1];
85
+ }
86
+ const rawId = fileNameWithExt.split('.')[0];
87
+ let parentId = '';
88
+ if (keyParts.length > 2) {
89
+ parentId = keyParts[keyParts.length - 2];
90
+ }
91
+ <% if (typeof parentIdKeys !== 'undefined' && parentIdKeys && parentIdKeys.length > 1) { -%>
92
+ <% for (let i = 1; i < parentIdKeys.length; i++) { -%>
93
+ let <%- parentIdKeys[i] %> = '';
94
+ if (keyParts.length > <%- 2 + i %>) {
95
+ <%- parentIdKeys[i] %> = keyParts[keyParts.length - <%- 2 + i %>];
96
+ }
97
+ <% } -%>
98
+ <% } -%>
99
+ //(</extractIdentifiersFromKeyOrMetadata>)
100
+
63
101
  //(<endpointHook>)
64
102
  //(</endpointHook>)
103
+
104
+ <% if (typeof nextStepFunctionName === 'string' && nextStepFunctionName) { -%>
105
+ const metaUserId =
106
+ s3Metadata.submittedbyuserid ||
107
+ s3Metadata.submittedByUserId ||
108
+ s3Metadata.userid ||
109
+ s3Metadata.userId ||
110
+ _izContext.userId ||
111
+ '';
112
+ let messageObject = {
113
+ objectType: '<%- objectType %>',
114
+ submittedByUserId: metaUserId,
115
+ identifiers: {
116
+ <%- objectType %>Id: rawId
117
+ },
118
+ <% if (typeof parentIdKeys !== 'undefined' && parentIdKeys && parentIdKeys.length > 1) { -%>
119
+ targetIdentifiers: {
120
+ <%- parentIdKeys[0] %>: parentId,
121
+ <% for (let i = 1; i < parentIdKeys.length; i++) { -%>
122
+ <%- parentIdKeys[i] %>: <%- parentIdKeys[i] %><%- i < parentIdKeys.length - 1 ? ',' : '' %>
123
+ <% } -%>
124
+ },
125
+ <% } else if (typeof parentIdKey !== 'undefined' && parentIdKey) { -%>
126
+ targetIdentifiers: {
127
+ <%- parentIdKey %>: parentId
128
+ },
129
+ <% } -%>
130
+ fieldNames: {
131
+ //(<fieldNamesHook>)
132
+ //(</fieldNamesHook>)
133
+ }
134
+ };
135
+
136
+ messageObject =
137
+ callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
138
+ messageObject,
139
+ callingFlowSharedLib.addParentCallingFlowConfig(
140
+ passBackProperties,
141
+ callingFlowSharedLib.createCallingFlowConfig(
142
+ await lambdaSharedLib.lambdaFunctionName(
143
+ _izContext,
144
+ '<%- nextStepFunctionName %>'
145
+ ),
146
+ {}
147
+ )
148
+ )
149
+ );
150
+
151
+ let sendMessageToCreateEndpoint = {
152
+ Message: JSON.stringify(messageObject),
153
+ TopicArn: snsSharedLib.snsTopicArnByFlowSchema(_izContext, 'Create_In')
154
+ };
155
+
156
+ _izContext.logger.debug(
157
+ 'sendMessageToCreateEndpoint',
158
+ sendMessageToCreateEndpoint
159
+ );
160
+ await sns.publishAsync(_izContext, sendMessageToCreateEndpoint);
161
+
162
+ return {
163
+ status: 'dispatched',
164
+ s3Key,
165
+ messageObject
166
+ };
167
+ <% } else { -%>
168
+ return {
169
+ status: 'processed',
170
+ s3Key
171
+ };
172
+ <% } -%>
65
173
  } catch (err) {
66
- _izContext.logger.error('error ProcessImageAfterUploadMain: ', err);
174
+ _izContext.logger.error('Error in <%- functionName %>: ', err);
67
175
  throw err;
68
176
  }
69
177
  }