@izara_project/izara-core-generate-service-code 1.0.97 → 1.0.98
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 +1 -1
- package/src/compile/loadSchemas.js +29 -6
- package/src/emit/application/crud/templates/FlowEndpoint_HdrWbs.ejs +2 -2
- package/src/emit/application/crud/templates/FlowMain_Wbs.ejs +2 -2
- package/src/emit/application/custom/templates/s3/CreateObject_Main.ejs +5 -2
- package/src/emit/application/custom/templates/triggerCache/CheckTriggerCache_Main.ejs +2 -2
- package/src/emit/application/relationship/templates/ChangeRelationship_Main.ejs +3 -2
- package/src/emit/application/relationship/templates/CreateRelationship_Main.ejs +3 -2
- package/src/emit/application/relationship/templates/DeleteRelationship_Main.ejs +3 -2
- package/src/emit/application/relationship/templates/GetRelationship_Main.ejs +3 -2
- package/src/emit/application/relationship/templates/MoveRelationship_Main.ejs +3 -2
- package/src/emit/application/relationship/templates/UpdateRelationship_Main.ejs +3 -2
- package/src/emit/application/system/templates/RegisterComplete_Main.ejs +6 -2
- package/src/emit/application/system/templates/Register_Main.ejs +6 -2
- package/src/emit/application/system/templates/WebSocketComplete_Main.ejs +3 -3
- package/src/emit/infrastructure/resources/iamResourceArtifacts.js +1 -1
- package/src/emit/schemas/attributeTree/emitAttributeTreeSchemas.js +14 -22
- package/src/emit/schemas/attributeTree/emitAttributeTreeTargetValueStandard.js +132 -0
- package/src/emit/schemas/ledger/emitLedgerSchemas.js +33 -11
- package/src/emit/schemas/ledger/templates/LedgerObjectSchema.ejs +3 -0
- package/src/emit/schemas/ledger/templates/LedgerRelationshipSchema.ejs +1 -0
- package/src/emit/schemas/propertyValue/emitPropertyValueSchemas.js +329 -0
- package/src/generate.js +16 -75
- package/src/output/mergeHooks.js +69 -15
- package/src/plan/domainRegistry.js +41 -5
- package/task.md +132 -0
- package/test/integration/publicApi.test.js +54 -1
- package/test/unit/application/customFlowApplicationArtifacts.test.js +9 -0
- package/test/unit/application/relationshipApplicationArtifacts.test.js +30 -0
- package/test/unit/infrastructure/resourceArtifacts.test.js +1 -0
- package/test/unit/output/mergeHooks.test.js +268 -0
- package/test/unit/schemas/attributeTreeDirectives.test.js +177 -0
- package/test/unit/schemas/attributeTreeSchemas.test.js +10 -61
- package/test/unit/schemas/ledgerSchemas.test.js +33 -7
- package/test/unit/schemas/propertyValueSchemas.test.js +265 -0
- package/src/emit/schemas/attributeTree/emitAttributeTreeTargetSchemas.js +0 -153
- package/src/emit/schemas/attributeTree/resolveTargetServicePath.js +0 -111
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import ejsLib from 'ejs';
|
|
3
|
+
|
|
4
|
+
const TEMPLATE_URL = new URL('./templates/', import.meta.url);
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* Emits dynamic ObjectSchemas and RelationshipSchemas for ledger add-ons
|
|
3
8
|
*/
|
|
@@ -92,13 +97,17 @@ function _extractGraphStorageResources(object, storageResourceTag) {
|
|
|
92
97
|
return result;
|
|
93
98
|
}
|
|
94
99
|
|
|
95
|
-
function _renderObjectSchema(schema) {
|
|
96
|
-
return
|
|
100
|
+
function _renderObjectSchema(template, schema) {
|
|
101
|
+
return ejsLib.render(template, { schema });
|
|
97
102
|
}
|
|
98
103
|
|
|
99
|
-
function _renderRelationshipSchema(relationshipTag, content) {
|
|
104
|
+
function _renderRelationshipSchema(template, relationshipTag, content) {
|
|
100
105
|
const wrapper = [{ [relationshipTag]: content }];
|
|
101
|
-
return
|
|
106
|
+
return ejsLib.render(template, {
|
|
107
|
+
relationshipTag,
|
|
108
|
+
content,
|
|
109
|
+
wrapper
|
|
110
|
+
});
|
|
102
111
|
}
|
|
103
112
|
|
|
104
113
|
function _buildParentToEntryLinks({
|
|
@@ -117,7 +126,7 @@ function _buildParentToEntryLinks({
|
|
|
117
126
|
objectType: parentObjectType
|
|
118
127
|
},
|
|
119
128
|
linkType: 'many',
|
|
120
|
-
requiredOnCreate:
|
|
129
|
+
requiredOnCreate: false,
|
|
121
130
|
belongTo: true
|
|
122
131
|
},
|
|
123
132
|
to: {
|
|
@@ -176,12 +185,16 @@ export function ledgerRelationshipSchemaManagedPaths(objects = []) {
|
|
|
176
185
|
return paths;
|
|
177
186
|
}
|
|
178
187
|
|
|
179
|
-
export function emitLedgerObjectSchemas({ objects = [] } = {}) {
|
|
188
|
+
export async function emitLedgerObjectSchemas({ objects = [] } = {}) {
|
|
180
189
|
const ledgers = _extractLedgers(objects);
|
|
181
190
|
if (ledgers.length === 0) {
|
|
182
191
|
return [];
|
|
183
192
|
}
|
|
184
193
|
|
|
194
|
+
const template = await readFile(
|
|
195
|
+
new URL('LedgerObjectSchema.ejs', TEMPLATE_URL),
|
|
196
|
+
'utf8'
|
|
197
|
+
);
|
|
185
198
|
const artifacts = [];
|
|
186
199
|
|
|
187
200
|
for (const { parentObject, addOn, component } of ledgers) {
|
|
@@ -217,14 +230,14 @@ export function emitLedgerObjectSchemas({ objects = [] } = {}) {
|
|
|
217
230
|
|
|
218
231
|
artifacts.push({
|
|
219
232
|
path: `app/src/schemas/ObjectSchemas/generatedLedger/${objectType}.js`,
|
|
220
|
-
content: _renderObjectSchema(schema)
|
|
233
|
+
content: _renderObjectSchema(template, schema)
|
|
221
234
|
});
|
|
222
235
|
}
|
|
223
236
|
|
|
224
237
|
return artifacts;
|
|
225
238
|
}
|
|
226
239
|
|
|
227
|
-
export function emitLedgerRelationshipSchemas({
|
|
240
|
+
export async function emitLedgerRelationshipSchemas({
|
|
228
241
|
objects = [],
|
|
229
242
|
serviceTag = ''
|
|
230
243
|
} = {}) {
|
|
@@ -233,6 +246,10 @@ export function emitLedgerRelationshipSchemas({
|
|
|
233
246
|
return [];
|
|
234
247
|
}
|
|
235
248
|
|
|
249
|
+
const template = await readFile(
|
|
250
|
+
new URL('LedgerRelationshipSchema.ejs', TEMPLATE_URL),
|
|
251
|
+
'utf8'
|
|
252
|
+
);
|
|
236
253
|
const artifacts = [];
|
|
237
254
|
|
|
238
255
|
for (const { parentObject, addOn, component } of ledgers) {
|
|
@@ -281,6 +298,7 @@ export function emitLedgerRelationshipSchemas({
|
|
|
281
298
|
artifacts.push({
|
|
282
299
|
path: `app/src/schemas/RelationshipSchemas/generatedLedger/${component.newRelationshipTag}.js`,
|
|
283
300
|
content: _renderRelationshipSchema(
|
|
301
|
+
template,
|
|
284
302
|
component.newRelationshipTag,
|
|
285
303
|
currentRel
|
|
286
304
|
)
|
|
@@ -306,7 +324,11 @@ export function emitLedgerRelationshipSchemas({
|
|
|
306
324
|
};
|
|
307
325
|
artifacts.push({
|
|
308
326
|
path: `app/src/schemas/RelationshipSchemas/generatedLedger/${component.oldRelationshipTag}.js`,
|
|
309
|
-
content: _renderRelationshipSchema(
|
|
327
|
+
content: _renderRelationshipSchema(
|
|
328
|
+
template,
|
|
329
|
+
component.oldRelationshipTag,
|
|
330
|
+
oldRel
|
|
331
|
+
)
|
|
310
332
|
});
|
|
311
333
|
|
|
312
334
|
// 3. is<Prefix>Entry.js (if targetObjType or moveToTargetObjTypes is present)
|
|
@@ -341,7 +363,7 @@ export function emitLedgerRelationshipSchemas({
|
|
|
341
363
|
objectType: component.objectType
|
|
342
364
|
},
|
|
343
365
|
linkType: 'many',
|
|
344
|
-
requiredOnCreate:
|
|
366
|
+
requiredOnCreate: false
|
|
345
367
|
},
|
|
346
368
|
to: {
|
|
347
369
|
objType: {
|
|
@@ -361,7 +383,7 @@ export function emitLedgerRelationshipSchemas({
|
|
|
361
383
|
};
|
|
362
384
|
artifacts.push({
|
|
363
385
|
path: `app/src/schemas/RelationshipSchemas/generatedLedger/${isRelTag}.js`,
|
|
364
|
-
content: _renderRelationshipSchema(isRelTag, isRel)
|
|
386
|
+
content: _renderRelationshipSchema(template, isRelTag, isRel)
|
|
365
387
|
});
|
|
366
388
|
}
|
|
367
389
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default <%- JSON.stringify(wrapper, null, 2) %>;
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import propertyNode from '@izara_project/izara-property-nodes';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Emits dynamic ObjectSchemas and RelationshipSchemas for propertyValue add-ons
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
function _capitalize(str) {
|
|
8
|
+
if (!str) {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
if (typeof str !== 'string') {
|
|
12
|
+
return '';
|
|
13
|
+
}
|
|
14
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function _extractPropertyValues(objects = []) {
|
|
18
|
+
if (!Array.isArray(objects)) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
const results = [];
|
|
22
|
+
const seenTags = new Set();
|
|
23
|
+
|
|
24
|
+
for (const object of objects) {
|
|
25
|
+
if (!Array.isArray(object?.addOnDataStructure)) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
for (const addOn of object.addOnDataStructure) {
|
|
29
|
+
if (addOn?.type === 'propertyValue') {
|
|
30
|
+
let tag = object.objectType;
|
|
31
|
+
if (addOn.propertyValuePrefix) {
|
|
32
|
+
tag = addOn.propertyValuePrefix;
|
|
33
|
+
}
|
|
34
|
+
if (!tag) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (seenTags.has(tag)) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
seenTags.add(tag);
|
|
41
|
+
results.push({
|
|
42
|
+
parentObject: object,
|
|
43
|
+
addOn,
|
|
44
|
+
tag
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return results;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function _extractGraphStorageResources(object) {
|
|
54
|
+
const result = {};
|
|
55
|
+
if (object?.storageResources) {
|
|
56
|
+
for (const [tag, res] of Object.entries(object.storageResources)) {
|
|
57
|
+
if (res?.storageType === 'graph') {
|
|
58
|
+
let graphServerTag = 'GraphHandler';
|
|
59
|
+
if (res.graphServerTag) {
|
|
60
|
+
graphServerTag = res.graphServerTag;
|
|
61
|
+
}
|
|
62
|
+
result[tag] = {
|
|
63
|
+
storageType: 'graph',
|
|
64
|
+
graphServerTag
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (Object.keys(result).length === 0) {
|
|
70
|
+
result.myGraph = {
|
|
71
|
+
storageType: 'graph',
|
|
72
|
+
graphServerTag: 'GraphHandler'
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function _renderObjectSchema(schema) {
|
|
79
|
+
const json = JSON.stringify(schema, null, 2).replace(/\n/g, '\n ');
|
|
80
|
+
return `export default [\n ${json}\n];\n`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function _renderRelationshipSchema(relationshipTag, content) {
|
|
84
|
+
const wrapper = [{ [relationshipTag]: content }];
|
|
85
|
+
return `export default ${JSON.stringify(wrapper, null, 2)};\n`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function propertyValueObjectSchemaManagedPaths(objects = []) {
|
|
89
|
+
const items = _extractPropertyValues(objects);
|
|
90
|
+
const paths = [];
|
|
91
|
+
|
|
92
|
+
for (const { tag } of items) {
|
|
93
|
+
const labelType = propertyNode.createPropertyLabelGraphNodeLabel(tag);
|
|
94
|
+
const valueType = propertyNode.createPropertyValueGraphNodeLabel(tag);
|
|
95
|
+
paths.push(
|
|
96
|
+
`app/src/schemas/ObjectSchemas/generatedCode/propertyValue/${labelType}.js`,
|
|
97
|
+
`app/src/schemas/ObjectSchemas/generatedCode/propertyValue/${valueType}.js`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return paths;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function propertyValueRelationshipSchemaManagedPaths(objects = []) {
|
|
105
|
+
const items = _extractPropertyValues(objects);
|
|
106
|
+
const paths = [];
|
|
107
|
+
|
|
108
|
+
for (const { tag } of items) {
|
|
109
|
+
const tagCap = _capitalize(tag);
|
|
110
|
+
const hasRel = propertyNode.createHasPropertyGraphRelationshipType(tagCap);
|
|
111
|
+
const disabledRel =
|
|
112
|
+
propertyNode.createDisabledPropertyGraphRelationshipType(tagCap);
|
|
113
|
+
const isRel =
|
|
114
|
+
propertyNode.createIsPropertyLabelGraphRelationshipType(tagCap);
|
|
115
|
+
paths.push(
|
|
116
|
+
`app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/${hasRel}.js`,
|
|
117
|
+
`app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/${disabledRel}.js`,
|
|
118
|
+
`app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/${isRel}.js`
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return paths;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function emitPropertyValueObjectSchemas({ objects = [] } = {}) {
|
|
126
|
+
const items = _extractPropertyValues(objects);
|
|
127
|
+
if (items.length === 0) {
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const artifacts = [];
|
|
132
|
+
|
|
133
|
+
for (const { parentObject, tag } of items) {
|
|
134
|
+
const graphStorageResources = _extractGraphStorageResources(parentObject);
|
|
135
|
+
const storageResourceTags = Object.keys(graphStorageResources);
|
|
136
|
+
|
|
137
|
+
const labelIdSuffix = _capitalize(
|
|
138
|
+
propertyNode.consts.PROPERTY_LABEL_GRAPH_IDENTIFIER_ID
|
|
139
|
+
);
|
|
140
|
+
const labelType = propertyNode.createPropertyLabelGraphNodeLabel(tag);
|
|
141
|
+
const labelIdField = `${tag}${labelIdSuffix}`;
|
|
142
|
+
|
|
143
|
+
const labelSchema = {
|
|
144
|
+
objectType: labelType,
|
|
145
|
+
canDelete: true,
|
|
146
|
+
generatedBy: 'user',
|
|
147
|
+
storageResources: graphStorageResources,
|
|
148
|
+
fieldNames: {
|
|
149
|
+
[labelIdField]: {
|
|
150
|
+
type: 'string',
|
|
151
|
+
randomOnCreate: true,
|
|
152
|
+
canUpdate: false,
|
|
153
|
+
storageResourceTags
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
identifiers: [
|
|
157
|
+
{
|
|
158
|
+
type: 'identifier',
|
|
159
|
+
fieldName: labelIdField
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
artifacts.push({
|
|
165
|
+
path: `app/src/schemas/ObjectSchemas/generatedCode/propertyValue/${labelType}.js`,
|
|
166
|
+
content: _renderObjectSchema(labelSchema)
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
const valueIdSuffix = _capitalize(
|
|
170
|
+
propertyNode.consts.PROPERTY_VALUE_GRAPH_IDENTIFIERS_ID
|
|
171
|
+
);
|
|
172
|
+
const valueType = propertyNode.createPropertyValueGraphNodeLabel(tag);
|
|
173
|
+
const valueIdField = `${tag}${valueIdSuffix}`;
|
|
174
|
+
|
|
175
|
+
const valueSchema = {
|
|
176
|
+
objectType: valueType,
|
|
177
|
+
canDelete: true,
|
|
178
|
+
generatedBy: 'user',
|
|
179
|
+
storageResources: graphStorageResources,
|
|
180
|
+
fieldNames: {
|
|
181
|
+
[valueIdField]: {
|
|
182
|
+
type: 'string',
|
|
183
|
+
randomOnCreate: true,
|
|
184
|
+
canUpdate: false,
|
|
185
|
+
storageResourceTags
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
identifiers: [
|
|
189
|
+
{
|
|
190
|
+
type: 'identifier',
|
|
191
|
+
fieldName: valueIdField
|
|
192
|
+
}
|
|
193
|
+
]
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
artifacts.push({
|
|
197
|
+
path: `app/src/schemas/ObjectSchemas/generatedCode/propertyValue/${valueType}.js`,
|
|
198
|
+
content: _renderObjectSchema(valueSchema)
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return artifacts;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function emitPropertyValueRelationshipSchemas({
|
|
206
|
+
objects = [],
|
|
207
|
+
serviceTag = ''
|
|
208
|
+
} = {}) {
|
|
209
|
+
const items = _extractPropertyValues(objects);
|
|
210
|
+
if (items.length === 0) {
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const artifacts = [];
|
|
215
|
+
|
|
216
|
+
for (const { parentObject, tag } of items) {
|
|
217
|
+
const tagCap = _capitalize(tag);
|
|
218
|
+
const parentObjectType = parentObject.objectType;
|
|
219
|
+
let effectiveServiceTag = 'CurrentService';
|
|
220
|
+
if (parentObject?.serviceTag) {
|
|
221
|
+
effectiveServiceTag = parentObject.serviceTag;
|
|
222
|
+
} else if (serviceTag) {
|
|
223
|
+
effectiveServiceTag = serviceTag;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const graphStorageResources = _extractGraphStorageResources(parentObject);
|
|
227
|
+
const storageResourceTags = Object.keys(graphStorageResources);
|
|
228
|
+
|
|
229
|
+
const labelType = propertyNode.createPropertyLabelGraphNodeLabel(tag);
|
|
230
|
+
const valueType = propertyNode.createPropertyValueGraphNodeLabel(tag);
|
|
231
|
+
|
|
232
|
+
const hasRelTag =
|
|
233
|
+
propertyNode.createHasPropertyGraphRelationshipType(tagCap);
|
|
234
|
+
const hasRel = {
|
|
235
|
+
fieldNames: {},
|
|
236
|
+
storageResources: graphStorageResources,
|
|
237
|
+
generatedBy: 'user',
|
|
238
|
+
links: [
|
|
239
|
+
{
|
|
240
|
+
storageResourceTags,
|
|
241
|
+
from: {
|
|
242
|
+
objType: {
|
|
243
|
+
serviceTag: effectiveServiceTag,
|
|
244
|
+
objectType: parentObjectType
|
|
245
|
+
},
|
|
246
|
+
linkType: 'one'
|
|
247
|
+
},
|
|
248
|
+
to: {
|
|
249
|
+
objType: {
|
|
250
|
+
serviceTag: effectiveServiceTag,
|
|
251
|
+
objectType: valueType
|
|
252
|
+
},
|
|
253
|
+
linkType: 'many',
|
|
254
|
+
requiredOnCreate: true
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
]
|
|
258
|
+
};
|
|
259
|
+
artifacts.push({
|
|
260
|
+
path: `app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/${hasRelTag}.js`,
|
|
261
|
+
content: _renderRelationshipSchema(hasRelTag, hasRel)
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const disabledRelTag =
|
|
265
|
+
propertyNode.createDisabledPropertyGraphRelationshipType(tagCap);
|
|
266
|
+
const disabledRel = {
|
|
267
|
+
fieldNames: {},
|
|
268
|
+
storageResources: graphStorageResources,
|
|
269
|
+
generatedBy: 'user',
|
|
270
|
+
links: [
|
|
271
|
+
{
|
|
272
|
+
storageResourceTags,
|
|
273
|
+
from: {
|
|
274
|
+
objType: {
|
|
275
|
+
serviceTag: effectiveServiceTag,
|
|
276
|
+
objectType: parentObjectType
|
|
277
|
+
},
|
|
278
|
+
linkType: 'one'
|
|
279
|
+
},
|
|
280
|
+
to: {
|
|
281
|
+
objType: {
|
|
282
|
+
serviceTag: effectiveServiceTag,
|
|
283
|
+
objectType: valueType
|
|
284
|
+
},
|
|
285
|
+
linkType: 'many'
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
]
|
|
289
|
+
};
|
|
290
|
+
artifacts.push({
|
|
291
|
+
path: `app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/${disabledRelTag}.js`,
|
|
292
|
+
content: _renderRelationshipSchema(disabledRelTag, disabledRel)
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
const isRelTag =
|
|
296
|
+
propertyNode.createIsPropertyLabelGraphRelationshipType(tagCap);
|
|
297
|
+
const isRel = {
|
|
298
|
+
fieldNames: {},
|
|
299
|
+
storageResources: graphStorageResources,
|
|
300
|
+
generatedBy: 'systemNoUser',
|
|
301
|
+
links: [
|
|
302
|
+
{
|
|
303
|
+
storageResourceTags,
|
|
304
|
+
from: {
|
|
305
|
+
objType: {
|
|
306
|
+
serviceTag: effectiveServiceTag,
|
|
307
|
+
objectType: valueType
|
|
308
|
+
},
|
|
309
|
+
linkType: 'many',
|
|
310
|
+
requiredOnCreate: true
|
|
311
|
+
},
|
|
312
|
+
to: {
|
|
313
|
+
objType: {
|
|
314
|
+
serviceTag: effectiveServiceTag,
|
|
315
|
+
objectType: labelType
|
|
316
|
+
},
|
|
317
|
+
linkType: 'one'
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
]
|
|
321
|
+
};
|
|
322
|
+
artifacts.push({
|
|
323
|
+
path: `app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/${isRelTag}.js`,
|
|
324
|
+
content: _renderRelationshipSchema(isRelTag, isRel)
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return artifacts;
|
|
329
|
+
}
|
package/src/generate.js
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
1
|
import { buildGenerationPlan } from './plan/buildGenerationPlan.js';
|
|
3
2
|
import { resolveEmissionGroups } from './plan/domainRegistry.js';
|
|
4
3
|
import { commitArtifacts } from './output/commitArtifacts.js';
|
|
5
4
|
import { compileProject } from './compile/compileProject.js';
|
|
6
5
|
import {
|
|
7
6
|
loadLocalSchemaDirectory,
|
|
7
|
+
loadGenerateDirectives,
|
|
8
8
|
resolveExtendedObjectSchemas,
|
|
9
9
|
resolveGraphServiceTags
|
|
10
10
|
} from './compile/loadSchemas.js';
|
|
11
|
-
import {
|
|
12
|
-
resolveTargetServicePath,
|
|
13
|
-
emitAttributeTreeTargetSchemas
|
|
14
|
-
} from './emit/schemas/attributeTree/emitAttributeTreeSchemas.js';
|
|
15
11
|
|
|
16
12
|
export async function generate(rootPath, options = {}) {
|
|
17
13
|
const startedAt = Date.now();
|
|
@@ -26,13 +22,23 @@ export async function generate(rootPath, options = {}) {
|
|
|
26
22
|
relationships,
|
|
27
23
|
flows,
|
|
28
24
|
notifications,
|
|
29
|
-
errors
|
|
25
|
+
errors,
|
|
26
|
+
directives
|
|
30
27
|
] = await Promise.all([
|
|
31
28
|
loadLocalSchemaDirectory(project, 'ObjectSchemas', schemaLoadOptions),
|
|
32
|
-
loadLocalSchemaDirectory(
|
|
29
|
+
loadLocalSchemaDirectory(
|
|
30
|
+
project,
|
|
31
|
+
'RelationshipSchemas',
|
|
32
|
+
schemaLoadOptions
|
|
33
|
+
),
|
|
33
34
|
loadLocalSchemaDirectory(project, 'FlowSchemas', schemaLoadOptions),
|
|
34
|
-
loadLocalSchemaDirectory(
|
|
35
|
-
|
|
35
|
+
loadLocalSchemaDirectory(
|
|
36
|
+
project,
|
|
37
|
+
'NotificationSchemas',
|
|
38
|
+
schemaLoadOptions
|
|
39
|
+
),
|
|
40
|
+
loadLocalSchemaDirectory(project, 'ErrorSchemas', schemaLoadOptions),
|
|
41
|
+
loadGenerateDirectives(project, schemaLoadOptions)
|
|
36
42
|
]);
|
|
37
43
|
const schemaBucketName =
|
|
38
44
|
options.schemaBucketName || process.env.iz_serviceSchemaBucketName;
|
|
@@ -76,6 +82,7 @@ export async function generate(rootPath, options = {}) {
|
|
|
76
82
|
flows,
|
|
77
83
|
notifications,
|
|
78
84
|
errors,
|
|
85
|
+
directives,
|
|
79
86
|
objectGraphServiceTags,
|
|
80
87
|
relationshipGraphServiceTags,
|
|
81
88
|
logger: options.logger
|
|
@@ -101,14 +108,6 @@ export async function generate(rootPath, options = {}) {
|
|
|
101
108
|
)
|
|
102
109
|
);
|
|
103
110
|
}
|
|
104
|
-
const targetFiles = await _emitTargetServiceAttributeTreeSchemas({
|
|
105
|
-
project,
|
|
106
|
-
objects,
|
|
107
|
-
logger: options.logger
|
|
108
|
-
});
|
|
109
|
-
for (const targetFile of targetFiles) {
|
|
110
|
-
files.push(targetFile);
|
|
111
|
-
}
|
|
112
111
|
const durationMs = Date.now() - startedAt;
|
|
113
112
|
console.log(
|
|
114
113
|
`[INFO] [Generate] STATUS=FINISHED | ` +
|
|
@@ -126,61 +125,3 @@ export async function generate(rootPath, options = {}) {
|
|
|
126
125
|
}
|
|
127
126
|
}
|
|
128
127
|
|
|
129
|
-
async function _emitTargetServiceAttributeTreeSchemas({
|
|
130
|
-
project,
|
|
131
|
-
objects,
|
|
132
|
-
logger
|
|
133
|
-
}) {
|
|
134
|
-
if (!Array.isArray(objects)) {
|
|
135
|
-
return [];
|
|
136
|
-
}
|
|
137
|
-
const committedFiles = [];
|
|
138
|
-
for (const object of objects) {
|
|
139
|
-
if (!Array.isArray(object?.addOnDataStructure)) {
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
for (const addOn of object.addOnDataStructure) {
|
|
143
|
-
if (addOn?.type === 'attributeTree' && addOn?.attributeTreeTag) {
|
|
144
|
-
const attributeTag = addOn.attributeTreeTag;
|
|
145
|
-
const targetServiceRoot = resolveTargetServicePath({
|
|
146
|
-
currentServiceRoot: project.rootPath,
|
|
147
|
-
attributeTag
|
|
148
|
-
});
|
|
149
|
-
if (targetServiceRoot) {
|
|
150
|
-
const artifacts = emitAttributeTreeTargetSchemas({
|
|
151
|
-
attributeTag,
|
|
152
|
-
targetServiceRoot
|
|
153
|
-
});
|
|
154
|
-
const relativeArtifacts = artifacts.map((artifact) => {
|
|
155
|
-
return {
|
|
156
|
-
path: path.relative(targetServiceRoot, artifact.path),
|
|
157
|
-
content: artifact.content
|
|
158
|
-
};
|
|
159
|
-
});
|
|
160
|
-
const targetPlan = buildGenerationPlan(
|
|
161
|
-
{ outputPath: targetServiceRoot },
|
|
162
|
-
relativeArtifacts,
|
|
163
|
-
{
|
|
164
|
-
managedScopes: {
|
|
165
|
-
'attribute-tree-target-schemas': relativeArtifacts.map(
|
|
166
|
-
(a) => a.path
|
|
167
|
-
)
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
);
|
|
171
|
-
const targetFiles = await commitArtifacts(targetPlan);
|
|
172
|
-
for (const targetFile of targetFiles) {
|
|
173
|
-
committedFiles.push(targetFile);
|
|
174
|
-
}
|
|
175
|
-
if (logger && typeof logger.info === 'function') {
|
|
176
|
-
logger.info(
|
|
177
|
-
`[INFO] [AttributeTree] Target schemas emitted for ` +
|
|
178
|
-
`tag=${attributeTag} to ${targetServiceRoot}`
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
return committedFiles;
|
|
186
|
-
}
|
package/src/output/mergeHooks.js
CHANGED
|
@@ -24,7 +24,10 @@ async function mergeHook(outputRoot, artifact) {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
const skipWrite =
|
|
28
|
+
artifact.writeWhenFileExist === false ||
|
|
29
|
+
artifact.writeWhenFileExists === false;
|
|
30
|
+
if (sourceContent !== null && skipWrite) {
|
|
28
31
|
return sourceContent;
|
|
29
32
|
}
|
|
30
33
|
|
|
@@ -37,32 +40,83 @@ async function mergeHook(outputRoot, artifact) {
|
|
|
37
40
|
return artifact.content;
|
|
38
41
|
}
|
|
39
42
|
|
|
43
|
+
const tagOccurrences = new Map();
|
|
40
44
|
return artifact.content.replace(
|
|
41
45
|
matchers.anyTag,
|
|
42
46
|
(_match, p1, _body1, p2) => {
|
|
43
|
-
const tagName = p1
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
const tagName = _extractTagName(p1, p2);
|
|
48
|
+
if (!tagName) {
|
|
49
|
+
return _match;
|
|
50
|
+
}
|
|
51
|
+
let count = 0;
|
|
52
|
+
if (tagOccurrences.has(tagName)) {
|
|
53
|
+
count = tagOccurrences.get(tagName);
|
|
54
|
+
}
|
|
55
|
+
tagOccurrences.set(tagName, count + 1);
|
|
56
|
+
|
|
57
|
+
const matches = sourceContent.match(matchers.tagPattern(tagName));
|
|
58
|
+
if (!matches || count >= matches.length) {
|
|
59
|
+
return _match;
|
|
60
|
+
}
|
|
61
|
+
const hookBlock = matches[count];
|
|
62
|
+
if (hookBlock !== null && hookBlock !== undefined) {
|
|
63
|
+
return hookBlock;
|
|
64
|
+
}
|
|
65
|
+
return _match;
|
|
46
66
|
}
|
|
47
67
|
);
|
|
48
68
|
}
|
|
49
69
|
|
|
70
|
+
function _extractTagName(p1, p2) {
|
|
71
|
+
if (typeof p1 === 'string' && p1.length > 0) {
|
|
72
|
+
return p1;
|
|
73
|
+
}
|
|
74
|
+
if (typeof p2 === 'string' && p2.length > 0) {
|
|
75
|
+
return p2;
|
|
76
|
+
}
|
|
77
|
+
return '';
|
|
78
|
+
}
|
|
79
|
+
|
|
50
80
|
function hookMatchers(filePath) {
|
|
51
|
-
|
|
81
|
+
const lower = filePath.toLowerCase();
|
|
82
|
+
if (
|
|
83
|
+
lower.endsWith('.js') ||
|
|
84
|
+
lower.endsWith('.mjs') ||
|
|
85
|
+
lower.endsWith('.cjs')
|
|
86
|
+
) {
|
|
87
|
+
const jsP1 =
|
|
88
|
+
'\\/\\/\\s*\\(<\\s*([\\w.-]+)\\s*>\\)([\\s\\S]*?)' +
|
|
89
|
+
'\\/\\/\\s*\\(<\\/\\s*\\1\\s*>\\)';
|
|
90
|
+
const jsP2 =
|
|
91
|
+
'\\/\\/\\s*<#\\s*([\\w.-]+)\\s*#>([\\s\\S]*?)' +
|
|
92
|
+
'\\/\\/\\s*<#\\/\\s*\\3\\s*#>';
|
|
52
93
|
return {
|
|
53
|
-
anyTag:
|
|
54
|
-
tagPattern: (name) =>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
94
|
+
anyTag: new RegExp(`(?:${jsP1}|${jsP2})`, 'gm'),
|
|
95
|
+
tagPattern: (name) => {
|
|
96
|
+
const esc = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
97
|
+
const p1 =
|
|
98
|
+
`\\/\\/\\s*\\(<\\s*${esc}\\s*>\\)([\\s\\S]*?)` +
|
|
99
|
+
`\\/\\/\\s*\\(<\\/\\s*${esc}\\s*>\\)`;
|
|
100
|
+
const p2 =
|
|
101
|
+
`\\/\\/\\s*<#\\s*${esc}\\s*#>([\\s\\S]*?)` +
|
|
102
|
+
`\\/\\/\\s*<#\\/\\s*${esc}\\s*#>`;
|
|
103
|
+
return new RegExp(`(?:${p1}|${p2})`, 'gm');
|
|
104
|
+
}
|
|
59
105
|
};
|
|
60
106
|
}
|
|
61
|
-
if (
|
|
107
|
+
if (lower.endsWith('.yml') || lower.endsWith('.yaml')) {
|
|
108
|
+
const ymlPattern =
|
|
109
|
+
'#\\s*<#\\s*([\\w.-]+)\\s*#>([\\s\\S]*?)' +
|
|
110
|
+
'#\\s*<#\\/\\s*\\1\\s*#>';
|
|
62
111
|
return {
|
|
63
|
-
anyTag:
|
|
64
|
-
tagPattern: (name) =>
|
|
65
|
-
|
|
112
|
+
anyTag: new RegExp(ymlPattern, 'gm'),
|
|
113
|
+
tagPattern: (name) => {
|
|
114
|
+
const esc = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
115
|
+
return new RegExp(
|
|
116
|
+
`#\\s*<#\\s*${esc}\\s*#>([\\s\\S]*?)#\\s*<#\\/\\s*${esc}\\s*#>`,
|
|
117
|
+
'gm'
|
|
118
|
+
);
|
|
119
|
+
}
|
|
66
120
|
};
|
|
67
121
|
}
|
|
68
122
|
return null;
|