@auto-engineer/server-generator-nestjs 0.11.16

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 (143) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/LICENSE +10 -0
  3. package/README.md +290 -0
  4. package/dist/src/codegen/entity-consolidation.d.ts +19 -0
  5. package/dist/src/codegen/entity-consolidation.d.ts.map +1 -0
  6. package/dist/src/codegen/entity-consolidation.js +134 -0
  7. package/dist/src/codegen/entity-consolidation.js.map +1 -0
  8. package/dist/src/codegen/extract/commands.d.ts +25 -0
  9. package/dist/src/codegen/extract/commands.d.ts.map +1 -0
  10. package/dist/src/codegen/extract/commands.js +67 -0
  11. package/dist/src/codegen/extract/commands.js.map +1 -0
  12. package/dist/src/codegen/extract/data-sink.d.ts +6 -0
  13. package/dist/src/codegen/extract/data-sink.d.ts.map +1 -0
  14. package/dist/src/codegen/extract/data-sink.js +78 -0
  15. package/dist/src/codegen/extract/data-sink.js.map +1 -0
  16. package/dist/src/codegen/extract/events.d.ts +10 -0
  17. package/dist/src/codegen/extract/events.d.ts.map +1 -0
  18. package/dist/src/codegen/extract/events.js +42 -0
  19. package/dist/src/codegen/extract/events.js.map +1 -0
  20. package/dist/src/codegen/extract/fields.d.ts +3 -0
  21. package/dist/src/codegen/extract/fields.d.ts.map +1 -0
  22. package/dist/src/codegen/extract/fields.js +9 -0
  23. package/dist/src/codegen/extract/fields.js.map +1 -0
  24. package/dist/src/codegen/extract/graphql.d.ts +14 -0
  25. package/dist/src/codegen/extract/graphql.d.ts.map +1 -0
  26. package/dist/src/codegen/extract/graphql.js +81 -0
  27. package/dist/src/codegen/extract/graphql.js.map +1 -0
  28. package/dist/src/codegen/extract/gwt.d.ts +6 -0
  29. package/dist/src/codegen/extract/gwt.d.ts.map +1 -0
  30. package/dist/src/codegen/extract/gwt.js +64 -0
  31. package/dist/src/codegen/extract/gwt.js.map +1 -0
  32. package/dist/src/codegen/extract/imports.d.ts +29 -0
  33. package/dist/src/codegen/extract/imports.d.ts.map +1 -0
  34. package/dist/src/codegen/extract/imports.js +55 -0
  35. package/dist/src/codegen/extract/imports.js.map +1 -0
  36. package/dist/src/codegen/extract/index.d.ts +10 -0
  37. package/dist/src/codegen/extract/index.d.ts.map +1 -0
  38. package/dist/src/codegen/extract/index.js +10 -0
  39. package/dist/src/codegen/extract/index.js.map +1 -0
  40. package/dist/src/codegen/extract/messages.d.ts +17 -0
  41. package/dist/src/codegen/extract/messages.d.ts.map +1 -0
  42. package/dist/src/codegen/extract/messages.js +172 -0
  43. package/dist/src/codegen/extract/messages.js.map +1 -0
  44. package/dist/src/codegen/extract/projection.d.ts +5 -0
  45. package/dist/src/codegen/extract/projection.d.ts.map +1 -0
  46. package/dist/src/codegen/extract/projection.js +44 -0
  47. package/dist/src/codegen/extract/projection.js.map +1 -0
  48. package/dist/src/codegen/extract/query.d.ts +14 -0
  49. package/dist/src/codegen/extract/query.d.ts.map +1 -0
  50. package/dist/src/codegen/extract/query.js +17 -0
  51. package/dist/src/codegen/extract/query.js.map +1 -0
  52. package/dist/src/codegen/extract/states.d.ts +5 -0
  53. package/dist/src/codegen/extract/states.d.ts.map +1 -0
  54. package/dist/src/codegen/extract/states.js +48 -0
  55. package/dist/src/codegen/extract/states.js.map +1 -0
  56. package/dist/src/codegen/extract/step-converter.d.ts +17 -0
  57. package/dist/src/codegen/extract/step-converter.d.ts.map +1 -0
  58. package/dist/src/codegen/extract/step-converter.js +82 -0
  59. package/dist/src/codegen/extract/step-converter.js.map +1 -0
  60. package/dist/src/codegen/extract/step-types.d.ts +29 -0
  61. package/dist/src/codegen/extract/step-types.d.ts.map +1 -0
  62. package/dist/src/codegen/extract/step-types.js +16 -0
  63. package/dist/src/codegen/extract/step-types.js.map +1 -0
  64. package/dist/src/codegen/extract/type-helpers.d.ts +13 -0
  65. package/dist/src/codegen/extract/type-helpers.d.ts.map +1 -0
  66. package/dist/src/codegen/extract/type-helpers.js +98 -0
  67. package/dist/src/codegen/extract/type-helpers.js.map +1 -0
  68. package/dist/src/codegen/scaffoldFromSchema.d.ts +9 -0
  69. package/dist/src/codegen/scaffoldFromSchema.d.ts.map +1 -0
  70. package/dist/src/codegen/scaffoldFromSchema.js +389 -0
  71. package/dist/src/codegen/scaffoldFromSchema.js.map +1 -0
  72. package/dist/src/codegen/templates/command/command.ts.ejs +16 -0
  73. package/dist/src/codegen/templates/command/handler.specs.ts.ejs +50 -0
  74. package/dist/src/codegen/templates/command/handler.ts.ejs +30 -0
  75. package/dist/src/codegen/templates/command/input.ts.ejs +23 -0
  76. package/dist/src/codegen/templates/command/resolver.ts.ejs +56 -0
  77. package/dist/src/codegen/templates/entity/entity.ts.ejs +35 -0
  78. package/dist/src/codegen/templates/entity/index.ts.ejs +6 -0
  79. package/dist/src/codegen/templates/module/app-module.ts.ejs +65 -0
  80. package/dist/src/codegen/templates/module/domain-module.ts.ejs +46 -0
  81. package/dist/src/codegen/templates/query/handler.ts.ejs +25 -0
  82. package/dist/src/codegen/templates/query/query.ts.ejs +1 -0
  83. package/dist/src/codegen/templates/query/resolver.ts.ejs +20 -0
  84. package/dist/src/codegen/templates/query/type.ts.ejs +24 -0
  85. package/dist/src/codegen/types.d.ts +38 -0
  86. package/dist/src/codegen/types.d.ts.map +1 -0
  87. package/dist/src/codegen/types.js +2 -0
  88. package/dist/src/codegen/types.js.map +1 -0
  89. package/dist/src/codegen/utils/path.d.ts +4 -0
  90. package/dist/src/codegen/utils/path.d.ts.map +1 -0
  91. package/dist/src/codegen/utils/path.js +18 -0
  92. package/dist/src/codegen/utils/path.js.map +1 -0
  93. package/dist/src/commands/generate-server.d.ts +28 -0
  94. package/dist/src/commands/generate-server.d.ts.map +1 -0
  95. package/dist/src/commands/generate-server.js +421 -0
  96. package/dist/src/commands/generate-server.js.map +1 -0
  97. package/dist/src/index.d.ts +3 -0
  98. package/dist/src/index.d.ts.map +1 -0
  99. package/dist/src/index.js +3 -0
  100. package/dist/src/index.js.map +1 -0
  101. package/dist/src/shared/graphql-types.ts +19 -0
  102. package/dist/src/shared/main.ts +27 -0
  103. package/dist/src/shared/mikro-orm.config.ts +18 -0
  104. package/dist/tsconfig.tsbuildinfo +1 -0
  105. package/package.json +70 -0
  106. package/src/codegen/entity-consolidation.ts +213 -0
  107. package/src/codegen/extract/commands.ts +108 -0
  108. package/src/codegen/extract/data-sink.ts +93 -0
  109. package/src/codegen/extract/events.ts +63 -0
  110. package/src/codegen/extract/fields.ts +17 -0
  111. package/src/codegen/extract/graphql.ts +103 -0
  112. package/src/codegen/extract/gwt.ts +79 -0
  113. package/src/codegen/extract/imports.ts +71 -0
  114. package/src/codegen/extract/index.ts +9 -0
  115. package/src/codegen/extract/messages.ts +232 -0
  116. package/src/codegen/extract/projection.ts +62 -0
  117. package/src/codegen/extract/query.ts +28 -0
  118. package/src/codegen/extract/states.ts +69 -0
  119. package/src/codegen/extract/step-converter.ts +124 -0
  120. package/src/codegen/extract/step-types.ts +51 -0
  121. package/src/codegen/extract/type-helpers.ts +102 -0
  122. package/src/codegen/scaffoldFromSchema.ts +559 -0
  123. package/src/codegen/templates/command/command.ts.ejs +16 -0
  124. package/src/codegen/templates/command/handler.specs.ts.ejs +50 -0
  125. package/src/codegen/templates/command/handler.ts.ejs +30 -0
  126. package/src/codegen/templates/command/input.ts.ejs +23 -0
  127. package/src/codegen/templates/command/resolver.ts.ejs +56 -0
  128. package/src/codegen/templates/entity/entity.ts.ejs +35 -0
  129. package/src/codegen/templates/entity/index.ts.ejs +6 -0
  130. package/src/codegen/templates/module/app-module.ts.ejs +65 -0
  131. package/src/codegen/templates/module/domain-module.ts.ejs +46 -0
  132. package/src/codegen/templates/query/handler.ts.ejs +25 -0
  133. package/src/codegen/templates/query/query.ts.ejs +1 -0
  134. package/src/codegen/templates/query/resolver.ts.ejs +20 -0
  135. package/src/codegen/templates/query/type.ts.ejs +24 -0
  136. package/src/codegen/types.ts +39 -0
  137. package/src/codegen/utils/path.ts +20 -0
  138. package/src/commands/generate-server.ts +551 -0
  139. package/src/index.ts +10 -0
  140. package/src/shared/graphql-types.ts +19 -0
  141. package/src/shared/main.ts +27 -0
  142. package/src/shared/mikro-orm.config.ts +18 -0
  143. package/tsconfig.json +12 -0
