@izara_project/izara-core-generate-service-code 1.0.91 → 1.0.93

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 (36) hide show
  1. package/package.json +7 -10
  2. package/src/compile/flowValidator.js +6 -0
  3. package/src/compile/loadSchemas.js +195 -69
  4. package/src/emit/coreFunction/templates/UploadSchema_Main.ejs +2 -2
  5. package/src/emit/crud/generateCrudApplicationArtifacts.js +15 -17
  6. package/src/emit/crud/generateDynamicCrudFlowSchemas.js +16 -21
  7. package/src/emit/crud/loadLocalSchemaArrays.js +4 -8
  8. package/src/emit/custom/customFlowPaths.js +149 -0
  9. package/src/emit/custom/customFlowS3.js +156 -0
  10. package/src/emit/custom/customFlowSteps.js +385 -0
  11. package/src/emit/custom/customFlowTemplates.js +28 -0
  12. package/src/emit/custom/customFlows.js +48 -19
  13. package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +57 -692
  14. package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +27 -25
  15. package/src/emit/error/emitErrorSchemas.js +73 -0
  16. package/src/emit/error/templates/errorSchema.ejs +8 -0
  17. package/src/emit/rbac/generateCreateTargetRoleHandler.js +11 -13
  18. package/src/emit/rbac/generateDynamicRbacFlowSchemas.js +14 -18
  19. package/src/emit/relationship/generateDynamicRelationshipFlowSchemas.js +16 -19
  20. package/src/emit/relationship/generateRelationshipApplicationArtifacts.js +19 -19
  21. package/src/emit/resource/dynamoResourceArtifacts.js +18 -0
  22. package/src/emit/resource/emitResourceArtifacts.js +13 -1247
  23. package/src/emit/resource/generateResourceArtifacts.js +20 -20
  24. package/src/emit/resource/iamResourceArtifacts.js +612 -0
  25. package/src/emit/resource/resourceState.js +564 -0
  26. package/src/emit/resource/resourceTemplate.js +30 -0
  27. package/src/emit/resource/s3ResourceArtifacts.js +14 -0
  28. package/src/emit/resource/sqsResourceArtifacts.js +113 -0
  29. package/src/emit/shared/runSubsystemGeneration.js +55 -0
  30. package/src/emit/system/emitSystemWebSocketArtifacts.js +2 -1
  31. package/src/generate.js +37 -4
  32. package/test/crudApplicationArtifacts.test.js +72 -0
  33. package/test/customFlowApplicationArtifacts.test.js +98 -0
  34. package/test/errorSchemas.test.js +154 -0
  35. package/test/publicApi.test.js +1 -1
  36. package/test/resourceArtifacts.test.js +99 -0
@@ -1,7 +1,5 @@
1
- import { buildGenerationPlan } from '../../plan/buildGenerationPlan.js';
2
- import { commitArtifacts } from '../../output/commitArtifacts.js';
3
- import { compileProject } from '../../compile/compileProject.js';
4
1
  import { loadLocalSchemaDirectory } from '../../compile/loadSchemas.js';
