@auto-engineer/frontend-generator-react-graphql 0.11.15 → 0.11.17

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 (33) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/shadcn-starter/package.json +1 -2
  3. package/dist/src/commands/generate-client.d.ts.map +1 -1
  4. package/dist/src/commands/generate-client.js +4 -1
  5. package/dist/src/commands/generate-client.js.map +1 -1
  6. package/dist/src/generator/generateComponents.d.ts +1 -1
  7. package/dist/src/generator/generateComponents.d.ts.map +1 -1
  8. package/dist/src/generator/generateComponents.js +80 -15
  9. package/dist/src/generator/generateComponents.js.map +1 -1
  10. package/dist/src/generator/templates/component.ejs +125 -3
  11. package/dist/src/generator/templates/component.ejs.specs.d.ts +2 -0
  12. package/dist/src/generator/templates/component.ejs.specs.d.ts.map +1 -0
  13. package/dist/src/generator/templates/component.ejs.specs.js +407 -0
  14. package/dist/src/generator/templates/component.ejs.specs.js.map +1 -0
  15. package/dist/src/generator/templates/component.ejs.specs.ts +448 -0
  16. package/dist/src/generator/templates/page.ejs +97 -0
  17. package/dist/src/generator/templates/page.ejs.specs.d.ts +2 -0
  18. package/dist/src/generator/templates/page.ejs.specs.d.ts.map +1 -0
  19. package/dist/src/generator/templates/page.ejs.specs.js +284 -0
  20. package/dist/src/generator/templates/page.ejs.specs.js.map +1 -0
  21. package/dist/src/generator/templates/page.ejs.specs.ts +315 -0
  22. package/dist/src/generator/type-guidance-builder.d.ts +12 -0
  23. package/dist/src/generator/type-guidance-builder.d.ts.map +1 -0
  24. package/dist/src/generator/type-guidance-builder.js +212 -0
  25. package/dist/src/generator/type-guidance-builder.js.map +1 -0
  26. package/dist/src/graphql-type-extractor.d.ts +16 -0
  27. package/dist/src/graphql-type-extractor.d.ts.map +1 -0
  28. package/dist/src/graphql-type-extractor.js +144 -0
  29. package/dist/src/graphql-type-extractor.js.map +1 -0
  30. package/dist/src/types.d.ts +1 -0
  31. package/dist/src/types.d.ts.map +1 -1
  32. package/dist/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +4 -4