@@ -0,0 +1,5 @@
1
+
2
+ > @auto-engineer/server-generator-nestjs@0.11.16 build /home/runner/work/auto-engineer/auto-engineer/packages/server-generator-nestjs
3
+ > tsc && tsx ../../scripts/fix-esm-imports.ts && rm -rf dist/src/codegen/templates && mkdir -p dist/src/codegen && cp -r src/codegen/templates dist/src/codegen/templates && cp -r src/shared dist/src
4
+
5
+ Fixed ESM imports in dist/
package/LICENSE ADDED
@@ -0,0 +1,10 @@
1
+ Elastic License 2.0
2
+
3
+ Copyright 2024 Sam Hatoum
4
+
5
+ This software and associated documentation files (the "Software") are licensed under the Elastic License 2.0 (the "License"). You may not use this file except in compliance with the License.
6
+
7
+ You may obtain a copy of the License at:
8
+ https://www.elastic.co/licensing/elastic-license
9
+
10
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
package/README.md ADDED
@@ -0,0 +1,290 @@
1
+ # @auto-engineer/server-generator-nestjs
2
+
3
+ | | |
4
+ | --- | --- |
5
+ | **Status** | EXPERIMENTAL - NOT READY FOR PRODUCTION |
6
+ | **Stability** | APIs will change without notice |
7
+ | **Completeness** | Features may be incomplete or broken |
8
+
9
+ Generates complete NestJS servers from narrative domain models with CQRS, GraphQL, and MikroORM.
10
+
11
+ ---
12
+
13
+ ## Purpose
14
+
15
+ Without `@auto-engineer/server-generator-nestjs`, you would have to manually scaffold NestJS modules, wire up CQRS command/query handlers, configure GraphQL resolvers, define MikroORM entities, and write boilerplate test files for every domain slice.
16
+
17
+ This package takes a narrative model (JSON) describing your domain flows and slices, then generates a fully functional NestJS server with:
18
+
19
+ - CQRS pattern via `@nestjs/cqrs` for command and query separation
20
+ - GraphQL API via Apollo Server with auto-generated resolvers
21
+ - MikroORM entities with SQLite persistence
22
+ - Test scaffolds for each command handler
23
+
24
+ The generated server is immediately runnable and provides a foundation for domain-driven development.
25
+
26
+ ---
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ pnpm add @auto-engineer/server-generator-nestjs
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ This package generates NestJS servers from domain models. Here is how to use it.
37
+
38
+ ### 1. Register the handlers
39
+
40
+ ```typescript
41
+ import { COMMANDS } from "@auto-engineer/server-generator-nestjs";
42
+ import { createMessageBus } from "@auto-engineer/message-bus";
43
+
44
+ const bus = createMessageBus();
45
+ COMMANDS.forEach((cmd) => bus.register(cmd));
46
+ ```
47
+
48
+ ### 2. Send a command
49
+
50
+ ```typescript
51
+ const result = await bus.send({
52
+ type: "GenerateServer",
53
+ data: {
54
+ modelPath: ".context/model.json",
55
+ destination: ".",
56
+ },
57
+ });
58
+
59
+ console.log(result);
60
+ // → { type: 'ServerGenerated', data: { serverDir: './server', ... } }
61
+ ```
62
+
63
+ The command reads your model file, generates a complete NestJS server in the `server/` directory, and installs dependencies automatically.
64
+
65
+ ---
66
+
67
+ ## How-to Guides
68
+
69
+ ### Run via CLI
70
+
71
+ ```bash
72
+ auto generate:server --model-path=.context/model.json --destination=.
73
+ ```
74
+
75
+ ### Run Programmatically
76
+
77
+ ```typescript
78
+ import { commandHandler } from "@auto-engineer/server-generator-nestjs";
79
+
80
+ const result = await commandHandler.handle({
81
+ type: "GenerateServer",
82
+ data: {
83
+ modelPath: ".context/model.json",
84
+ destination: "/path/to/project",
85
+ },
86
+ requestId: "req-123",
87
+ });
88
+ ```
89
+
90
+ ### Handle Errors
91
+
92
+ ```typescript
93
+ if (result.type === "ServerGenerationFailed") {
94
+ console.error(result.data.error);
95
+ }
96
+ ```
97
+
98
+ ### Handle Per-Slice Progress
99
+
100
+ The handler emits `SliceGeneratedEvent` for each domain slice processed:
101
+
102
+ ```typescript
103
+ const events = await commandHandler.handle(command);
104
+
105
+ for (const event of events) {
106
+ if (event.type === "SliceGenerated") {
107
+ console.log(`Generated: ${event.data.flowName}.${event.data.sliceName}`);
108
+ }
109
+ }
110
+ ```
111
+
112
+ ### Enable Debug Logging
113
+
114
+ ```bash
115
+ DEBUG=auto:server-generator-nestjs:* pnpm auto generate:server
116
+ ```
117
+
118
+ Available debug namespaces:
119
+
120
+ - `auto:server-generator-nestjs` - General operation logging
121
+ - `auto:server-generator-nestjs:schema` - Model parsing details
122
+ - `auto:server-generator-nestjs:files` - File copy operations
123
+ - `auto:server-generator-nestjs:deps` - Dependency installation
124
+ - `auto:server-generator-nestjs:scaffold` - Scaffold generation
125
+
126
+ ---
127
+
128
+ ## API Reference
129
+
130
+ ### Exports
131
+
132
+ ```typescript
133
+ import { COMMANDS } from "@auto-engineer/server-generator-nestjs";
134
+
135
+ import type {
136
+ GenerateServerCommand,
137
+ GenerateServerEvents,
138
+ ServerGeneratedEvent,
139
+ ServerGenerationFailedEvent,
140
+ SliceGeneratedEvent,
141
+ } from "@auto-engineer/server-generator-nestjs";
142
+ ```
143
+
144
+ ### Commands
145
+
146
+ | Command | CLI Alias | Description |
147
+ | ---------------- | ----------------- | --------------------------------- |
148
+ | `GenerateServer` | `generate:server` | Generate NestJS server from model |
149
+
150
+ ### Command Fields
151
+
152
+ | Field | Type | Required | Description |
153
+ | ------------- | -------- | -------- | ------------------------------------------ |
154
+ | `modelPath` | `string` | Yes | Path to the JSON model file |
155
+ | `destination` | `string` | Yes | Destination directory for generated server |
156
+
157
+ ### Events
158
+
159
+ | Event | Description |
160
+ | ----------------------------- | -------------------------------- |
161
+ | `ServerGeneratedEvent` | Emitted on successful generation |
162
+ | `ServerGenerationFailedEvent` | Emitted when generation fails |
163
+ | `SliceGeneratedEvent` | Emitted for each slice processed |
164
+
165
+ ### ServerGeneratedEvent Data
166
+
167
+ ```typescript
168
+ {
169
+ modelPath: string;
170
+ destination: string;
171
+ serverDir: string;
172
+ contextSchemaGraphQL?: string;
173
+ }
174
+ ```
175
+
176
+ ### ServerGenerationFailedEvent Data
177
+
178
+ ```typescript
179
+ {
180
+ modelPath: string;
181
+ destination: string;
182
+ error: string;
183
+ }
184
+ ```
185
+
186
+ ### SliceGeneratedEvent Data
187
+
188
+ ```typescript
189
+ {
190
+ flowName: string;
191
+ sliceName: string;
192
+ sliceType: string;
193
+ schemaPath: string;
194
+ slicePath: string;
195
+ }
196
+ ```
197
+
198
+ ---
199
+
200
+ ## Architecture
201
+
202
+ ```
203
+ src/
204
+ ├── index.ts # Package entry point (exports COMMANDS)
205
+ ├── commands/
206
+ │ └── generate-server.ts # Main command handler
207
+ ├── codegen/
208
+ │ ├── scaffoldFromSchema.ts # Scaffold orchestrator
209
+ │ ├── entity-consolidation.ts # Entity field merging
210
+ │ ├── types.ts # Core type definitions
211
+ │ ├── extract/ # Message/GWT extraction
212
+ │ │ ├── commands.ts # Command extraction
213
+ │ │ ├── events.ts # Event extraction
214
+ │ │ ├── states.ts # State extraction
215
+ │ │ ├── fields.ts # Field extraction
216
+ │ │ ├── gwt.ts # GWT mapping builders
217
+ │ │ ├── graphql.ts # GraphQL query parsing
218
+ │ │ └── imports.ts # Cross-slice imports
219
+ │ ├── templates/ # EJS templates
220
+ │ │ ├── command/ # Command slice templates
221
+ │ │ ├── query/ # Query slice templates
222
+ │ │ ├── entity/ # Entity templates
223
+ │ │ └── module/ # NestJS module templates
224
+ │ └── utils/
225
+ │ └── path.ts # Path utilities
226
+ └── shared/ # Files copied to generated server
227
+ ├── main.ts # NestJS bootstrap
228
+ ├── mikro-orm.config.ts # Database configuration
229
+ └── graphql-types.ts # Shared GraphQL types
230
+ ```
231
+
232
+ ### Generated Server Structure
233
+
234
+ The command generates the following structure:
235
+
236
+ ```
237
+ server/
238
+ ├── package.json
239
+ ├── tsconfig.json
240
+ ├── vitest.config.ts
241
+ ├── mikro-orm.config.ts
242
+ └── src/
243
+ ├── main.ts
244
+ └── domain/
245
+ ├── shared/
246
+ │ └── graphql-types.ts
247
+ ├── {flow-name}/
248
+ │ ├── {slice-name}/
249
+ │ │ ├── command.ts
250
+ │ │ ├── input.ts
251
+ │ │ ├── handler.ts
252
+ │ │ ├── handler.specs.ts
253
+ │ │ └── resolver.ts
254
+ │ └── entities/
255
+ │ └── {entity}.entity.ts
256
+ └── {flow-name}.module.ts
257
+ ```
258
+
259
+ ### Dependencies
260
+
261
+ **Monorepo:**
262
+
263
+ | Package | Usage |
264
+ | -------------------------- | ----------------------------- |
265
+ | `@auto-engineer/narrative` | Domain model type definitions |
266
+
267
+ **External:**
268
+
269
+ | Package | Usage |
270
+ | ------------------- | --------------------------- |
271
+ | `@nestjs/cqrs` | CQRS command/query pattern |
272
+ | `@nestjs/graphql` | GraphQL schema generation |
273
+ | `@nestjs/apollo` | Apollo Server integration |
274
+ | `@mikro-orm/core` | ORM for entity persistence |
275
+ | `@mikro-orm/sqlite` | SQLite database driver |
276
+ | `ejs` | Template rendering engine |
277
+ | `prettier` | Generated code formatting |
278
+ | `change-case` | Naming convention utilities |
279
+ | `execa` | Dependency installation |
280
+
281
+ ---
282
+
283
+ ## Known Limitations
284
+
285
+ This generator is experimental. Current limitations include:
286
+
287
+ - Schema extraction is incomplete for complex slice types
288
+ - Generated code may require manual fixes
289
+ - Test coverage is minimal
290
+ - Only SQLite persistence is supported
@@ -0,0 +1,19 @@
1
+ import type { Narrative } from '@auto-engineer/narrative';
2
+ import type { MessageDefinition } from './types.js';
3
+ export interface EntityField {
4
+ name: string;
5
+ tsType: string;
6
+ nullable: boolean;
7
+ isPrimary: boolean;
8
+ isEnum: boolean;
9
+ enumName?: string;
10
+ indexed: boolean;
11
+ }
12
+ export interface ConsolidatedEntity {
13
+ entityName: string;
14
+ tableName: string;
15
+ fields: EntityField[];
16
+ enumImports: string[];
17
+ }
18
+ export declare function consolidateEntityFields(flow: Narrative, messages: MessageDefinition[], unionToEnumName: Map<string, string>): ConsolidatedEntity;
19
+ //# sourceMappingURL=entity-consolidation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-consolidation.d.ts","sourceRoot":"","sources":["../../../src/codegen/entity-consolidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAI1D,OAAO,KAAK,EAAkB,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAIpE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAkKD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,kBAAkB,CAuBpB"}
@@ -0,0 +1,134 @@
1
+ import { camelCase, pascalCase } from 'change-case';
2
+ import createDebug from 'debug';
3
+ import { extractMessagesFromSpecs } from './extract/index.js';
4
+ const debug = createDebug('auto:server-generator-nestjs:entity');
5
+ function isEnumType(tsType) {
6
+ const cleanType = tsType.replace(/\s*\|\s*null\b/g, '').trim();
7
+ return /^"[^"]+"(\s*\|\s*"[^"]+")+$/.test(cleanType) || /^'[^']+'(\s*\|\s*'[^']+)+$/.test(cleanType);
8
+ }
9
+ function detectPrimaryKeyField(fields, flowName) {
10
+ const idCandidates = [`${camelCase(flowName)}Id`, 'id', `${camelCase(flowName)}ID`, 'ID'];
11
+ for (const candidate of idCandidates) {
12
+ const field = fields.find((f) => f.name === candidate);
13
+ if (field) {
14
+ return field.name;
15
+ }
16
+ }
17
+ const stringFields = fields.filter((f) => f.tsType === 'string' && f.name.toLowerCase().includes('id'));
18
+ if (stringFields.length > 0) {
19
+ return stringFields[0].name;
20
+ }
21
+ return null;
22
+ }
23
+ function shouldIndexField(fieldName, tsType) {
24
+ const indexableNames = ['status', 'type', 'category', 'state'];
25
+ const nameLower = fieldName.toLowerCase();
26
+ if (indexableNames.some((name) => nameLower.includes(name))) {
27
+ return true;
28
+ }
29
+ if (isEnumType(tsType)) {
30
+ return true;
31
+ }
32
+ return false;
33
+ }
34
+ function processFieldsFromMessages(fields, fieldMap, unionToEnumName, enumsUsed) {
35
+ for (const field of fields) {
36
+ if (field.name === 'now')
37
+ continue;
38
+ if (!fieldMap.has(field.name)) {
39
+ const isEnum = isEnumType(field.tsType);
40
+ const cleanType = field.tsType.replace(/\s*\|\s*null\b/g, '').trim();
41
+ let enumName;
42
+ if (isEnum) {
43
+ const matches = cleanType.match(/'([^']+)'/g);
44
+ const values = matches !== null ? matches.map((v) => v.slice(1, -1)) : [];
45
+ const normalized = values
46
+ .sort()
47
+ .map((v) => `'${v}'`)
48
+ .join(' | ');
49
+ enumName = unionToEnumName.get(normalized);
50
+ if (typeof enumName === 'string' && enumName.length > 0) {
51
+ enumsUsed.add(enumName);
52
+ }
53
+ }
54
+ fieldMap.set(field.name, {
55
+ name: field.name,
56
+ tsType: field.tsType,
57
+ nullable: /\|\s*null\b/.test(field.tsType),
58
+ isPrimary: false,
59
+ isEnum,
60
+ enumName,
61
+ indexed: false,
62
+ });
63
+ }
64
+ }
65
+ }
66
+ function processMessagesWithFields(messageArray, messageLabel, fieldMap, unionToEnumName, enumsUsed) {
67
+ for (const msg of messageArray) {
68
+ debug(' %s: %s with %d fields', messageLabel, msg.type, msg.fields.length);
69
+ if (msg.fields.length > 0) {
70
+ processFieldsFromMessages(msg.fields, fieldMap, unionToEnumName, enumsUsed);
71
+ }
72
+ }
73
+ }
74
+ function processCommandSlice(slice, messages, fieldMap, unionToEnumName, enumsUsed) {
75
+ debug(' Processing slice: %s (type: %s)', slice.name, slice.type);
76
+ const extracted = extractMessagesFromSpecs(slice, messages);
77
+ processMessagesWithFields(extracted.commands, 'Command', fieldMap, unionToEnumName, enumsUsed);
78
+ processMessagesWithFields(extracted.events, 'Event', fieldMap, unionToEnumName, enumsUsed);
79
+ }
80
+ function processQuerySlice(slice, messages, fieldMap, unionToEnumName, enumsUsed) {
81
+ debug(' Processing slice: %s (type: %s)', slice.name, slice.type);
82
+ const extracted = extractMessagesFromSpecs(slice, messages);
83
+ processMessagesWithFields(extracted.states, 'State', fieldMap, unionToEnumName, enumsUsed);
84
+ }
85
+ function collectFieldsFromSlices(flow, messages, fieldMap, unionToEnumName, enumsUsed) {
86
+ for (const slice of flow.slices) {
87
+ if (slice.type === 'experience')
88
+ continue;
89
+ if (slice.type === 'command') {
90
+ processCommandSlice(slice, messages, fieldMap, unionToEnumName, enumsUsed);
91
+ }
92
+ if (slice.type === 'query') {
93
+ processQuerySlice(slice, messages, fieldMap, unionToEnumName, enumsUsed);
94
+ }
95
+ }
96
+ }
97
+ function markPrimaryKeyAndIndexes(fields, fieldMap, flowName) {
98
+ const primaryKeyField = detectPrimaryKeyField(fields, flowName);
99
+ if (typeof primaryKeyField === 'string' && primaryKeyField.length > 0) {
100
+ const field = fieldMap.get(primaryKeyField);
101
+ if (field !== undefined) {
102
+ field.isPrimary = true;
103
+ debug(' Detected primary key: %s', primaryKeyField);
104
+ }
105
+ }
106
+ else {
107
+ debug(' WARNING: No primary key detected for flow: %s', flowName);
108
+ }
109
+ for (const field of fields) {
110
+ if (!field.isPrimary && shouldIndexField(field.name, field.tsType)) {
111
+ field.indexed = true;
112
+ debug(' Marking field for indexing: %s', field.name);
113
+ }
114
+ }
115
+ }
116
+ export function consolidateEntityFields(flow, messages, unionToEnumName) {
117
+ debug('Consolidating entity fields for flow: %s', flow.name);
118
+ const fieldMap = new Map();
119
+ const enumsUsed = new Set();
120
+ collectFieldsFromSlices(flow, messages, fieldMap, unionToEnumName, enumsUsed);
121
+ const fields = Array.from(fieldMap.values());
122
+ markPrimaryKeyAndIndexes(fields, fieldMap, flow.name);
123
+ const entityName = pascalCase(flow.name) + 'Entity';
124
+ const tableName = camelCase(flow.name) + 's';
125
+ debug('Consolidated entity: %s with %d fields', entityName, fields.length);
126
+ debug(' Enum imports: %o', Array.from(enumsUsed));
127
+ return {
128
+ entityName,
129
+ tableName,
130
+ fields,
131
+ enumImports: Array.from(enumsUsed),
132
+ };
133
+ }
134
+ //# sourceMappingURL=entity-consolidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-consolidation.js","sourceRoot":"","sources":["../../../src/codegen/entity-consolidation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Message, MessageDefinition } from '../types';
2
+ import type { CommandExample, EventExample } from './step-types';
3
+ export declare function extractCommandsFromGwt(gwtSpecs: Array<{
4
+ given?: Array<EventExample | unknown>;
5
+ when?: CommandExample | EventExample | unknown[];
6
+ then: Array<EventExample | unknown | {
7
+ errorType: string;
8
+ message?: string;
9
+ }>;
10
+ }>, allMessages: MessageDefinition[]): {
11
+ commands: Message[];
12
+ commandSchemasByName: Record<string, Message>;
13
+ };
14
+ export declare function extractCommandsFromThen(gwtSpecs: Array<{
15
+ given?: Array<EventExample | unknown>;
16
+ when?: CommandExample | EventExample | unknown[];
17
+ then: Array<EventExample | unknown | {
18
+ errorType: string;
19
+ message?: string;
20
+ }>;
21
+ }>, allMessages: MessageDefinition[]): {
22
+ commands: Message[];
23
+ commandSchemasByName: Record<string, Message>;
24
+ };
25
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../src/codegen/extract/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE3D,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAoBjE,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,KAAK,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC,YAAY,GAAG,OAAO,CAAC,CAAC;IACtC,IAAI,CAAC,EAAE,cAAc,GAAG,YAAY,GAAG,OAAO,EAAE,CAAC;IACjD,IAAI,EAAE,KAAK,CAAC,YAAY,GAAG,OAAO,GAAG;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/E,CAAC,EACF,WAAW,EAAE,iBAAiB,EAAE,GAC/B;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAwBxE;AAgCD,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,KAAK,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC,YAAY,GAAG,OAAO,CAAC,CAAC;IACtC,IAAI,CAAC,EAAE,cAAc,GAAG,YAAY,GAAG,OAAO,EAAE,CAAC;IACjD,IAAI,EAAE,KAAK,CAAC,YAAY,GAAG,OAAO,GAAG;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/E,CAAC,EACF,WAAW,EAAE,iBAAiB,EAAE,GAC/B;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAexE"}
@@ -0,0 +1,67 @@
1
+ import { extractFieldsFromMessage } from './fields.js';
2
+ function createCommandMessage(commandRef, allMessages, source) {
3
+ const fields = extractFieldsFromMessage(commandRef, 'command', allMessages);
4
+ if (fields.length === 0 && source === 'then') {
5
+ return undefined;
6
+ }
7
+ return {
8
+ type: commandRef,
9
+ fields,
10
+ source,
11
+ };
12
+ }
13
+ export function extractCommandsFromGwt(gwtSpecs, allMessages) {
14
+ const commandSchemasByName = {};
15
+ const commands = gwtSpecs
16
+ .map((gwt) => {
17
+ const cmd = gwt.when;
18
+ if (Array.isArray(cmd) ||
19
+ typeof cmd !== 'object' ||
20
+ cmd === null ||
21
+ !('commandRef' in cmd) ||
22
+ typeof cmd.commandRef !== 'string' ||
23
+ !cmd.commandRef)
24
+ return undefined;
25
+ const command = createCommandMessage(cmd.commandRef, allMessages, 'when');
26
+ if (command) {
27
+ commandSchemasByName[cmd.commandRef] = command;
28
+ }
29
+ return command;
30
+ })
31
+ .filter((cmd) => cmd !== undefined);
32
+ return { commands, commandSchemasByName };
33
+ }
34
+ function isValidCommandExample(commandExample) {
35
+ return (typeof commandExample === 'object' &&
36
+ commandExample !== null &&
37
+ 'commandRef' in commandExample &&
38
+ typeof commandExample.commandRef === 'string' &&
39
+ !!commandExample.commandRef);
40
+ }
41
+ function processCommandExample(commandExample, commands, commandSchemasByName, allMessages) {
42
+ if (!isValidCommandExample(commandExample)) {
43
+ return;
44
+ }
45
+ const commandRef = commandExample.commandRef;
46
+ if (!(commandRef in commandSchemasByName)) {
47
+ const command = createCommandMessage(commandRef, allMessages, 'then');
48
+ if (command) {
49
+ commands.push(command);
50
+ commandSchemasByName[commandRef] = command;
51
+ }
52
+ }
53
+ }
54
+ export function extractCommandsFromThen(gwtSpecs, allMessages) {
55
+ const commands = [];
56
+ const commandSchemasByName = {};
57
+ for (const gwt of gwtSpecs) {
58
+ if (!Array.isArray(gwt.then)) {
59
+ continue;
60
+ }
61
+ for (const commandExample of gwt.then) {
62
+ processCommandExample(commandExample, commands, commandSchemasByName, allMessages);
63
+ }
64
+ }
65
+ return { commands, commandSchemasByName };
66
+ }
67
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../../src/codegen/extract/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Slice } from '@auto-engineer/narrative';
2
+ export declare function getStreamFromSink(slice: Slice): {
3
+ streamPattern?: string;
4
+ streamId?: string;
5
+ };
6
+ //# sourceMappingURL=data-sink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-sink.d.ts","sourceRoot":"","sources":["../../../../src/codegen/extract/data-sink.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AA2EtD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAiB7F"}
@@ -0,0 +1,78 @@
1
+ import { extractGwtSpecsFromSlice } from './step-converter.js';
2
+ function resolveStreamId(stream, exampleData) {
3
+ return stream.replace(/\$\{([^}]+)\}/g, (_, key) => String(exampleData?.[key] ?? 'unknown'));
4
+ }
5
+ function extractExampleDataFromReact(firstSpec) {
6
+ if (Array.isArray(firstSpec.when)) {
7
+ const firstWhen = firstSpec.when[0];
8
+ return typeof firstWhen?.exampleData === 'object' && firstWhen.exampleData !== null ? firstWhen.exampleData : {};
9
+ }
10
+ return {};
11
+ }
12
+ function extractExampleDataFromCommand(firstSpec) {
13
+ const then = firstSpec.then;
14
+ const firstExample = then.find((t) => 'exampleData' in t);
15
+ return typeof firstExample?.exampleData === 'object' && firstExample.exampleData !== null
16
+ ? firstExample.exampleData
17
+ : {};
18
+ }
19
+ function extractExampleDataFromQuery(firstSpec) {
20
+ if (Array.isArray(firstSpec.when)) {
21
+ const firstWhen = firstSpec.when[0];
22
+ return typeof firstWhen?.exampleData === 'object' && firstWhen.exampleData !== null ? firstWhen.exampleData : {};
23
+ }
24
+ return {};
25
+ }
26
+ function extractExampleDataFromSpecs(slice, gwtSpecs) {
27
+ if (gwtSpecs.length === 0) {
28
+ return {};
29
+ }
30
+ const firstSpec = gwtSpecs[0];
31
+ switch (slice.type) {
32
+ case 'react':
33
+ return extractExampleDataFromReact(firstSpec);
34
+ case 'command':
35
+ return extractExampleDataFromCommand(firstSpec);
36
+ case 'query':
37
+ return extractExampleDataFromQuery(firstSpec);
38
+ default:
39
+ return {};
40
+ }
41
+ }
42
+ function isValidStreamSink(item) {
43
+ return (typeof item === 'object' &&
44
+ item !== null &&
45
+ 'destination' in item &&
46
+ typeof item.destination === 'object' &&
47
+ item.destination !== null &&
48
+ 'type' in item.destination &&
49
+ item.destination.type === 'stream' &&
50
+ 'pattern' in item.destination &&
51
+ typeof item.destination.pattern === 'string');
52
+ }
53
+ function processStreamSink(item, exampleData) {
54
+ if (!isValidStreamSink(item)) {
55
+ return null;
56
+ }
57
+ const streamPattern = item.destination.pattern;
58
+ const streamId = streamPattern.length > 0 ? resolveStreamId(streamPattern, exampleData) : undefined;
59
+ return { streamPattern, streamId };
60
+ }
61
+ export function getStreamFromSink(slice) {
62
+ if (!('server' in slice))
63
+ return {};
64
+ const gwtSpecs = extractGwtSpecsFromSlice(slice);
65
+ const exampleData = extractExampleDataFromSpecs(slice, gwtSpecs);
66
+ if (!('server' in slice) || slice.server == null || !('data' in slice.server) || !Array.isArray(slice.server.data)) {
67
+ return {};
68
+ }
69
+ const serverData = slice.server.data;
70
+ for (const item of serverData) {
71
+ const result = processStreamSink(item, exampleData);
72
+ if (result) {
73
+ return result;
74
+ }
75
+ }
76
+ return {};
77
+ }
78
+ //# sourceMappingURL=data-sink.js.map