@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
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test, { after } from 'node:test';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
loadGenerateDirectives
|
|
6
|
+
} from '../../../src/compile/loadSchemas.js';
|
|
7
|
+
import {
|
|
8
|
+
emitAttributeTreeTargetValueStandard,
|
|
9
|
+
attributeTreeTargetValueStandardManagedPaths
|
|
10
|
+
} from '../../../src/emit/schemas/attributeTree/emitAttributeTreeTargetValueStandard.js';
|
|
11
|
+
import { generate } from '../../../src/generate.js';
|
|
12
|
+
import {
|
|
13
|
+
createTestProject,
|
|
14
|
+
readProjectFile,
|
|
15
|
+
writeProjectFile,
|
|
16
|
+
cleanupTestProjects
|
|
17
|
+
} from '../../helpers/testProject.js';
|
|
18
|
+
|
|
19
|
+
after(async () => {
|
|
20
|
+
await cleanupTestProjects();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('loadGenerateDirectives returns empty array when directory missing', async () => {
|
|
24
|
+
const rootPath = await createTestProject({
|
|
25
|
+
prefix: 'izara-no-directives-test-',
|
|
26
|
+
serviceTag: 'TestService'
|
|
27
|
+
});
|
|
28
|
+
const project = { schemaRoot: `${rootPath}/app/src/schemas` };
|
|
29
|
+
const directives = await loadGenerateDirectives(project);
|
|
30
|
+
assert.deepEqual(directives, []);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('loadGenerateDirectives loads directives from GenerateDirectives folder', async () => {
|
|
34
|
+
const rootPath = await createTestProject({
|
|
35
|
+
prefix: 'izara-directives-load-test-',
|
|
36
|
+
serviceTag: 'SellOfferTermManager',
|
|
37
|
+
schemas: {
|
|
38
|
+
'GenerateDirectives/sellOfferTermValueStandard.js': `export default {
|
|
39
|
+
type: 'attributeTreeTarget',
|
|
40
|
+
attributeTreeTag: 'sellOfferTerm'
|
|
41
|
+
};
|
|
42
|
+
`
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
const project = { schemaRoot: `${rootPath}/app/src/schemas` };
|
|
46
|
+
const directives = await loadGenerateDirectives(project);
|
|
47
|
+
assert.equal(directives.length, 1);
|
|
48
|
+
assert.equal(directives[0].type, 'attributeTreeTarget');
|
|
49
|
+
assert.equal(directives[0].attributeTreeTag, 'sellOfferTerm');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('emitAttributeTreeTargetValueStandard emits expected schema with hook', () => {
|
|
53
|
+
const directives = [
|
|
54
|
+
{
|
|
55
|
+
type: 'attributeTreeTarget',
|
|
56
|
+
attributeTreeTag: 'sellOfferTerm'
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
const managedPaths =
|
|
61
|
+
attributeTreeTargetValueStandardManagedPaths(directives);
|
|
62
|
+
assert.deepEqual(managedPaths, [
|
|
63
|
+
'app/src/schemas/ObjectSchemas/generatedCode/attributeTree/sellOfferTermValueStandard.js'
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
const artifacts = emitAttributeTreeTargetValueStandard({ directives });
|
|
67
|
+
assert.equal(artifacts.length, 1);
|
|
68
|
+
|
|
69
|
+
const artifact = artifacts[0];
|
|
70
|
+
assert.equal(
|
|
71
|
+
artifact.path,
|
|
72
|
+
'app/src/schemas/ObjectSchemas/generatedCode/attributeTree/sellOfferTermValueStandard.js'
|
|
73
|
+
);
|
|
74
|
+
assert.match(
|
|
75
|
+
artifact.content,
|
|
76
|
+
/objectType:\s*['"]sellOfferTermValueStandard['"]/
|
|
77
|
+
);
|
|
78
|
+
assert.match(artifact.content, /sellOfferTermValueStandardId/);
|
|
79
|
+
assert.match(
|
|
80
|
+
artifact.content,
|
|
81
|
+
/\/\/\(<addOnDataStructuresellOfferTermValueStandard>\)/
|
|
82
|
+
);
|
|
83
|
+
assert.match(
|
|
84
|
+
artifact.content,
|
|
85
|
+
/\/\/\(<\/addOnDataStructuresellOfferTermValueStandard>\)/
|
|
86
|
+
);
|
|
87
|
+
assert.match(artifact.content, /propertyValue/);
|
|
88
|
+
assert.match(artifact.content, /GraphHandler/);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('managed paths and emitter return empty when no matching directives', () => {
|
|
92
|
+
assert.deepEqual(attributeTreeTargetValueStandardManagedPaths([]), []);
|
|
93
|
+
assert.deepEqual(
|
|
94
|
+
attributeTreeTargetValueStandardManagedPaths([{ type: 'other' }]),
|
|
95
|
+
[]
|
|
96
|
+
);
|
|
97
|
+
assert.deepEqual(emitAttributeTreeTargetValueStandard({ directives: [] }), []);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('generate commits and cleans up attributeTreeTarget dynamic schemas', async () => {
|
|
101
|
+
const rootPath = await createTestProject({
|
|
102
|
+
prefix: 'izara-directives-gen-test-',
|
|
103
|
+
serviceTag: 'SellOfferTermManager',
|
|
104
|
+
schemas: {
|
|
105
|
+
'GenerateDirectives/sellOfferTermValueStandard.js': `export default {
|
|
106
|
+
type: 'attributeTreeTarget',
|
|
107
|
+
attributeTreeTag: 'sellOfferTerm'
|
|
108
|
+
};
|
|
109
|
+
`
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
await generate(rootPath);
|
|
114
|
+
|
|
115
|
+
const targetRelPath =
|
|
116
|
+
'app/src/schemas/ObjectSchemas/generatedCode/attributeTree/sellOfferTermValueStandard.js';
|
|
117
|
+
const content = await readProjectFile(rootPath, targetRelPath);
|
|
118
|
+
assert.match(content, /sellOfferTermValueStandard/);
|
|
119
|
+
assert.match(
|
|
120
|
+
content,
|
|
121
|
+
/\/\/\(<addOnDataStructuresellOfferTermValueStandard>\)/
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
// Regeneration preserves user changes inside the hook
|
|
125
|
+
const modifiedContent = content.replace(
|
|
126
|
+
'//(<addOnDataStructuresellOfferTermValueStandard>)\n // {\n // type: \'propertyValue\',\n // propertyValuePrefix: \'sellOfferTermValueStandard\'\n // }\n //(</addOnDataStructuresellOfferTermValueStandard>)',
|
|
127
|
+
'//(<addOnDataStructuresellOfferTermValueStandard>)\n {\n type: \'propertyValue\',\n propertyValuePrefix: \'sellOfferTermValueStandard\'\n }\n //(</addOnDataStructuresellOfferTermValueStandard>)'
|
|
128
|
+
);
|
|
129
|
+
await writeProjectFile(rootPath, targetRelPath, modifiedContent);
|
|
130
|
+
|
|
131
|
+
await generate(rootPath);
|
|
132
|
+
|
|
133
|
+
const regeneratedContent = await readProjectFile(rootPath, targetRelPath);
|
|
134
|
+
assert.match(
|
|
135
|
+
regeneratedContent,
|
|
136
|
+
/type:\s*'propertyValue'/
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// Cascading verification: PropertyValue schemas generated in phase 2
|
|
140
|
+
const propLabelPath =
|
|
141
|
+
'app/src/schemas/ObjectSchemas/generatedCode/propertyValue/sellOfferTermValueStandardPropertyLabel.js';
|
|
142
|
+
const propValuePath =
|
|
143
|
+
'app/src/schemas/ObjectSchemas/generatedCode/propertyValue/sellOfferTermValueStandardPropertyValue.js';
|
|
144
|
+
const hasPropRelPath =
|
|
145
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/hasSellOfferTermValueStandardPropertyValue.js';
|
|
146
|
+
const disPropRelPath =
|
|
147
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/disabledSellOfferTermValueStandardPropertyValue.js';
|
|
148
|
+
const isPropRelPath =
|
|
149
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/isSellOfferTermValueStandardPropertyLabel.js';
|
|
150
|
+
|
|
151
|
+
const propLabelContent = await readProjectFile(rootPath, propLabelPath);
|
|
152
|
+
assert.match(propLabelContent, /sellOfferTermValueStandardPropertyLabel/);
|
|
153
|
+
|
|
154
|
+
const propValueContent = await readProjectFile(rootPath, propValuePath);
|
|
155
|
+
assert.match(propValueContent, /sellOfferTermValueStandardPropertyValue/);
|
|
156
|
+
|
|
157
|
+
const hasPropRelContent = await readProjectFile(rootPath, hasPropRelPath);
|
|
158
|
+
assert.match(hasPropRelContent, /hasSellOfferTermValueStandardPropertyValue/);
|
|
159
|
+
|
|
160
|
+
const disPropRelContent = await readProjectFile(rootPath, disPropRelPath);
|
|
161
|
+
assert.match(disPropRelContent, /disabledSellOfferTermValueStandardPropertyValue/);
|
|
162
|
+
|
|
163
|
+
const isPropRelContent = await readProjectFile(rootPath, isPropRelPath);
|
|
164
|
+
assert.match(isPropRelContent, /isSellOfferTermValueStandardPropertyLabel/);
|
|
165
|
+
|
|
166
|
+
// When directive removed, file is cleaned up
|
|
167
|
+
await writeProjectFile(
|
|
168
|
+
rootPath,
|
|
169
|
+
'app/src/schemas/GenerateDirectives/sellOfferTermValueStandard.js',
|
|
170
|
+
'export default { type: "disabled" };\n'
|
|
171
|
+
);
|
|
172
|
+
await generate(rootPath);
|
|
173
|
+
|
|
174
|
+
await assert.rejects(readProjectFile(rootPath, targetRelPath), {
|
|
175
|
+
code: 'ENOENT'
|
|
176
|
+
});
|
|
177
|
+
});
|
|
@@ -8,9 +8,7 @@ import {
|
|
|
8
8
|
emitAttributeTreeObjectSchemas,
|
|
9
9
|
emitAttributeTreeRelationshipSchemas,
|
|
10
10
|
attributeTreeObjectSchemaManagedPaths,
|
|
11
|
-
attributeTreeRelationshipSchemaManagedPaths
|
|
12
|
-
resolveTargetServicePath,
|
|
13
|
-
emitAttributeTreeTargetSchemas
|
|
11
|
+
attributeTreeRelationshipSchemaManagedPaths
|
|
14
12
|
} from '../../../src/emit/schemas/attributeTree/emitAttributeTreeSchemas.js';
|
|
15
13
|
import { generate } from '../../../src/generate.js';
|
|
16
14
|
import {
|
|
@@ -54,9 +52,9 @@ test('emitAttributeTreeObjectSchemas returns 3 object schemas per attributeTree
|
|
|
54
52
|
|
|
55
53
|
const paths = artifacts.map((a) => a.path);
|
|
56
54
|
assert.deepEqual(paths, [
|
|
57
|
-
'app/src/schemas/ObjectSchemas/
|
|
58
|
-
'app/src/schemas/ObjectSchemas/
|
|
59
|
-
'app/src/schemas/ObjectSchemas/
|
|
55
|
+
'app/src/schemas/ObjectSchemas/generatedCode/attributeTree/sellOfferTermLink.js',
|
|
56
|
+
'app/src/schemas/ObjectSchemas/generatedCode/attributeTree/sellOfferTermValue.js',
|
|
57
|
+
'app/src/schemas/ObjectSchemas/generatedCode/attributeTree/sellOfferTermLabel.js'
|
|
60
58
|
]);
|
|
61
59
|
|
|
62
60
|
const valueArtifact = artifacts.find((a) =>
|
|
@@ -103,10 +101,10 @@ test('emitAttributeTreeRelationshipSchemas returns 4 relationship schemas per at
|
|
|
103
101
|
|
|
104
102
|
const paths = artifacts.map((a) => a.path);
|
|
105
103
|
assert.deepEqual(paths, [
|
|
106
|
-
'app/src/schemas/RelationshipSchemas/
|
|
107
|
-
'app/src/schemas/RelationshipSchemas/
|
|
108
|
-
'app/src/schemas/RelationshipSchemas/
|
|
109
|
-
'app/src/schemas/RelationshipSchemas/
|
|
104
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/attributeTree/hasSellOfferTermLink.js',
|
|
105
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/attributeTree/disabledSellOfferTermLink.js',
|
|
106
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/attributeTree/isSellOfferTerm.js',
|
|
107
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/attributeTree/isSellOfferTermLabel.js'
|
|
110
108
|
]);
|
|
111
109
|
|
|
112
110
|
const hasRel = artifacts.find((a) => a.path.endsWith('hasSellOfferTermLink.js'));
|
|
@@ -153,9 +151,9 @@ test('generate commits and cleans up attributeTree dynamic schemas', async () =>
|
|
|
153
151
|
await generate(rootPath);
|
|
154
152
|
|
|
155
153
|
const objectRelPath =
|
|
156
|
-
'app/src/schemas/ObjectSchemas/
|
|
154
|
+
'app/src/schemas/ObjectSchemas/generatedCode/attributeTree/sellOfferTermLink.js';
|
|
157
155
|
const relRelPath =
|
|
158
|
-
'app/src/schemas/RelationshipSchemas/
|
|
156
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/attributeTree/hasSellOfferTermLink.js';
|
|
159
157
|
|
|
160
158
|
const objectContent = await readProjectFile(rootPath, objectRelPath);
|
|
161
159
|
assert.match(objectContent, /sellOfferTermLink/);
|
|
@@ -244,53 +242,4 @@ async function createProjectWithAttributeTree({
|
|
|
244
242
|
});
|
|
245
243
|
}
|
|
246
244
|
|
|
247
|
-
test('resolveTargetServicePath prioritizes dev suffix and matches attributeTag', async () => {
|
|
248
|
-
const tmpRoot = trackTestProject(
|
|
249
|
-
await mkdtemp(join(tmpdir(), 'izara-services-test-'))
|
|
250
|
-
);
|
|
251
|
-
|
|
252
|
-
const currentServiceDir = join(
|
|
253
|
-
tmpRoot,
|
|
254
|
-
'izara-market-products-sell-offer-manager-pong'
|
|
255
|
-
);
|
|
256
|
-
const targetWithSuffix = join(
|
|
257
|
-
tmpRoot,
|
|
258
|
-
'izara-market-products-sell-offer-term-pong'
|
|
259
|
-
);
|
|
260
|
-
const targetOtherDev = join(
|
|
261
|
-
tmpRoot,
|
|
262
|
-
'izara-market-products-sell-offer-term-alice'
|
|
263
|
-
);
|
|
264
|
-
const unrelatedService = join(
|
|
265
|
-
tmpRoot,
|
|
266
|
-
'izara-market-products-cart-pong'
|
|
267
|
-
);
|
|
268
|
-
|
|
269
|
-
await mkdir(join(currentServiceDir, 'app/src'), { recursive: true });
|
|
270
|
-
await mkdir(join(targetWithSuffix, 'app/src'), { recursive: true });
|
|
271
|
-
await mkdir(join(targetOtherDev, 'app/src'), { recursive: true });
|
|
272
|
-
await mkdir(join(unrelatedService, 'app/src'), { recursive: true });
|
|
273
|
-
|
|
274
|
-
const resolved = resolveTargetServicePath({
|
|
275
|
-
currentServiceRoot: currentServiceDir,
|
|
276
|
-
attributeTag: 'sellOfferTerm'
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
assert.equal(resolved, targetWithSuffix);
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
test('emitAttributeTreeTargetSchemas produces expected standard schemas', () => {
|
|
283
|
-
const targetDir = '/dummy/path/izara-market-products-sellOfferTerm';
|
|
284
|
-
const artifacts = emitAttributeTreeTargetSchemas({
|
|
285
|
-
attributeTag: 'sellOfferTerm',
|
|
286
|
-
targetServiceRoot: targetDir
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
assert.equal(artifacts.length, 3);
|
|
290
|
-
const paths = artifacts.map((a) => a.path);
|
|
291
|
-
|
|
292
|
-
assert.ok(paths.some((p) => p.endsWith('sellOfferTermValueStandardPropertyLabel.js')));
|
|
293
|
-
assert.ok(paths.some((p) => p.endsWith('sellOfferTermValueStandardPropertyValue.js')));
|
|
294
|
-
assert.ok(paths.some((p) => p.endsWith('sellOfferTermValueStandard.js')));
|
|
295
|
-
});
|
|
296
245
|
|
|
@@ -19,7 +19,7 @@ after(async () => {
|
|
|
19
19
|
await cleanupTestProjects();
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
test('emitLedgerObjectSchemas returns 1 object schema per ledger addOn', () => {
|
|
22
|
+
test('emitLedgerObjectSchemas returns 1 object schema per ledger addOn', async () => {
|
|
23
23
|
const objects = [
|
|
24
24
|
{
|
|
25
25
|
objectType: 'unitStandard',
|
|
@@ -61,7 +61,7 @@ test('emitLedgerObjectSchemas returns 1 object schema per ledger addOn', () => {
|
|
|
61
61
|
}
|
|
62
62
|
];
|
|
63
63
|
|
|
64
|
-
const artifacts = emitLedgerObjectSchemas({ objects });
|
|
64
|
+
const artifacts = await emitLedgerObjectSchemas({ objects });
|
|
65
65
|
assert.equal(artifacts.length, 2);
|
|
66
66
|
|
|
67
67
|
const paths = artifacts.map((a) => a.path);
|
|
@@ -81,7 +81,7 @@ test('emitLedgerObjectSchemas returns 1 object schema per ledger addOn', () => {
|
|
|
81
81
|
assert.match(entryArtifact.content, /GraphHandler/);
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
-
test('emitLedgerRelationshipSchemas returns current, old, and is relationship schemas per ledger addOn', () => {
|
|
84
|
+
test('emitLedgerRelationshipSchemas returns current, old, and is relationship schemas per ledger addOn', async () => {
|
|
85
85
|
const objects = [
|
|
86
86
|
{
|
|
87
87
|
objectType: 'unitStandard',
|
|
@@ -113,7 +113,7 @@ test('emitLedgerRelationshipSchemas returns current, old, and is relationship sc
|
|
|
113
113
|
}
|
|
114
114
|
];
|
|
115
115
|
|
|
116
|
-
const artifacts = emitLedgerRelationshipSchemas({
|
|
116
|
+
const artifacts = await emitLedgerRelationshipSchemas({
|
|
117
117
|
objects,
|
|
118
118
|
serviceTag: 'UnitStandard'
|
|
119
119
|
});
|
|
@@ -156,14 +156,40 @@ test('emitLedgerRelationshipSchemas returns current, old, and is relationship sc
|
|
|
156
156
|
assert.match(isRel.content, /"generatedBy": "systemNoUser"/);
|
|
157
157
|
assert.match(isRel.content, /"supplyLocation"/);
|
|
158
158
|
assert.match(isRel.content, /"unitPacking"/);
|
|
159
|
+
|
|
160
|
+
// 4. Verify requiredOnCreate is false in links
|
|
161
|
+
const _parseRel = (content) => {
|
|
162
|
+
const raw = content
|
|
163
|
+
.replace(/^export default\s+/, '')
|
|
164
|
+
.replace(/;\s*$/, '');
|
|
165
|
+
return JSON.parse(raw)[0];
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const currentRelData = Object.values(_parseRel(currentRel.content))[0];
|
|
169
|
+
for (const link of currentRelData.links) {
|
|
170
|
+
assert.equal(link.from.requiredOnCreate, false);
|
|
171
|
+
assert.equal(link.to.requiredOnCreate, false);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const oldRelData = Object.values(_parseRel(oldRel.content))[0];
|
|
175
|
+
for (const link of oldRelData.links) {
|
|
176
|
+
assert.equal(link.from.requiredOnCreate, false);
|
|
177
|
+
assert.equal(link.to.requiredOnCreate, false);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const isRelData = Object.values(_parseRel(isRel.content))[0];
|
|
181
|
+
for (const link of isRelData.links) {
|
|
182
|
+
assert.equal(link.from.requiredOnCreate, false);
|
|
183
|
+
assert.equal(link.to.requiredOnCreate, false);
|
|
184
|
+
}
|
|
159
185
|
});
|
|
160
186
|
|
|
161
|
-
test('managed paths return empty array when no ledger is present', () => {
|
|
187
|
+
test('managed paths return empty array when no ledger is present', async () => {
|
|
162
188
|
const objects = [{ objectType: 'user', addOnDataStructure: [] }];
|
|
163
189
|
assert.deepEqual(ledgerObjectSchemaManagedPaths(objects), []);
|
|
164
190
|
assert.deepEqual(ledgerRelationshipSchemaManagedPaths(objects), []);
|
|
165
|
-
assert.deepEqual(emitLedgerObjectSchemas({ objects }), []);
|
|
166
|
-
assert.deepEqual(emitLedgerRelationshipSchemas({ objects }), []);
|
|
191
|
+
assert.deepEqual(await emitLedgerObjectSchemas({ objects }), []);
|
|
192
|
+
assert.deepEqual(await emitLedgerRelationshipSchemas({ objects }), []);
|
|
167
193
|
});
|
|
168
194
|
|
|
169
195
|
test('generate commits and cleans up ledger dynamic schemas', async () => {
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test, { after } from 'node:test';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
emitPropertyValueObjectSchemas,
|
|
6
|
+
emitPropertyValueRelationshipSchemas,
|
|
7
|
+
propertyValueObjectSchemaManagedPaths,
|
|
8
|
+
propertyValueRelationshipSchemaManagedPaths
|
|
9
|
+
} from '../../../src/emit/schemas/propertyValue/emitPropertyValueSchemas.js';
|
|
10
|
+
import { generate } from '../../../src/generate.js';
|
|
11
|
+
import {
|
|
12
|
+
createTestProject,
|
|
13
|
+
readProjectFile,
|
|
14
|
+
writeProjectFile,
|
|
15
|
+
cleanupTestProjects
|
|
16
|
+
} from '../../helpers/testProject.js';
|
|
17
|
+
|
|
18
|
+
after(async () => {
|
|
19
|
+
await cleanupTestProjects();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('emitPropertyValueObjectSchemas returns 2 object schemas per propertyValue addOn', () => {
|
|
23
|
+
const objects = [
|
|
24
|
+
{
|
|
25
|
+
objectType: 'item',
|
|
26
|
+
serviceTag: 'ItemService',
|
|
27
|
+
storageResources: {
|
|
28
|
+
dynamoDB: {
|
|
29
|
+
storageType: 'dynamoDB',
|
|
30
|
+
tableName: 'ItemRecords'
|
|
31
|
+
},
|
|
32
|
+
myGraph: {
|
|
33
|
+
storageType: 'graph',
|
|
34
|
+
graphServerTag: 'GraphHandler'
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
addOnDataStructure: [
|
|
38
|
+
{
|
|
39
|
+
type: 'propertyValue',
|
|
40
|
+
propertyValuePrefix: 'itemProperty'
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
objectType: 'supplyNetwork',
|
|
46
|
+
serviceTag: 'SupplyService',
|
|
47
|
+
storageResources: {
|
|
48
|
+
myGraph: {
|
|
49
|
+
storageType: 'graph',
|
|
50
|
+
graphServerTag: 'GraphHandler'
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
addOnDataStructure: [
|
|
54
|
+
{
|
|
55
|
+
type: 'propertyValue'
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
const artifacts = emitPropertyValueObjectSchemas({ objects });
|
|
62
|
+
assert.equal(artifacts.length, 4);
|
|
63
|
+
|
|
64
|
+
const paths = artifacts.map((a) => a.path);
|
|
65
|
+
assert.deepEqual(paths, [
|
|
66
|
+
'app/src/schemas/ObjectSchemas/generatedCode/propertyValue/itemPropertyPropertyLabel.js',
|
|
67
|
+
'app/src/schemas/ObjectSchemas/generatedCode/propertyValue/itemPropertyPropertyValue.js',
|
|
68
|
+
'app/src/schemas/ObjectSchemas/generatedCode/propertyValue/supplyNetworkPropertyLabel.js',
|
|
69
|
+
'app/src/schemas/ObjectSchemas/generatedCode/propertyValue/supplyNetworkPropertyValue.js'
|
|
70
|
+
]);
|
|
71
|
+
|
|
72
|
+
const labelArtifact = artifacts[0];
|
|
73
|
+
assert.match(
|
|
74
|
+
labelArtifact.content,
|
|
75
|
+
/"objectType": "itemPropertyPropertyLabel"/
|
|
76
|
+
);
|
|
77
|
+
assert.match(labelArtifact.content, /"itemPropertyPropertyLabelId"/);
|
|
78
|
+
assert.match(labelArtifact.content, /"generatedBy": "user"/);
|
|
79
|
+
assert.match(labelArtifact.content, /"canDelete": true/);
|
|
80
|
+
assert.doesNotMatch(labelArtifact.content, /dynamoDB/);
|
|
81
|
+
assert.match(labelArtifact.content, /GraphHandler/);
|
|
82
|
+
|
|
83
|
+
const valueArtifact = artifacts[1];
|
|
84
|
+
assert.match(
|
|
85
|
+
valueArtifact.content,
|
|
86
|
+
/"objectType": "itemPropertyPropertyValue"/
|
|
87
|
+
);
|
|
88
|
+
assert.match(valueArtifact.content, /"itemPropertyPropertyValueId"/);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('emitPropertyValueRelationshipSchemas returns 3 relationship schemas per propertyValue addOn', () => {
|
|
92
|
+
const objects = [
|
|
93
|
+
{
|
|
94
|
+
objectType: 'item',
|
|
95
|
+
serviceTag: 'ItemService',
|
|
96
|
+
storageResources: {
|
|
97
|
+
myGraph: {
|
|
98
|
+
storageType: 'graph',
|
|
99
|
+
graphServerTag: 'GraphHandler'
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
addOnDataStructure: [
|
|
103
|
+
{
|
|
104
|
+
type: 'propertyValue',
|
|
105
|
+
propertyValuePrefix: 'item'
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
const artifacts = emitPropertyValueRelationshipSchemas({
|
|
112
|
+
objects,
|
|
113
|
+
serviceTag: 'ItemService'
|
|
114
|
+
});
|
|
115
|
+
assert.equal(artifacts.length, 3);
|
|
116
|
+
|
|
117
|
+
const paths = artifacts.map((a) => a.path);
|
|
118
|
+
assert.deepEqual(paths, [
|
|
119
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/hasItemPropertyValue.js',
|
|
120
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/disabledItemPropertyValue.js',
|
|
121
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/isItemPropertyLabel.js'
|
|
122
|
+
]);
|
|
123
|
+
|
|
124
|
+
// 1. hasItemPropertyValue
|
|
125
|
+
const hasRel = artifacts[0];
|
|
126
|
+
assert.match(hasRel.content, /"hasItemPropertyValue"/);
|
|
127
|
+
assert.match(hasRel.content, /"generatedBy": "user"/);
|
|
128
|
+
assert.match(hasRel.content, /"objectType": "item"/);
|
|
129
|
+
assert.match(hasRel.content, /"objectType": "itemPropertyValue"/);
|
|
130
|
+
assert.match(hasRel.content, /"linkType": "one"/);
|
|
131
|
+
assert.match(hasRel.content, /"linkType": "many"/);
|
|
132
|
+
|
|
133
|
+
// 2. disabledItemPropertyValue
|
|
134
|
+
const disabledRel = artifacts[1];
|
|
135
|
+
assert.match(disabledRel.content, /"disabledItemPropertyValue"/);
|
|
136
|
+
assert.match(disabledRel.content, /"generatedBy": "user"/);
|
|
137
|
+
|
|
138
|
+
// 3. isItemPropertyLabel
|
|
139
|
+
const isRel = artifacts[2];
|
|
140
|
+
assert.match(isRel.content, /"isItemPropertyLabel"/);
|
|
141
|
+
assert.match(isRel.content, /"generatedBy": "systemNoUser"/);
|
|
142
|
+
assert.match(isRel.content, /"objectType": "itemPropertyLabel"/);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('managed paths return empty array when no propertyValue is present', () => {
|
|
146
|
+
const objects = [{ objectType: 'user', addOnDataStructure: [] }];
|
|
147
|
+
assert.deepEqual(propertyValueObjectSchemaManagedPaths(objects), []);
|
|
148
|
+
assert.deepEqual(propertyValueRelationshipSchemaManagedPaths(objects), []);
|
|
149
|
+
assert.deepEqual(emitPropertyValueObjectSchemas({ objects }), []);
|
|
150
|
+
assert.deepEqual(emitPropertyValueRelationshipSchemas({ objects }), []);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test('generate commits and cleans up propertyValue dynamic schemas', async () => {
|
|
154
|
+
const rootPath = await createProjectWithPropertyValue({ hasAddOn: true });
|
|
155
|
+
await generate(rootPath);
|
|
156
|
+
|
|
157
|
+
const labelPath =
|
|
158
|
+
'app/src/schemas/ObjectSchemas/generatedCode/propertyValue/itemPropertyLabel.js';
|
|
159
|
+
const valuePath =
|
|
160
|
+
'app/src/schemas/ObjectSchemas/generatedCode/propertyValue/itemPropertyValue.js';
|
|
161
|
+
const hasRelPath =
|
|
162
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/hasItemPropertyValue.js';
|
|
163
|
+
const disabledRelPath =
|
|
164
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/disabledItemPropertyValue.js';
|
|
165
|
+
const isRelPath =
|
|
166
|
+
'app/src/schemas/RelationshipSchemas/generatedCode/propertyValue/isItemPropertyLabel.js';
|
|
167
|
+
|
|
168
|
+
const labelContent = await readProjectFile(rootPath, labelPath);
|
|
169
|
+
assert.match(labelContent, /itemPropertyLabel/);
|
|
170
|
+
assert.match(labelContent, /GraphHandler/);
|
|
171
|
+
|
|
172
|
+
const valueContent = await readProjectFile(rootPath, valuePath);
|
|
173
|
+
assert.match(valueContent, /itemPropertyValue/);
|
|
174
|
+
|
|
175
|
+
const hasRelContent = await readProjectFile(rootPath, hasRelPath);
|
|
176
|
+
assert.match(hasRelContent, /hasItemPropertyValue/);
|
|
177
|
+
|
|
178
|
+
const disabledRelContent = await readProjectFile(rootPath, disabledRelPath);
|
|
179
|
+
assert.match(disabledRelContent, /disabledItemPropertyValue/);
|
|
180
|
+
|
|
181
|
+
const isRelContent = await readProjectFile(rootPath, isRelPath);
|
|
182
|
+
assert.match(isRelContent, /isItemPropertyLabel/);
|
|
183
|
+
|
|
184
|
+
// Re-run without addOn to verify stale file cleanup
|
|
185
|
+
await createProjectWithPropertyValue({ rootPath, hasAddOn: false });
|
|
186
|
+
await generate(rootPath);
|
|
187
|
+
|
|
188
|
+
await assert.rejects(readProjectFile(rootPath, labelPath), {
|
|
189
|
+
code: 'ENOENT'
|
|
190
|
+
});
|
|
191
|
+
await assert.rejects(readProjectFile(rootPath, valuePath), {
|
|
192
|
+
code: 'ENOENT'
|
|
193
|
+
});
|
|
194
|
+
await assert.rejects(readProjectFile(rootPath, hasRelPath), {
|
|
195
|
+
code: 'ENOENT'
|
|
196
|
+
});
|
|
197
|
+
await assert.rejects(readProjectFile(rootPath, disabledRelPath), {
|
|
198
|
+
code: 'ENOENT'
|
|
199
|
+
});
|
|
200
|
+
await assert.rejects(readProjectFile(rootPath, isRelPath), {
|
|
201
|
+
code: 'ENOENT'
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
async function createProjectWithPropertyValue({
|
|
206
|
+
rootPath: existingRoot,
|
|
207
|
+
hasAddOn = true
|
|
208
|
+
} = {}) {
|
|
209
|
+
let addOnContent = ' addOnDataStructure: [],';
|
|
210
|
+
if (hasAddOn) {
|
|
211
|
+
addOnContent = `
|
|
212
|
+
addOnDataStructure: [
|
|
213
|
+
{
|
|
214
|
+
type: 'propertyValue',
|
|
215
|
+
propertyValuePrefix: 'item'
|
|
216
|
+
}
|
|
217
|
+
],`;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const schemaContent = `export default [
|
|
221
|
+
{
|
|
222
|
+
objectType: 'item',
|
|
223
|
+
canDelete: false,
|
|
224
|
+
generatedBy: 'user',${addOnContent}
|
|
225
|
+
storageResources: {
|
|
226
|
+
graph: {
|
|
227
|
+
storageType: 'graph',
|
|
228
|
+
graphServerTag: 'GraphHandler'
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
fieldNames: {
|
|
232
|
+
itemId: {
|
|
233
|
+
type: 'string',
|
|
234
|
+
randomOnCreate: true,
|
|
235
|
+
canUpdate: false,
|
|
236
|
+
storageResourceTags: ['graph']
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
identifiers: [
|
|
240
|
+
{
|
|
241
|
+
type: 'partitionKey',
|
|
242
|
+
fieldName: 'itemId'
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
}
|
|
246
|
+
];
|
|
247
|
+
`;
|
|
248
|
+
|
|
249
|
+
if (existingRoot) {
|
|
250
|
+
await writeProjectFile(
|
|
251
|
+
existingRoot,
|
|
252
|
+
'app/src/schemas/ObjectSchemas/Item.js',
|
|
253
|
+
schemaContent
|
|
254
|
+
);
|
|
255
|
+
return existingRoot;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return await createTestProject({
|
|
259
|
+
prefix: 'izara-property-value-test-',
|
|
260
|
+
serviceTag: 'ItemService',
|
|
261
|
+
schemas: {
|
|
262
|
+
'ObjectSchemas/Item.js': schemaContent
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|