@@ -0,0 +1,284 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import ejs from 'ejs';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+ const pageTemplate = fs.readFileSync(path.resolve(__dirname, 'page.ejs'), 'utf-8');
9
+ describe('page.ejs', () => {
10
+ it('should generate a basic page with organisms and no type guidance', () => {
11
+ const content = ejs.render(pageTemplate, {
12
+ name: 'Dashboard',
13
+ description: 'Main dashboard page',
14
+ organisms: ['StatsOverview', 'ActivityFeed'],
15
+ template: undefined,
16
+ specs: [],
17
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
18
+ organismSpecs: {},
19
+ });
20
+ expect(content).toContain('import { StatsOverview } from "@/components/organisms/StatsOverview";');
21
+ expect(content).toContain('import { ActivityFeed } from "@/components/organisms/ActivityFeed";');
22
+ expect(content).toContain('// Main dashboard page');
23
+ expect(content).toContain('PAGE COMPOSITION');
24
+ expect(content).toContain('export function Dashboard()');
25
+ });
26
+ it('should generate a page with organisms and specs', () => {
27
+ const content = ejs.render(pageTemplate, {
28
+ name: 'AdminPanel',
29
+ description: 'Admin control panel',
30
+ organisms: ['UserManagement', 'SystemSettings'],
31
+ template: undefined,
32
+ specs: ['manage users', 'configure system'],
33
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
34
+ organismSpecs: {},
35
+ });
36
+ expect(content).toContain('// Specs:');
37
+ expect(content).toContain('// - manage users');
38
+ expect(content).toContain('// - configure system');
39
+ expect(content).toContain('PAGE COMPOSITION');
40
+ });
41
+ it('should generate a page with spec coverage analysis', () => {
42
+ const content = ejs.render(pageTemplate, {
43
+ name: 'UserProfile',
44
+ description: 'User profile page',
45
+ organisms: ['ProfileHeader', 'ProfileDetails'],
46
+ template: undefined,
47
+ specs: ['display user info', 'show activity history'],
48
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
49
+ organismSpecs: {
50
+ ProfileHeader: ['display user info'],
51
+ ProfileDetails: ['show activity history'],
52
+ },
53
+ });
54
+ expect(content).toContain('YOUR SPECS (what this page must accomplish):');
55
+ expect(content).toContain('[✓] display user info');
56
+ expect(content).toContain('└─ Implemented by ProfileHeader');
57
+ expect(content).toContain('[✓] show activity history');
58
+ expect(content).toContain('└─ Implemented by ProfileDetails');
59
+ });
60
+ it('should generate a page with template import', () => {
61
+ const content = ejs.render(pageTemplate, {
62
+ name: 'Settings',
63
+ description: 'Settings page',
64
+ organisms: ['GeneralSettings'],
65
+ template: 'single-column-layout',
66
+ specs: [],
67
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
68
+ organismSpecs: {},
69
+ });
70
+ expect(content).toContain('import { SingleColumnLayout } from "@/components/templates/single-column-layout";');
71
+ });
72
+ it('should generate a page with type guidance', () => {
73
+ const content = ejs.render(pageTemplate, {
74
+ name: 'TodoList',
75
+ description: 'Todo list page',
76
+ organisms: ['TodoGrid'],
77
+ template: undefined,
78
+ specs: ['display todos', 'filter by status'],
79
+ typeGuidance: {
80
+ imports: ['Todo', 'TodoStatus'],
81
+ queryGuidance: [
82
+ "Query - AllTodos:\n Import: import { AllTodos } from '@/graphql/queries'\n Returns: data?.todos → Todo[]",
83
+ ],
84
+ mutationGuidance: [],
85
+ enumGuidance: [
86
+ "Enum - TodoStatus:\n Import: import { TodoStatus } from '@/gql/graphql'\n Values:\n TodoStatus.Active = 'ACTIVE'",
87
+ ],
88
+ },
89
+ organismSpecs: {},
90
+ });
91
+ expect(content).toContain('CRITICAL - TYPE GUIDANCE');
92
+ expect(content).toContain('Query - AllTodos:');
93
+ expect(content).toContain('Enum - TodoStatus:');
94
+ });
95
+ it('should generate a page with partial spec coverage', () => {
96
+ const content = ejs.render(pageTemplate, {
97
+ name: 'TaskBoard',
98
+ description: 'Task management board',
99
+ organisms: ['TaskList', 'TaskFilters'],
100
+ template: undefined,
101
+ specs: ['display tasks', 'filter by status', 'sort by date', 'search tasks'],
102
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
103
+ organismSpecs: {
104
+ TaskList: ['display tasks', 'sort by date'],
105
+ TaskFilters: ['filter by status'],
106
+ },
107
+ });
108
+ expect(content).toContain('[✓] display tasks');
109
+ expect(content).toContain('└─ Implemented by TaskList');
110
+ expect(content).toContain('[✓] filter by status');
111
+ expect(content).toContain('└─ Implemented by TaskFilters');
112
+ expect(content).toContain('[✓] sort by date');
113
+ expect(content).toContain('└─ Implemented by TaskList');
114
+ expect(content).toContain('[ ] search tasks');
115
+ expect(content).not.toContain('search tasks\n// └─');
116
+ });
117
+ it('should generate a page with NO spec coverage', () => {
118
+ const content = ejs.render(pageTemplate, {
119
+ name: 'Analytics',
120
+ description: 'Analytics dashboard',
121
+ organisms: ['ChartPanel', 'MetricsPanel'],
122
+ template: undefined,
123
+ specs: ['show revenue chart', 'display user metrics', 'export data'],
124
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
125
+ organismSpecs: {
126
+ ChartPanel: ['render line chart', 'render bar chart'],
127
+ MetricsPanel: ['show count metrics', 'show percentage metrics'],
128
+ },
129
+ });
130
+ expect(content).toContain('[ ] show revenue chart');
131
+ expect(content).toContain('[ ] display user metrics');
132
+ expect(content).toContain('[ ] export data');
133
+ expect(content).not.toContain('[✓]');
134
+ expect(content).not.toContain('└─ Implemented by');
135
+ });
136
+ it('should generate a page with mutation guidance', () => {
137
+ const content = ejs.render(pageTemplate, {
138
+ name: 'CreateItem',
139
+ description: 'Create item page',
140
+ organisms: ['ItemForm'],
141
+ template: undefined,
142
+ specs: ['collect item data', 'submit item'],
143
+ typeGuidance: {
144
+ imports: ['CreateItemInput'],
145
+ queryGuidance: [],
146
+ mutationGuidance: [
147
+ "Mutation - CreateItem:\n Import: import { CreateItem } from '@/graphql/mutations'\n Variables: CreateItemInput\n Returns: data?.createItem → Item",
148
+ ],
149
+ enumGuidance: [],
150
+ },
151
+ organismSpecs: {},
152
+ });
153
+ expect(content).toContain('CRITICAL - TYPE GUIDANCE');
154
+ expect(content).toContain('Mutation - CreateItem:');
155
+ expect(content).toContain('Child organism data requirements');
156
+ });
157
+ it('should generate a page with only mutation guidance (no queries)', () => {
158
+ const content = ejs.render(pageTemplate, {
159
+ name: 'DeleteConfirmation',
160
+ description: 'Delete confirmation page',
161
+ organisms: ['ConfirmDialog'],
162
+ template: undefined,
163
+ specs: ['confirm deletion'],
164
+ typeGuidance: {
165
+ imports: [],
166
+ queryGuidance: [],
167
+ mutationGuidance: [
168
+ "Mutation - DeleteItem:\n Import: import { DeleteItem } from '@/graphql/mutations'\n Variables: { itemId: string }",
169
+ ],
170
+ enumGuidance: [],
171
+ },
172
+ organismSpecs: {},
173
+ });
174
+ expect(content).toContain('CRITICAL - TYPE GUIDANCE');
175
+ expect(content).toContain('Mutation - DeleteItem:');
176
+ expect(content).not.toContain('Query -');
177
+ });
178
+ it('should generate a page with template and type guidance combined', () => {
179
+ const content = ejs.render(pageTemplate, {
180
+ name: 'ProductCatalog',
181
+ description: 'Product catalog page',
182
+ organisms: ['ProductGrid', 'ProductFilters'],
183
+ template: 'two-column-layout',
184
+ specs: ['display products', 'filter products'],
185
+ typeGuidance: {
186
+ imports: ['Product'],
187
+ queryGuidance: [
188
+ "Query - AllProducts:\n Import: import { AllProducts } from '@/graphql/queries'\n Returns: data?.products → Product[]",
189
+ ],
190
+ mutationGuidance: [],
191
+ enumGuidance: [],
192
+ },
193
+ organismSpecs: {
194
+ ProductGrid: ['display products'],
195
+ ProductFilters: ['filter products'],
196
+ },
197
+ });
198
+ expect(content).toContain('import { TwoColumnLayout } from "@/components/templates/two-column-layout";');
199
+ expect(content).toContain('CRITICAL - TYPE GUIDANCE');
200
+ expect(content).toContain('[✓] display products');
201
+ expect(content).toContain('[✓] filter products');
202
+ });
203
+ it('should include responsive design guidance', () => {
204
+ const content = ejs.render(pageTemplate, {
205
+ name: 'SimpleList',
206
+ description: 'Simple list page',
207
+ organisms: ['ItemList'],
208
+ template: undefined,
209
+ specs: ['show items'],
210
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
211
+ organismSpecs: {},
212
+ });
213
+ expect(content).toContain('CRITICAL - CONTAINER-AWARE RESPONSIVE DESIGN:');
214
+ expect(content).toContain('GRIDS: Always start mobile-first');
215
+ expect(content).toContain('grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3');
216
+ expect(content).toContain('TEXT SIZING: Use responsive classes');
217
+ expect(content).toContain('MENTAL TEST: Would this work in a 320px wide container?');
218
+ });
219
+ it('should handle organisms without organismSpecs data', () => {
220
+ const content = ejs.render(pageTemplate, {
221
+ name: 'MixedPage',
222
+ description: 'Page with documented and undocumented organisms',
223
+ organisms: ['DocumentedOrg', 'UndocumentedOrg'],
224
+ template: undefined,
225
+ specs: ['feature A', 'feature B'],
226
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
227
+ organismSpecs: {
228
+ DocumentedOrg: ['feature A'],
229
+ },
230
+ });
231
+ expect(content).toContain('**DocumentedOrg** capabilities:');
232
+ expect(content).toContain('• feature A');
233
+ expect(content).toContain('**UndocumentedOrg**');
234
+ expect(content).toContain('(Organism with specific purpose - compose as needed)');
235
+ });
236
+ describe('Edge Cases', () => {
237
+ it('should handle empty organisms array', () => {
238
+ const content = ejs.render(pageTemplate, {
239
+ name: 'EmptyPage',
240
+ description: 'Page without organisms',
241
+ organisms: [],
242
+ template: undefined,
243
+ specs: [],
244
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
245
+ organismSpecs: {},
246
+ });
247
+ expect(content).not.toContain('PAGE COMPOSITION');
248
+ expect(content).not.toContain('Composition Rules');
249
+ expect(content).toContain('export function EmptyPage()');
250
+ });
251
+ it('should handle undefined specs gracefully', () => {
252
+ const content = ejs.render(pageTemplate, {
253
+ name: 'NoSpecs',
254
+ description: 'Page without specs',
255
+ organisms: ['SomeOrganism'],
256
+ template: undefined,
257
+ specs: undefined,
258
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
259
+ organismSpecs: {},
260
+ });
261
+ expect(content).not.toContain('// Specs:');
262
+ expect(content).not.toContain('YOUR SPECS');
263
+ expect(content).toContain('PAGE COMPOSITION');
264
+ });
265
+ it('should handle organisms with empty organismSpecs arrays', () => {
266
+ const content = ejs.render(pageTemplate, {
267
+ name: 'EmptySpecs',
268
+ description: 'Organisms with no documented specs',
269
+ organisms: ['Org1', 'Org2'],
270
+ template: undefined,
271
+ specs: ['feature X', 'feature Y'],
272
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
273
+ organismSpecs: {
274
+ Org1: [],
275
+ Org2: [],
276
+ },
277
+ });
278
+ expect(content).toContain('[ ] feature X');
279
+ expect(content).toContain('[ ] feature Y');
280
+ expect(content).not.toContain('[✓]');
281
+ });
282
+ });
283
+ });
284
+ //# sourceMappingURL=page.ejs.specs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.ejs.specs.js","sourceRoot":"","sources":["../../../../src/generator/templates/page.ejs.specs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,315 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import ejs from 'ejs';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+
10
+ const pageTemplate = fs.readFileSync(path.resolve(__dirname, 'page.ejs'), 'utf-8');
11
+
12
+ describe('page.ejs', () => {
13
+ it('should generate a basic page with organisms and no type guidance', () => {
14
+ const content = ejs.render(pageTemplate, {
15
+ name: 'Dashboard',
16
+ description: 'Main dashboard page',
17
+ organisms: ['StatsOverview', 'ActivityFeed'],
18
+ template: undefined,
19
+ specs: [],
20
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
21
+ organismSpecs: {},
22
+ });
23
+
24
+ expect(content).toContain('import { StatsOverview } from "@/components/organisms/StatsOverview";');
25
+ expect(content).toContain('import { ActivityFeed } from "@/components/organisms/ActivityFeed";');
26
+ expect(content).toContain('// Main dashboard page');
27
+ expect(content).toContain('PAGE COMPOSITION');
28
+ expect(content).toContain('export function Dashboard()');
29
+ });
30
+
31
+ it('should generate a page with organisms and specs', () => {
32
+ const content = ejs.render(pageTemplate, {
33
+ name: 'AdminPanel',
34
+ description: 'Admin control panel',
35
+ organisms: ['UserManagement', 'SystemSettings'],
36
+ template: undefined,
37
+ specs: ['manage users', 'configure system'],
38
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
39
+ organismSpecs: {},
40
+ });
41
+
42
+ expect(content).toContain('// Specs:');
43
+ expect(content).toContain('// - manage users');
44
+ expect(content).toContain('// - configure system');
45
+ expect(content).toContain('PAGE COMPOSITION');
46
+ });
47
+
48
+ it('should generate a page with spec coverage analysis', () => {
49
+ const content = ejs.render(pageTemplate, {
50
+ name: 'UserProfile',
51
+ description: 'User profile page',
52
+ organisms: ['ProfileHeader', 'ProfileDetails'],
53
+ template: undefined,
54
+ specs: ['display user info', 'show activity history'],
55
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
56
+ organismSpecs: {
57
+ ProfileHeader: ['display user info'],
58
+ ProfileDetails: ['show activity history'],
59
+ },
60
+ });
61
+
62
+ expect(content).toContain('YOUR SPECS (what this page must accomplish):');
63
+ expect(content).toContain('[✓] display user info');
64
+ expect(content).toContain('└─ Implemented by ProfileHeader');
65
+ expect(content).toContain('[✓] show activity history');
66
+ expect(content).toContain('└─ Implemented by ProfileDetails');
67
+ });
68
+
69
+ it('should generate a page with template import', () => {
70
+ const content = ejs.render(pageTemplate, {
71
+ name: 'Settings',
72
+ description: 'Settings page',
73
+ organisms: ['GeneralSettings'],
74
+ template: 'single-column-layout',
75
+ specs: [],
76
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
77
+ organismSpecs: {},
78
+ });
79
+
80
+ expect(content).toContain('import { SingleColumnLayout } from "@/components/templates/single-column-layout";');
81
+ });
82
+
83
+ it('should generate a page with type guidance', () => {
84
+ const content = ejs.render(pageTemplate, {
85
+ name: 'TodoList',
86
+ description: 'Todo list page',
87
+ organisms: ['TodoGrid'],
88
+ template: undefined,
89
+ specs: ['display todos', 'filter by status'],
90
+ typeGuidance: {
91
+ imports: ['Todo', 'TodoStatus'],
92
+ queryGuidance: [
93
+ "Query - AllTodos:\n Import: import { AllTodos } from '@/graphql/queries'\n Returns: data?.todos → Todo[]",
94
+ ],
95
+ mutationGuidance: [],
96
+ enumGuidance: [
97
+ "Enum - TodoStatus:\n Import: import { TodoStatus } from '@/gql/graphql'\n Values:\n TodoStatus.Active = 'ACTIVE'",
98
+ ],
99
+ },
100
+ organismSpecs: {},
101
+ });
102
+
103
+ expect(content).toContain('CRITICAL - TYPE GUIDANCE');
104
+ expect(content).toContain('Query - AllTodos:');
105
+ expect(content).toContain('Enum - TodoStatus:');
106
+ });
107
+
108
+ it('should generate a page with partial spec coverage', () => {
109
+ const content = ejs.render(pageTemplate, {
110
+ name: 'TaskBoard',
111
+ description: 'Task management board',
112
+ organisms: ['TaskList', 'TaskFilters'],
113
+ template: undefined,
114
+ specs: ['display tasks', 'filter by status', 'sort by date', 'search tasks'],
115
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
116
+ organismSpecs: {
117
+ TaskList: ['display tasks', 'sort by date'],
118
+ TaskFilters: ['filter by status'],
119
+ },
120
+ });
121
+
122
+ expect(content).toContain('[✓] display tasks');
123
+ expect(content).toContain('└─ Implemented by TaskList');
124
+ expect(content).toContain('[✓] filter by status');
125
+ expect(content).toContain('└─ Implemented by TaskFilters');
126
+ expect(content).toContain('[✓] sort by date');
127
+ expect(content).toContain('└─ Implemented by TaskList');
128
+ expect(content).toContain('[ ] search tasks');
129
+ expect(content).not.toContain('search tasks\n// └─');
130
+ });
131
+
132
+ it('should generate a page with NO spec coverage', () => {
133
+ const content = ejs.render(pageTemplate, {
134
+ name: 'Analytics',
135
+ description: 'Analytics dashboard',
136
+ organisms: ['ChartPanel', 'MetricsPanel'],
137
+ template: undefined,
138
+ specs: ['show revenue chart', 'display user metrics', 'export data'],
139
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
140
+ organismSpecs: {
141
+ ChartPanel: ['render line chart', 'render bar chart'],
142
+ MetricsPanel: ['show count metrics', 'show percentage metrics'],
143
+ },
144
+ });
145
+
146
+ expect(content).toContain('[ ] show revenue chart');
147
+ expect(content).toContain('[ ] display user metrics');
148
+ expect(content).toContain('[ ] export data');
149
+ expect(content).not.toContain('[✓]');
150
+ expect(content).not.toContain('└─ Implemented by');
151
+ });
152
+
153
+ it('should generate a page with mutation guidance', () => {
154
+ const content = ejs.render(pageTemplate, {
155
+ name: 'CreateItem',
156
+ description: 'Create item page',
157
+ organisms: ['ItemForm'],
158
+ template: undefined,
159
+ specs: ['collect item data', 'submit item'],
160
+ typeGuidance: {
161
+ imports: ['CreateItemInput'],
162
+ queryGuidance: [],
163
+ mutationGuidance: [
164
+ "Mutation - CreateItem:\n Import: import { CreateItem } from '@/graphql/mutations'\n Variables: CreateItemInput\n Returns: data?.createItem → Item",
165
+ ],
166
+ enumGuidance: [],
167
+ },
168
+ organismSpecs: {},
169
+ });
170
+
171
+ expect(content).toContain('CRITICAL - TYPE GUIDANCE');
172
+ expect(content).toContain('Mutation - CreateItem:');
173
+ expect(content).toContain('Child organism data requirements');
174
+ });
175
+
176
+ it('should generate a page with only mutation guidance (no queries)', () => {
177
+ const content = ejs.render(pageTemplate, {
178
+ name: 'DeleteConfirmation',
179
+ description: 'Delete confirmation page',
180
+ organisms: ['ConfirmDialog'],
181
+ template: undefined,
182
+ specs: ['confirm deletion'],
183
+ typeGuidance: {
184
+ imports: [],
185
+ queryGuidance: [],
186
+ mutationGuidance: [
187
+ "Mutation - DeleteItem:\n Import: import { DeleteItem } from '@/graphql/mutations'\n Variables: { itemId: string }",
188
+ ],
189
+ enumGuidance: [],
190
+ },
191
+ organismSpecs: {},
192
+ });
193
+
194
+ expect(content).toContain('CRITICAL - TYPE GUIDANCE');
195
+ expect(content).toContain('Mutation - DeleteItem:');
196
+ expect(content).not.toContain('Query -');
197
+ });
198
+
199
+ it('should generate a page with template and type guidance combined', () => {
200
+ const content = ejs.render(pageTemplate, {
201
+ name: 'ProductCatalog',
202
+ description: 'Product catalog page',
203
+ organisms: ['ProductGrid', 'ProductFilters'],
204
+ template: 'two-column-layout',
205
+ specs: ['display products', 'filter products'],
206
+ typeGuidance: {
207
+ imports: ['Product'],
208
+ queryGuidance: [
209
+ "Query - AllProducts:\n Import: import { AllProducts } from '@/graphql/queries'\n Returns: data?.products → Product[]",
210
+ ],
211
+ mutationGuidance: [],
212
+ enumGuidance: [],
213
+ },
214
+ organismSpecs: {
215
+ ProductGrid: ['display products'],
216
+ ProductFilters: ['filter products'],
217
+ },
218
+ });
219
+
220
+ expect(content).toContain('import { TwoColumnLayout } from "@/components/templates/two-column-layout";');
221
+ expect(content).toContain('CRITICAL - TYPE GUIDANCE');
222
+ expect(content).toContain('[✓] display products');
223
+ expect(content).toContain('[✓] filter products');
224
+ });
225
+
226
+ it('should include responsive design guidance', () => {
227
+ const content = ejs.render(pageTemplate, {
228
+ name: 'SimpleList',
229
+ description: 'Simple list page',
230
+ organisms: ['ItemList'],
231
+ template: undefined,
232
+ specs: ['show items'],
233
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
234
+ organismSpecs: {},
235
+ });
236
+
237
+ expect(content).toContain('CRITICAL - CONTAINER-AWARE RESPONSIVE DESIGN:');
238
+ expect(content).toContain('GRIDS: Always start mobile-first');
239
+ expect(content).toContain('grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3');
240
+ expect(content).toContain('TEXT SIZING: Use responsive classes');
241
+ expect(content).toContain('MENTAL TEST: Would this work in a 320px wide container?');
242
+ });
243
+
244
+ it('should handle organisms without organismSpecs data', () => {
245
+ const content = ejs.render(pageTemplate, {
246
+ name: 'MixedPage',
247
+ description: 'Page with documented and undocumented organisms',
248
+ organisms: ['DocumentedOrg', 'UndocumentedOrg'],
249
+ template: undefined,
250
+ specs: ['feature A', 'feature B'],
251
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
252
+ organismSpecs: {
253
+ DocumentedOrg: ['feature A'],
254
+ },
255
+ });
256
+
257
+ expect(content).toContain('**DocumentedOrg** capabilities:');
258
+ expect(content).toContain('• feature A');
259
+ expect(content).toContain('**UndocumentedOrg**');
260
+ expect(content).toContain('(Organism with specific purpose - compose as needed)');
261
+ });
262
+
263
+ describe('Edge Cases', () => {
264
+ it('should handle empty organisms array', () => {
265
+ const content = ejs.render(pageTemplate, {
266
+ name: 'EmptyPage',
267
+ description: 'Page without organisms',
268
+ organisms: [],
269
+ template: undefined,
270
+ specs: [],
271
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
272
+ organismSpecs: {},
273
+ });
274
+
275
+ expect(content).not.toContain('PAGE COMPOSITION');
276
+ expect(content).not.toContain('Composition Rules');
277
+ expect(content).toContain('export function EmptyPage()');
278
+ });
279
+
280
+ it('should handle undefined specs gracefully', () => {
281
+ const content = ejs.render(pageTemplate, {
282
+ name: 'NoSpecs',
283
+ description: 'Page without specs',
284
+ organisms: ['SomeOrganism'],
285
+ template: undefined,
286
+ specs: undefined,
287
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
288
+ organismSpecs: {},
289
+ });
290
+
291
+ expect(content).not.toContain('// Specs:');
292
+ expect(content).not.toContain('YOUR SPECS');
293
+ expect(content).toContain('PAGE COMPOSITION');
294
+ });
295
+
296
+ it('should handle organisms with empty organismSpecs arrays', () => {
297
+ const content = ejs.render(pageTemplate, {
298
+ name: 'EmptySpecs',
299
+ description: 'Organisms with no documented specs',
300
+ organisms: ['Org1', 'Org2'],
301
+ template: undefined,
302
+ specs: ['feature X', 'feature Y'],
303
+ typeGuidance: { imports: [], queryGuidance: [], mutationGuidance: [], enumGuidance: [] },
304
+ organismSpecs: {
305
+ Org1: [],
306
+ Org2: [],
307
+ },
308
+ });
309
+
310
+ expect(content).toContain('[ ] feature X');
311
+ expect(content).toContain('[ ] feature Y');
312
+ expect(content).not.toContain('[✓]');
313
+ });
314
+ });
315
+ });
@@ -0,0 +1,12 @@
1
+ import { MoleculeSpec, OrganismSpec, PageSpec, IAScheme } from '../types';
2
+ import { TypeMapping } from '../graphql-type-extractor';
3
+ export interface TypeGuidance {
4
+ imports: string[];
5
+ queryGuidance: string[];
6
+ mutationGuidance: string[];
7
+ enumGuidance: string[];
8
+ typeFieldGuidance: string[];
9
+ }
10
+ export declare function buildTypeGuidance(componentName: string, spec: MoleculeSpec | OrganismSpec | PageSpec, typeMappings: TypeMapping): TypeGuidance;
11
+ export declare function aggregateOrganismGuidance(pageName: string, pageSpec: PageSpec, iaScheme: IAScheme, typeMappings: TypeMapping): TypeGuidance;
12
+ //# sourceMappingURL=type-guidance-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-guidance-builder.d.ts","sourceRoot":"","sources":["../../../src/generator/type-guidance-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAmB,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC3F,OAAO,EACL,WAAW,EAIZ,MAAM,2BAA2B,CAAC;AAKnC,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,YAAY,GAAG,YAAY,GAAG,QAAQ,EAC5C,YAAY,EAAE,WAAW,GACxB,YAAY,CAuCd;AAkOD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,WAAW,GACxB,YAAY,CAqDd"}