2
+ import { runSubsystemGeneration } from '../shared/runSubsystemGeneration.js';
5
3
  import {
6
4
  customFlowApplicationManagedPaths,
7
5
  emitCustomFlowApplicationArtifacts
@@ -16,27 +14,31 @@ export async function generateCustomFlowApplicationArtifacts(
16
14
  rootPath,
17
15
  options = {}
18
16
  ) {
19
- const project = compileProject({ ...options, rootPath });
20
- const [flows, objects] = await Promise.all([
21
- loadLocalSchemaDirectory(project, 'FlowSchemas'),
22
- loadLocalSchemaDirectory(project, 'ObjectSchemas')
23
- ]);
24
- const system = await emitSystemWebSocketArtifacts(flows);
25
- const custom = await emitCustomFlowApplicationArtifacts(flows, {
26
- systemFunctions: system.functions,
27
- objects
17
+ return await runSubsystemGeneration({
18
+ rootPath,
19
+ options,
20
+ loadInputs: async (project) => {
21
+ const [flows, objects] = await Promise.all([
22
+ loadLocalSchemaDirectory(project, 'FlowSchemas'),
23
+ loadLocalSchemaDirectory(project, 'ObjectSchemas')
24
+ ]);
25
+ return { flows, objects };
26
+ },
27
+ emitArtifacts: async ({ flows, objects }) => {
28
+ const system = await emitSystemWebSocketArtifacts(flows);
29
+ const custom = await emitCustomFlowApplicationArtifacts(flows, {
30
+ systemFunctions: system.functions,
31
+ objects
32
+ });
33
+ return [...system.artifacts, ...custom];
34
+ },
35
+ managedScope: 'custom-flow-application',
36
+ resolveManagedPaths: ({ flows, objects }) => [
37
+ ...systemWebSocketManagedPaths(),
38
+ ...customFlowApplicationManagedPaths(flows, {
39
+ includeYaml: hasSystemWebSocket(flows),
40
+ objects
41
+ })
42
+ ]
28
43
  });
29
- const artifacts = [...system.artifacts, ...custom];
30
- const files = await commitArtifacts(
31
- buildGenerationPlan(project, artifacts, {
32
- managedPaths: [
33
- ...systemWebSocketManagedPaths(),
34
- ...customFlowApplicationManagedPaths(flows, {
35
- includeYaml: hasSystemWebSocket(flows), objects
36
- })
37
- ],
38
- managedScope: 'custom-flow-application'
39
- })
40
- );
41
- return { project, files };
42
44
  }
@@ -0,0 +1,73 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import ejsLib from 'ejs';
3
+
4
+ const TEMPLATE_URL = new URL('./templates/', import.meta.url);
5
+ export const ERROR_SCHEMA_PATH =
6
+ 'app/src/schemas/ErrorSchemas/generateCode/errorSchema.js';
7
+
8
+ export function errorSchemaManagedPaths(errors = []) {
9
+ if (!errors || errors.length === 0) {
10
+ return [];
11
+ }
12
+ return [ERROR_SCHEMA_PATH];
13
+ }
14
+
15
+ /**
16
+ * Emits errorSchema.js artifact based on loaded ErrorSchemas
17
+ *
18
+ * @param {Object} params
19
+ * @param {Object} params.project
20
+ * @param {Array} [params.errors=[]]
21
+ * @param {Array} [params.objectGraphServiceTags=[]]
22
+ * @returns {Promise<Array<{path: string, content: string}>>}
23
+ */
24
+ export async function emitErrorSchemas({
25
+ project = {},
26
+ errors = [],
27
+ objectGraphServiceTags = []
28
+ } = {}) {
29
+ const safeErrors = Array.isArray(errors) ? errors : [];
30
+ if (safeErrors.length === 0) {
31
+ return [];
32
+ }
33
+
34
+ const defaultGraphServiceTag =
35
+ objectGraphServiceTags[0] || 'GraphHandler';
36
+ const defaultServiceTag = project?.serviceTag || '';
37
+
38
+ const errorTypes = {};
39
+ for (const item of safeErrors) {
40
+ if (!item || typeof item !== 'object' || !item.errorTag) {
41
+ continue;
42
+ }
43
+ const errorTag = item.errorTag;
44
+ const serviceTag = item.serviceTag || defaultServiceTag;
45
+ errorTypes[errorTag] = {
46
+ errorTag,
47
+ serviceTag
48
+ };
49
+ }
50
+
51
+ const sortedKeys = Object.keys(errorTypes).sort();
52
+ if (sortedKeys.length === 0) {
53
+ return [];
54
+ }
55
+
56
+ const sortedErrorTypes = {};
57
+ for (const key of sortedKeys) {
58
+ sortedErrorTypes[key] = errorTypes[key];
59
+ }
60
+
61
+ const templatePath = new URL('errorSchema.ejs', TEMPLATE_URL);
62
+ const template = await readFile(templatePath, 'utf8');
63
+ const content = ejsLib.render(template, {
64
+ errorTypes: sortedErrorTypes
65
+ });
66
+
67
+ return [
68
+ {
69
+ path: ERROR_SCHEMA_PATH,
70
+ content
71
+ }
72
+ ];
73
+ }
@@ -0,0 +1,8 @@
1
+ export const ERROR_TYPES = {
2
+ <% Object.keys(errorTypes).forEach((key, index, arr) => { -%>
3
+ <%- key %>: {
4
+ errorTag: '<%- errorTypes[key].errorTag %>',
5
+ serviceTag: '<%- errorTypes[key].serviceTag %>'
6
+ }<%= index < arr.length - 1 ? ',' : '' %>
7
+ <% }); -%>
8
+ };
@@ -1,21 +1,19 @@
1
- import { buildGenerationPlan } from '../../plan/buildGenerationPlan.js';
2
- import { commitArtifacts } from '../../output/commitArtifacts.js';
3
- import { compileProject } from '../../compile/compileProject.js';
4
1
  import { loadLocalSchemaDirectory } from '../../compile/loadSchemas.js';
2
+ import { runSubsystemGeneration } from '../shared/runSubsystemGeneration.js';
5
3
  import {
6
4
  emitRbacApplicationArtifacts,
7
5
  rbacApplicationManagedPaths
8
6
  } from './emitRbacApplicationArtifacts.js';
9
7
 
10
8
  export async function generateCreateTargetRoleHandler(rootPath, options = {}) {
11
- const project = compileProject({ ...options, rootPath });
12
- const objects = await loadLocalSchemaDirectory(project, 'ObjectSchemas');
13
- const artifacts = await emitRbacApplicationArtifacts(objects);
14
- const files = await commitArtifacts(
15
- buildGenerationPlan(project, artifacts, {
16
- managedPaths: rbacApplicationManagedPaths(),
17
- managedScope: 'rbac-application'
18
- })
19
- );
20
- return { project, files };
9
+ return await runSubsystemGeneration({
10
+ rootPath,
11
+ options,
12
+ loadInputs: async (project) => ({
13
+ objects: await loadLocalSchemaDirectory(project, 'ObjectSchemas')
14
+ }),
15
+ emitArtifacts: ({ objects }) => emitRbacApplicationArtifacts(objects),
16
+ managedScope: 'rbac-application',
17
+ resolveManagedPaths: () => rbacApplicationManagedPaths()
18
+ });
21
19
  }
@@ -1,27 +1,23 @@
1
- import { buildGenerationPlan } from '../../plan/buildGenerationPlan.js';
2
- import { commitArtifacts } from '../../output/commitArtifacts.js';
3
- import { compileProject } from '../../compile/compileProject.js';
4
1
  import { loadLocalSchemaDirectory } from '../../compile/loadSchemas.js';
2
+ import { runSubsystemGeneration } from '../shared/runSubsystemGeneration.js';
5
3
  import {
6
4
  emitDynamicRbacFlowSchemas,
7
5
  rbacFlowSchemaManagedPaths
8
6
  } from './emitDynamicRbacFlowSchemas.js';
9
7
 
10
8
  export async function generateDynamicRbacFlowSchemas(rootPath, options = {}) {
11
- const project = compileProject({ ...options, rootPath });
12
- const objects = await loadLocalSchemaDirectory(project, 'ObjectSchemas');
13
- const plan = buildGenerationPlan(
14
- project,
15
- await emitDynamicRbacFlowSchemas({
16
- objects,
17
- serviceTag: project.serviceTag
9
+ return await runSubsystemGeneration({
10
+ rootPath,
11
+ options,
12
+ loadInputs: async (project) => ({
13
+ objects: await loadLocalSchemaDirectory(project, 'ObjectSchemas')
18
14
  }),
19
- {
20
- managedPaths: rbacFlowSchemaManagedPaths(objects),
21
- managedScope: 'rbac-flow-schemas'
22
- }
23
- );
24
- const files = await commitArtifacts(plan);
25
-
26
- return { project, files };
15
+ emitArtifacts: ({ objects, project }) =>
16
+ emitDynamicRbacFlowSchemas({
17
+ objects,
18
+ serviceTag: project.serviceTag
19
+ }),
20
+ managedScope: 'rbac-flow-schemas',
21
+ resolveManagedPaths: ({ objects }) => rbacFlowSchemaManagedPaths(objects)
22
+ });
27
23
  }
@@ -1,7 +1,5 @@
1
- import { buildGenerationPlan } from '../../plan/buildGenerationPlan.js';
2
- import { commitArtifacts } from '../../output/commitArtifacts.js';
3
- import { compileProject } from '../../compile/compileProject.js';
4
1
  import { loadLocalSchemaDirectory } from '../../compile/loadSchemas.js';
2
+ import { runSubsystemGeneration } from '../shared/runSubsystemGeneration.js';
5
3
  import {
6
4
  dynamicRelationshipFlowSchemaManagedPaths,
7
5
  emitDynamicRelationshipFlowSchemas
@@ -11,20 +9,19 @@ export async function generateDynamicRelationshipFlowSchemas(
11
9
  rootPath,
12
10
  options = {}
13
11
  ) {
14
- const project = compileProject({ ...options, rootPath });
15
- const relationships = await loadLocalSchemaDirectory(
16
- project,
17
- 'RelationshipSchemas'
18
- );
19
- const plan = buildGenerationPlan(
20
- project,
21
- emitDynamicRelationshipFlowSchemas({ relationships }),
22
- {
23
- managedPaths: dynamicRelationshipFlowSchemaManagedPaths(relationships),
24
- managedScope: 'relationship-flow-schemas'
25
- }
26
- );
27
- const files = await commitArtifacts(plan);
28
-
29
- return { project, files };
12
+ return await runSubsystemGeneration({
13
+ rootPath,
14
+ options,
15
+ loadInputs: async (project) => ({
16
+ relationships: await loadLocalSchemaDirectory(
17
+ project,
18
+ 'RelationshipSchemas'
19
+ )
20
+ }),
21
+ emitArtifacts: ({ relationships }) =>
22
+ emitDynamicRelationshipFlowSchemas({ relationships }),
23
+ managedScope: 'relationship-flow-schemas',
24
+ resolveManagedPaths: ({ relationships }) =>
25
+ dynamicRelationshipFlowSchemaManagedPaths(relationships)
26
+ });
30
27
  }
@@ -1,7 +1,5 @@
1
- import { buildGenerationPlan } from '../../plan/buildGenerationPlan.js';
2
- import { commitArtifacts } from '../../output/commitArtifacts.js';
3
- import { compileProject } from '../../compile/compileProject.js';
4
1
  import { loadLocalSchemaDirectory } from '../../compile/loadSchemas.js';
2
+ import { runSubsystemGeneration } from '../shared/runSubsystemGeneration.js';
5
3
  import {
6
4
  emitRelationshipApplicationArtifacts,
7
5
  relationshipApplicationManagedPaths
@@ -11,21 +9,23 @@ export async function generateRelationshipApplicationArtifacts(
11
9
  rootPath,
12
10
  options = {}
13
11
  ) {
14
- const project = compileProject({ ...options, rootPath });
15
- const [relationships, flows] = await Promise.all([
16
- loadLocalSchemaDirectory(project, 'RelationshipSchemas'),
17
- loadLocalSchemaDirectory(project, 'FlowSchemas')
18
- ]);
19
- const artifacts = await emitRelationshipApplicationArtifacts({
20
- relationships,
21
- flows,
22
- serviceTag: project.serviceTag
12
+ return await runSubsystemGeneration({
13
+ rootPath,
14
+ options,
15
+ loadInputs: async (project) => {
16
+ const [relationships, flows] = await Promise.all([
17
+ loadLocalSchemaDirectory(project, 'RelationshipSchemas'),
18
+ loadLocalSchemaDirectory(project, 'FlowSchemas')
19
+ ]);
20
+ return { relationships, flows };
21
+ },
22
+ emitArtifacts: ({ relationships, flows, project }) =>
23
+ emitRelationshipApplicationArtifacts({
24
+ relationships,
25
+ flows,
26
+ serviceTag: project.serviceTag
27
+ }),
28
+ managedScope: 'relationship-application',
29
+ resolveManagedPaths: () => relationshipApplicationManagedPaths()
23
30
  });
24
- const files = await commitArtifacts(
25
- buildGenerationPlan(project, artifacts, {
26
- managedPaths: relationshipApplicationManagedPaths(),
27
- managedScope: 'relationship-application'
28
- })
29
- );
30
- return { project, files };
31
31
  }
@@ -0,0 +1,18 @@
1
+ import { indentYaml, renderResourceTemplate } from './resourceTemplate.js';
2
+
3
+ export async function renderDynamo(state) {
4
+ const [system, ...tables] = await Promise.all([
5
+ renderResourceTemplate('SystemDynamoDB_Yaml.ejs', {
6
+ hasS3: state.s3FlowTags.length > 0,
7
+ hasRbac: state.selfRbac
8
+ }),
9
+ ...state.tables.map((table) =>
10
+ renderResourceTemplate('DynamoDBTable_Yaml.ejs', table)
11
+ )
12
+ ]);
13
+ const indentedTables = tables.map((t) => indentYaml(t, 2)).join('\n');
14
+ if (indentedTables) {
15
+ return `${system}\n${indentedTables}`;
16
+ }
17
+ return `${system}`;
18
+ }