@auto-engineer/narrative 0.11.20 → 0.12.1
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +24 -0
- package/dist/src/fluent-builder.d.ts.map +1 -1
- package/dist/src/fluent-builder.js +9 -12
- package/dist/src/fluent-builder.js.map +1 -1
- package/dist/src/getNarratives.specs.js +43 -27
- package/dist/src/getNarratives.specs.js.map +1 -1
- package/dist/src/id/addAutoIds.specs.js +11 -25
- package/dist/src/id/addAutoIds.specs.js.map +1 -1
- package/dist/src/id/hasAllIds.specs.js +12 -12
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/model-to-narrative.specs.js +110 -108
- package/dist/src/model-to-narrative.specs.js.map +1 -1
- package/dist/src/narrative-context.d.ts +4 -2
- package/dist/src/narrative-context.d.ts.map +1 -1
- package/dist/src/narrative-context.js +98 -95
- package/dist/src/narrative-context.js.map +1 -1
- package/dist/src/narrative.d.ts +7 -1
- package/dist/src/narrative.d.ts.map +1 -1
- package/dist/src/narrative.js +27 -6
- package/dist/src/narrative.js.map +1 -1
- package/dist/src/samples/items.narrative.js +7 -7
- package/dist/src/samples/items.narrative.js.map +1 -1
- package/dist/src/samples/place-order.narrative.js +4 -4
- package/dist/src/samples/place-order.narrative.js.map +1 -1
- package/dist/src/samples/questionnaires.narrative.js +16 -18
- package/dist/src/samples/questionnaires.narrative.js.map +1 -1
- package/dist/src/samples/seasonal-assistant.schema.json +37 -31
- package/dist/src/schema.d.ts +91 -462
- package/dist/src/schema.d.ts.map +1 -1
- package/dist/src/schema.js +22 -24
- package/dist/src/schema.js.map +1 -1
- package/dist/src/slice-builder.js +2 -2
- package/dist/src/slice-builder.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/flow.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/flow.js +34 -10
- package/dist/src/transformers/model-to-narrative/generators/flow.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/imports.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/generators/imports.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/imports.js +2 -1
- package/dist/src/transformers/model-to-narrative/generators/imports.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/index.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/index.js +4 -8
- package/dist/src/transformers/narrative-to-model/index.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/type-inference.specs.js +3 -3
- package/dist/src/transformers/narrative-to-model/type-inference.specs.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/fluent-builder.ts +9 -12
- package/src/getNarratives.specs.ts +43 -28
- package/src/id/addAutoIds.specs.ts +11 -25
- package/src/id/hasAllIds.specs.ts +12 -12
- package/src/index.ts +2 -1
- package/src/model-to-narrative.specs.ts +110 -108
- package/src/narrative-context.ts +103 -101
- package/src/narrative.ts +44 -6
- package/src/samples/items.narrative.ts +7 -7
- package/src/samples/place-order.narrative.ts +4 -4
- package/src/samples/questionnaires.narrative.ts +17 -18
- package/src/samples/seasonal-assistant.schema.json +37 -31
- package/src/schema.ts +33 -24
- package/src/slice-builder.ts +2 -2
- package/src/transformers/model-to-narrative/generators/flow.ts +53 -23
- package/src/transformers/model-to-narrative/generators/imports.ts +2 -1
- package/src/transformers/narrative-to-model/index.ts +4 -7
- package/src/transformers/narrative-to-model/type-inference.specs.ts +3 -3
package/src/schema.ts
CHANGED
|
@@ -215,17 +215,38 @@ const SpecSchema = z
|
|
|
215
215
|
})
|
|
216
216
|
.describe('Specification with business rules');
|
|
217
217
|
|
|
218
|
+
const ItNode = z
|
|
219
|
+
.object({
|
|
220
|
+
type: z.literal('it'),
|
|
221
|
+
id: z.string().optional(),
|
|
222
|
+
title: z.string(),
|
|
223
|
+
})
|
|
224
|
+
.strict();
|
|
225
|
+
|
|
226
|
+
type ClientSpecNode =
|
|
227
|
+
| { type: 'it'; id?: string; title: string }
|
|
228
|
+
| { type: 'describe'; id?: string; title?: string; children?: ClientSpecNode[] };
|
|
229
|
+
|
|
230
|
+
export const ClientSpecNodeSchema: z.ZodType<ClientSpecNode> = z.lazy(() =>
|
|
231
|
+
z.union([
|
|
232
|
+
ItNode,
|
|
233
|
+
z
|
|
234
|
+
.object({
|
|
235
|
+
type: z.literal('describe'),
|
|
236
|
+
id: z.string().optional(),
|
|
237
|
+
title: z.string().optional(),
|
|
238
|
+
children: z.array(ClientSpecNodeSchema).default([]),
|
|
239
|
+
})
|
|
240
|
+
.strict(),
|
|
241
|
+
]),
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
export const ClientSpecSchema = z.array(ClientSpecNodeSchema).default([]);
|
|
245
|
+
|
|
218
246
|
const CommandSliceSchema = BaseSliceSchema.extend({
|
|
219
247
|
type: z.literal('command'),
|
|
220
248
|
client: z.object({
|
|
221
|
-
|
|
222
|
-
specs: z
|
|
223
|
-
.object({
|
|
224
|
-
name: z.string().describe('Spec group name'),
|
|
225
|
-
rules: z.array(z.string()).describe('UI specifications (should statements)'),
|
|
226
|
-
})
|
|
227
|
-
.optional()
|
|
228
|
-
.describe('Client-side specifications'),
|
|
249
|
+
specs: ClientSpecSchema,
|
|
229
250
|
}),
|
|
230
251
|
request: z.string().describe('Command request (GraphQL, REST endpoint, or other query format)').optional(),
|
|
231
252
|
server: z.object({
|
|
@@ -238,14 +259,7 @@ const CommandSliceSchema = BaseSliceSchema.extend({
|
|
|
238
259
|
const QuerySliceSchema = BaseSliceSchema.extend({
|
|
239
260
|
type: z.literal('query'),
|
|
240
261
|
client: z.object({
|
|
241
|
-
|
|
242
|
-
specs: z
|
|
243
|
-
.object({
|
|
244
|
-
name: z.string().describe('Spec group name'),
|
|
245
|
-
rules: z.array(z.string()).describe('UI specifications (should statements)'),
|
|
246
|
-
})
|
|
247
|
-
.optional()
|
|
248
|
-
.describe('Client-side specifications'),
|
|
262
|
+
specs: ClientSpecSchema,
|
|
249
263
|
}),
|
|
250
264
|
request: z.string().describe('Query request (GraphQL, REST endpoint, or other query format)').optional(),
|
|
251
265
|
server: z.object({
|
|
@@ -270,14 +284,7 @@ const ReactSliceSchema = BaseSliceSchema.extend({
|
|
|
270
284
|
const ExperienceSliceSchema = BaseSliceSchema.extend({
|
|
271
285
|
type: z.literal('experience'),
|
|
272
286
|
client: z.object({
|
|
273
|
-
|
|
274
|
-
specs: z
|
|
275
|
-
.object({
|
|
276
|
-
name: z.string().describe('Spec group name'),
|
|
277
|
-
rules: z.array(z.string()).describe('UI specifications (should statements)'),
|
|
278
|
-
})
|
|
279
|
-
.optional()
|
|
280
|
-
.describe('Client-side specifications'),
|
|
287
|
+
specs: ClientSpecSchema,
|
|
281
288
|
}),
|
|
282
289
|
}).describe('Experience slice for user interactions and UI behavior');
|
|
283
290
|
|
|
@@ -387,6 +394,8 @@ export const modelSchema = z
|
|
|
387
394
|
})
|
|
388
395
|
.describe('Complete system specification with all implementation details');
|
|
389
396
|
|
|
397
|
+
export type { ClientSpecNode };
|
|
398
|
+
|
|
390
399
|
export {
|
|
391
400
|
StateExampleSchema,
|
|
392
401
|
MessageFieldSchema,
|
package/src/slice-builder.ts
CHANGED
|
@@ -47,7 +47,7 @@ export const createSliceBuilder = (config: SliceConfig = {}): SliceBuilder => ({
|
|
|
47
47
|
const slice: CommandSlice = {
|
|
48
48
|
type: 'command',
|
|
49
49
|
name,
|
|
50
|
-
client: {
|
|
50
|
+
client: { specs: [] },
|
|
51
51
|
server: { description: '', specs: { name: '', rules: [] }, data: undefined },
|
|
52
52
|
// Optional fields
|
|
53
53
|
...(config.eventStream != null && { stream: config.eventStream }),
|
|
@@ -66,7 +66,7 @@ export const createSliceBuilder = (config: SliceConfig = {}): SliceBuilder => ({
|
|
|
66
66
|
const slice: QuerySlice = {
|
|
67
67
|
type: 'query',
|
|
68
68
|
name,
|
|
69
|
-
client: {
|
|
69
|
+
client: { specs: [] },
|
|
70
70
|
server: { description: '', specs: { name: '', rules: [] }, data: undefined },
|
|
71
71
|
// Optional fields
|
|
72
72
|
...(config.eventStream != null && { stream: config.eventStream }),
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
DataSourceSchema,
|
|
14
14
|
DestinationSchema,
|
|
15
15
|
OriginSchema,
|
|
16
|
+
type ClientSpecNode,
|
|
16
17
|
} from '../../../schema';
|
|
17
18
|
|
|
18
19
|
type CommandSlice = z.infer<typeof CommandSliceSchema>;
|
|
@@ -27,33 +28,55 @@ type Destination = z.infer<typeof DestinationSchema>;
|
|
|
27
28
|
type Origin = z.infer<typeof OriginSchema>;
|
|
28
29
|
type Slice = CommandSlice | QuerySlice | ReactSlice | ExperienceSlice;
|
|
29
30
|
|
|
30
|
-
function
|
|
31
|
+
function buildClientSpecNode(
|
|
31
32
|
ts: typeof import('typescript'),
|
|
32
33
|
f: tsNS.NodeFactory,
|
|
33
|
-
|
|
34
|
-
) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
f.createCallExpression(f.createIdentifier('should'), undefined, [f.createStringLiteral(txt)]),
|
|
38
|
-
),
|
|
39
|
-
);
|
|
34
|
+
node: ClientSpecNode,
|
|
35
|
+
): tsNS.Statement {
|
|
36
|
+
if (node.type === 'it') {
|
|
37
|
+
const args: tsNS.Expression[] = [];
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
if (node.id !== undefined && node.id !== '') {
|
|
40
|
+
args.push(f.createStringLiteral(node.id));
|
|
41
|
+
args.push(f.createStringLiteral(node.title));
|
|
42
|
+
} else {
|
|
43
|
+
args.push(f.createStringLiteral(node.title));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return f.createExpressionStatement(f.createCallExpression(f.createIdentifier('it'), undefined, args));
|
|
47
|
+
} else {
|
|
48
|
+
const childStatements = (node.children || []).map((child) => buildClientSpecNode(ts, f, child));
|
|
49
|
+
|
|
50
|
+
const args: tsNS.Expression[] = [];
|
|
51
|
+
|
|
52
|
+
if (node.id !== undefined && node.id !== '') {
|
|
53
|
+
args.push(f.createStringLiteral(node.id));
|
|
54
|
+
args.push(f.createStringLiteral(node.title ?? ''));
|
|
55
|
+
} else {
|
|
56
|
+
args.push(f.createStringLiteral(node.title ?? ''));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
args.push(
|
|
60
|
+
f.createArrowFunction(
|
|
61
|
+
undefined,
|
|
62
|
+
undefined,
|
|
63
|
+
[],
|
|
64
|
+
undefined,
|
|
65
|
+
f.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
66
|
+
f.createBlock(childStatements, true),
|
|
67
|
+
),
|
|
68
|
+
);
|
|
49
69
|
|
|
50
|
-
|
|
51
|
-
if (specs.name && specs.name.trim() !== '') {
|
|
52
|
-
args.push(f.createStringLiteral(specs.name));
|
|
70
|
+
return f.createExpressionStatement(f.createCallExpression(f.createIdentifier('describe'), undefined, args));
|
|
53
71
|
}
|
|
54
|
-
|
|
72
|
+
}
|
|
55
73
|
|
|
56
|
-
|
|
74
|
+
function buildClientSpecs(
|
|
75
|
+
ts: typeof import('typescript'),
|
|
76
|
+
f: tsNS.NodeFactory,
|
|
77
|
+
specs: ClientSpecNode[],
|
|
78
|
+
): tsNS.Statement[] {
|
|
79
|
+
return specs.map((node) => buildClientSpecNode(ts, f, node));
|
|
57
80
|
}
|
|
58
81
|
|
|
59
82
|
function buildInitialChain(
|
|
@@ -347,7 +370,14 @@ function addClientToChain(
|
|
|
347
370
|
chain: tsNS.Expression,
|
|
348
371
|
slice: CommandSlice | QuerySlice | ReactSlice | ExperienceSlice,
|
|
349
372
|
): tsNS.Expression {
|
|
350
|
-
if (
|
|
373
|
+
if (
|
|
374
|
+
'client' in slice &&
|
|
375
|
+
slice.client !== null &&
|
|
376
|
+
slice.client !== undefined &&
|
|
377
|
+
'specs' in slice.client &&
|
|
378
|
+
slice.client.specs !== undefined &&
|
|
379
|
+
slice.client.specs.length > 0
|
|
380
|
+
) {
|
|
351
381
|
return f.createCallExpression(f.createPropertyAccessExpression(chain, f.createIdentifier('client')), undefined, [
|
|
352
382
|
f.createArrowFunction(
|
|
353
383
|
undefined,
|
|
@@ -355,7 +385,7 @@ function addClientToChain(
|
|
|
355
385
|
[],
|
|
356
386
|
undefined,
|
|
357
387
|
f.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
358
|
-
f.createBlock(
|
|
388
|
+
f.createBlock(buildClientSpecs(ts, f, slice.client.specs), true),
|
|
359
389
|
),
|
|
360
390
|
]);
|
|
361
391
|
}
|
|
@@ -129,11 +129,9 @@ function createTypeResolver(
|
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
function
|
|
132
|
+
function getServerSpecs(slice: Slice) {
|
|
133
133
|
if ('server' in slice && slice.server?.specs !== undefined) {
|
|
134
134
|
return slice.server.specs;
|
|
135
|
-
} else if ('client' in slice && slice.client?.specs !== undefined) {
|
|
136
|
-
return slice.client.specs;
|
|
137
135
|
}
|
|
138
136
|
return undefined;
|
|
139
137
|
}
|
|
@@ -144,11 +142,10 @@ function processSliceSpecs(
|
|
|
144
142
|
messages: Map<string, Message>,
|
|
145
143
|
exampleShapeHints: ExampleShapeHints,
|
|
146
144
|
): void {
|
|
147
|
-
const
|
|
145
|
+
const serverSpec = getServerSpecs(slice);
|
|
148
146
|
|
|
149
|
-
if (
|
|
150
|
-
|
|
151
|
-
// Only process rule objects (server specs), not string rules (client specs)
|
|
147
|
+
if (serverSpec !== undefined && Array.isArray(serverSpec.rules)) {
|
|
148
|
+
serverSpec.rules.forEach((rule: unknown) => {
|
|
152
149
|
if (
|
|
153
150
|
typeof rule === 'object' &&
|
|
154
151
|
rule !== null &&
|
|
@@ -13,7 +13,7 @@ describe('Type inference in narrative-to-model transformer', () => {
|
|
|
13
13
|
id: 'SLICE-001',
|
|
14
14
|
type: 'command',
|
|
15
15
|
name: 'Submit Answer Command',
|
|
16
|
-
client: {
|
|
16
|
+
client: { specs: [] },
|
|
17
17
|
server: {
|
|
18
18
|
description: 'Submit answer server',
|
|
19
19
|
specs: {
|
|
@@ -59,7 +59,7 @@ describe('Type inference in narrative-to-model transformer', () => {
|
|
|
59
59
|
id: 'SLICE-002',
|
|
60
60
|
type: 'command',
|
|
61
61
|
name: 'Submit Questionnaire Command',
|
|
62
|
-
client: {
|
|
62
|
+
client: { specs: [] },
|
|
63
63
|
server: {
|
|
64
64
|
description: 'Submit questionnaire server',
|
|
65
65
|
specs: {
|
|
@@ -132,7 +132,7 @@ describe('Type inference in narrative-to-model transformer', () => {
|
|
|
132
132
|
id: 'SLICE-001',
|
|
133
133
|
type: 'command',
|
|
134
134
|
name: 'Single Object Command',
|
|
135
|
-
client: {
|
|
135
|
+
client: { specs: [] },
|
|
136
136
|
server: {
|
|
137
137
|
description: 'Single object server',
|
|
138
138
|
specs: {
|