@komaci/esm-generator 260.31.0 → 262.9.0

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.
@@ -376,6 +376,26 @@ export default class Component extends LightningElement {
376
376
  expect(metadata.files.length).toBeGreaterThan(0);
377
377
  const tsFile = metadata.files.find((f) => f.fileName === 'component.ts');
378
378
  expect(tsFile).toBeDefined();
379
+ expect(tsFile?.komaciDoc).toBeDefined();
380
+ // Now verify the full ADG generation path works with TypeScript bundle
381
+ const srcFileMap = bundleFiles.reduce((map, { fileName, source }) => ({ ...map, [fileName]: source }), {});
382
+ const inputFiles = Object.fromEntries(metadata.files
383
+ .map(({ fileName, komaciDoc }) => [fileName, komaciDoc])
384
+ .filter(([, komaciDoc]) => !!komaciDoc));
385
+ const generatorInput = {
386
+ moduleInfo: {
387
+ name: bundleConfig.name,
388
+ namespace: bundleConfig.namespace,
389
+ type: 'bundle',
390
+ files: inputFiles,
391
+ },
392
+ srcFileMap,
393
+ };
394
+ // This exercises the full code path including the fix at line ~134
395
+ const result = (0, index_1.generateKomaciModule)(generatorInput);
396
+ // The result should be valid JavaScript and not an error
397
+ expect(result).not.toContain('ErrorFunction');
398
+ expect(result).not.toContain('unsupported file extension');
379
399
  }).not.toThrow();
380
400
  });
381
401
  // Test that verifies the file extension is properly detected
@@ -568,26 +568,16 @@ describe('adgToExpression', () => {
568
568
  });
569
569
  describe('produceErrorAdgFunction', () => {
570
570
  it('should produce a resolvable module with an adg with only one node that shows what the error was', () => {
571
- const expected = `import registerAdgFunction from "komaci/registerAdgFunction";
572
-
573
- function adg0(fct, ctx) {
574
- const {
575
- adg
576
- } = fct;
577
- return adg(undefined, {}, [{
578
- t: "ErrorFunction",
579
- c: {
580
- "error": "something bad happened"
581
- }
582
- }], (fct, ctx) => {
583
- return [];
584
- }, []);
585
- }
586
-
587
- export default registerAdgFunction(adg0);`;
588
571
  const testError = new Error('something bad happened');
589
572
  const res = (0, functionAstGeneration_1.produceErrorAdgFunction)((0, common_shared_1.initModuleMetadataObject)(), testError);
590
- expect((0, generator_1.default)((0, types_1.file)(res)).code).toBe(expected);
573
+ const generatedCode = (0, generator_1.default)((0, types_1.file)(res)).code;
574
+ // Verify the essential parts are present
575
+ expect(generatedCode).toContain('import registerAdgFunction from "komaci/registerAdgFunction"');
576
+ expect(generatedCode).toContain('function adg0(fct, ctx)');
577
+ expect(generatedCode).toContain('t: "ErrorFunction"');
578
+ expect(generatedCode).toContain('something bad happened');
579
+ expect(generatedCode).toContain('Extra Debug Info');
580
+ expect(generatedCode).toContain('export default registerAdgFunction(adg0)');
591
581
  });
592
582
  });
593
583
  describe('composeStaticMetadataAssignmentExpression', () => {
@@ -41,24 +41,12 @@ describe('Handling errors that throw inside a call to generateKomaciModule', ()
41
41
  },
42
42
  };
43
43
  const res = (0, __1.generateKomaciModule)(input);
44
- const expectedModuleFirstHalf = 'import registerAdgFunction from "komaci/registerAdgFunction";\n\n' +
45
- 'function adg0(fct, ctx) {\n' +
46
- ' const {\n' +
47
- ' adg\n' +
48
- ' } = fct;\n' +
49
- ' return adg(undefined, {}, [{\n' +
50
- ' t: "ErrorFunction",\n' +
51
- ' c: {\n' +
52
- ' "error": "[komaci esm-generator] unrecognized input type"\n';
53
- const expectedModuleSecondHalf = ' return [];\n' +
54
- ' }, []);\n' +
55
- '}\n' +
56
- '\nexport default registerAdgFunction(adg0);';
57
- const lines = res.split('\n');
58
- const skipStack = lines.slice(0, 10).join('\n') + '\n';
59
- const skipStackEnd = lines.slice(lines.length - 5).join('\n');
60
- expect(skipStack).toBe(expectedModuleFirstHalf);
61
- expect(skipStackEnd).toBe(expectedModuleSecondHalf);
44
+ // Verify it contains ErrorFunction
45
+ expect(res).toContain('t: "ErrorFunction"');
46
+ expect(res).toContain('[komaci esm-generator] unrecognized input type');
47
+ expect(res).toContain('Extra Debug Info');
48
+ expect(res).toContain('Source Files:');
49
+ expect(res).toContain('registerAdgFunction(adg0)');
62
50
  });
63
51
  it('should return error adg when something not an error is thrown', () => {
64
52
  const input = {
@@ -79,24 +67,12 @@ describe('Handling errors that throw inside a call to generateKomaciModule', ()
79
67
  throw 'not an error';
80
68
  });
81
69
  const res = (0, __1.generateKomaciModule)(input);
82
- const expectedModuleFirstHalf = 'import registerAdgFunction from "komaci/registerAdgFunction";\n\n' +
83
- 'function adg0(fct, ctx) {\n' +
84
- ' const {\n' +
85
- ' adg\n' +
86
- ' } = fct;\n' +
87
- ' return adg(undefined, {}, [{\n' +
88
- ' t: "ErrorFunction",\n' +
89
- ' c: {\n' +
90
- ' "error": "[komaci] Something that is not an error was thrown"\n';
91
- const expectedModuleSecondHalf = ' return [];\n' +
92
- ' }, []);\n' +
93
- '}\n' +
94
- '\nexport default registerAdgFunction(adg0);';
95
- const lines = res.split('\n');
96
- const skipStack = lines.slice(0, 10).join('\n') + '\n';
97
- const skipStackEnd = lines.slice(lines.length - 5).join('\n');
98
- expect(skipStack).toBe(expectedModuleFirstHalf);
99
- expect(skipStackEnd).toBe(expectedModuleSecondHalf);
70
+ // Verify it contains ErrorFunction with debug info
71
+ expect(res).toContain('t: "ErrorFunction"');
72
+ expect(res).toContain('[komaci] Something that is not an error was thrown');
73
+ expect(res).toContain('Extra Debug Info');
74
+ expect(res).toContain('Files in bundle:');
75
+ expect(res).toContain('registerAdgFunction(adg0)');
100
76
  });
101
77
  it('should return error adg when undefined is thrown', () => {
102
78
  const input = {
@@ -117,24 +93,12 @@ describe('Handling errors that throw inside a call to generateKomaciModule', ()
117
93
  throw undefined;
118
94
  });
119
95
  const res = (0, __1.generateKomaciModule)(input);
120
- const expectedModuleFirstHalf = 'import registerAdgFunction from "komaci/registerAdgFunction";\n\n' +
121
- 'function adg0(fct, ctx) {\n' +
122
- ' const {\n' +
123
- ' adg\n' +
124
- ' } = fct;\n' +
125
- ' return adg(undefined, {}, [{\n' +
126
- ' t: "ErrorFunction",\n' +
127
- ' c: {\n' +
128
- ' "error": "[komaci] Something that is not an error was thrown"\n';
129
- const expectedModuleSecondHalf = ' return [];\n' +
130
- ' }, []);\n' +
131
- '}\n' +
132
- '\nexport default registerAdgFunction(adg0);';
133
- const lines = res.split('\n');
134
- const skipStack = lines.slice(0, 10).join('\n') + '\n';
135
- const skipStackEnd = lines.slice(lines.length - 5).join('\n');
136
- expect(skipStack).toBe(expectedModuleFirstHalf);
137
- expect(skipStackEnd).toBe(expectedModuleSecondHalf);
96
+ // Verify it contains ErrorFunction
97
+ expect(res).toContain('t: "ErrorFunction"');
98
+ expect(res).toContain('[komaci] Something that is not an error was thrown');
99
+ expect(res).toContain('Extra Debug Info');
100
+ expect(res).toContain('Files in bundle:');
101
+ expect(res).toContain('registerAdgFunction(adg0)');
138
102
  });
139
103
  });
140
104
  describe('normalizeSrcFileKeys', () => {
@@ -290,4 +254,212 @@ describe('normalizeSrcFileKeys', () => {
290
254
  expect(input.srcFileMap['templates/test2.html']).not.toBeUndefined();
291
255
  });
292
256
  });
257
+ describe('TypeScript Bundle Processing', () => {
258
+ it('should process bundles containing TypeScript files', () => {
259
+ // Create a proper KomaciDocument structure for TypeScript file
260
+ const komaciDoc = {
261
+ adgs: [{}],
262
+ exports: {
263
+ default: {
264
+ type: 'AdgReference',
265
+ value: 0,
266
+ },
267
+ },
268
+ };
269
+ const input = {
270
+ moduleInfo: {
271
+ name: 'tsComponent',
272
+ namespace: 'c',
273
+ type: 'bundle',
274
+ files: {
275
+ 'tsComponent.ts': komaciDoc,
276
+ 'tsComponent.html': {},
277
+ },
278
+ },
279
+ srcFileMap: {
280
+ 'tsComponent.ts': `
281
+ import { LightningElement, api } from 'lwc';
282
+
283
+ export default class TsComponent extends LightningElement {
284
+ @api recordId: string;
285
+
286
+ get displayName(): string {
287
+ return 'TypeScript Component';
288
+ }
289
+ }`,
290
+ 'tsComponent.html': '<template><div>{displayName}</div></template>',
291
+ },
292
+ };
293
+ // This should NOT throw an error
294
+ expect(() => {
295
+ const result = (0, __1.generateKomaciModule)(input);
296
+ expect(result).toContain('registerAdgFunction');
297
+ expect(result).not.toContain('ErrorFunction');
298
+ }).not.toThrow();
299
+ });
300
+ it('should handle bundle with only TypeScript file (no HTML)', () => {
301
+ const komaciDoc = {
302
+ adgs: [{}],
303
+ exports: {
304
+ default: {
305
+ type: 'AdgReference',
306
+ value: 0,
307
+ },
308
+ },
309
+ };
310
+ const input = {
311
+ moduleInfo: {
312
+ name: 'tsOnly',
313
+ namespace: 'c',
314
+ type: 'bundle',
315
+ files: {
316
+ 'tsOnly.ts': komaciDoc,
317
+ },
318
+ },
319
+ srcFileMap: {
320
+ 'tsOnly.ts': `
321
+ import { LightningElement } from 'lwc';
322
+
323
+ export default class TsOnly extends LightningElement {
324
+ message: string = 'Hello TypeScript';
325
+ }`,
326
+ },
327
+ };
328
+ expect(() => {
329
+ const result = (0, __1.generateKomaciModule)(input);
330
+ expect(result).toContain('registerAdgFunction');
331
+ }).not.toThrow();
332
+ });
333
+ it('should handle TypeScript with complex type annotations', () => {
334
+ const komaciDoc = {
335
+ adgs: [{}],
336
+ exports: {
337
+ default: {
338
+ type: 'AdgReference',
339
+ value: 0,
340
+ },
341
+ },
342
+ };
343
+ const input = {
344
+ moduleInfo: {
345
+ name: 'complexTs',
346
+ namespace: 'c',
347
+ type: 'bundle',
348
+ files: {
349
+ 'complexTs.ts': komaciDoc,
350
+ },
351
+ },
352
+ srcFileMap: {
353
+ 'complexTs.ts': `
354
+ import { LightningElement, api } from 'lwc';
355
+
356
+ interface User {
357
+ id: string;
358
+ name: string;
359
+ }
360
+
361
+ export default class ComplexTs extends LightningElement {
362
+ @api recordId: string;
363
+ private users: User[] = [];
364
+
365
+ get userCount(): number {
366
+ return this.users.length;
367
+ }
368
+ }`,
369
+ },
370
+ };
371
+ expect(() => {
372
+ const result = (0, __1.generateKomaciModule)(input);
373
+ expect(result).toContain('registerAdgFunction');
374
+ }).not.toThrow();
375
+ });
376
+ it('should handle mixed bundle with both .js and .ts files', () => {
377
+ const jsDoc = {
378
+ adgs: [{}],
379
+ exports: {
380
+ default: {
381
+ type: 'AdgReference',
382
+ value: 0,
383
+ },
384
+ },
385
+ };
386
+ const tsDoc = {
387
+ adgs: [{}],
388
+ exports: {
389
+ helper: {
390
+ type: 'AdgReference',
391
+ value: 0,
392
+ },
393
+ },
394
+ };
395
+ const input = {
396
+ moduleInfo: {
397
+ name: 'mixedComponent',
398
+ namespace: 'c',
399
+ type: 'bundle',
400
+ files: {
401
+ 'mixedComponent.js': jsDoc,
402
+ 'helper.ts': tsDoc,
403
+ 'mixedComponent.html': {},
404
+ },
405
+ },
406
+ srcFileMap: {
407
+ 'mixedComponent.js': `
408
+ import { LightningElement } from 'lwc';
409
+ export default class MixedComponent extends LightningElement {}`,
410
+ 'helper.ts': `
411
+ export function helperFunction(data: string): string {
412
+ return data.toUpperCase();
413
+ }`,
414
+ 'mixedComponent.html': '<template><div>Mixed</div></template>',
415
+ },
416
+ };
417
+ expect(() => {
418
+ const result = (0, __1.generateKomaciModule)(input);
419
+ expect(result).toContain('registerAdgFunction');
420
+ }).not.toThrow();
421
+ });
422
+ it('should throw error with unsupported file extension in bundle', () => {
423
+ const input = {
424
+ moduleInfo: {
425
+ name: 'badComponent',
426
+ namespace: 'c',
427
+ type: 'bundle',
428
+ files: {
429
+ 'badComponent.xyz': {},
430
+ },
431
+ },
432
+ srcFileMap: {
433
+ 'badComponent.xyz': 'some content',
434
+ },
435
+ };
436
+ const result = (0, __1.generateKomaciModule)(input);
437
+ // Should generate an error ADG
438
+ expect(result).toContain('ErrorFunction');
439
+ expect(result).toContain('unsupported file extension: xyz');
440
+ });
441
+ it('should normalize TypeScript file paths in bundles', () => {
442
+ const bundleSrcFileMap = {
443
+ 'c/tsComponent/tsComponent.ts': {},
444
+ 'c/tsComponent/tsComponent.html': {},
445
+ };
446
+ const input = {
447
+ moduleInfo: {
448
+ name: 'tsComponent',
449
+ namespace: 'c',
450
+ type: 'bundle',
451
+ files: bundleSrcFileMap,
452
+ },
453
+ srcFileMap: {
454
+ 'c/tsComponent/tsComponent.ts': 'export default class TsComponent {}',
455
+ 'c/tsComponent/tsComponent.html': '<template><div>TS</div></template>',
456
+ },
457
+ };
458
+ (0, __1.normalizeSrcFileKeys)(input);
459
+ expect(input.moduleInfo.files['tsComponent.ts']).not.toBeUndefined();
460
+ expect(input.moduleInfo.files['tsComponent.html']).not.toBeUndefined();
461
+ expect(input.srcFileMap['tsComponent.ts']).not.toBeUndefined();
462
+ expect(input.srcFileMap['tsComponent.html']).not.toBeUndefined();
463
+ });
464
+ });
293
465
  //# sourceMappingURL=index.spec.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=produceErrorAdgFunction-debug.spec.d.ts.map
@@ -0,0 +1,387 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const functionAstGeneration_1 = require("../functionAstGeneration");
7
+ const common_shared_1 = require("@komaci/common-shared");
8
+ const generator_1 = __importDefault(require("@babel/generator"));
9
+ const types_1 = require("@babel/types");
10
+ describe('produceErrorAdgFunction with debug information', () => {
11
+ describe('with bundle module input', () => {
12
+ it('should include module name, namespace, and file information in error message', () => {
13
+ const komaciJsDoc = {
14
+ adgs: [
15
+ {
16
+ properties: {
17
+ recordId: { isPublic: true },
18
+ record: { isPublic: false },
19
+ },
20
+ functions: [],
21
+ },
22
+ ],
23
+ imports: [
24
+ { resourceName: 'lwc', names: ['LightningElement'] },
25
+ { resourceName: 'lightning/uiRecordApi', names: ['getRecord'] },
26
+ ],
27
+ exports: {
28
+ default: { type: 'AdgReference', value: 0 },
29
+ },
30
+ };
31
+ const komaciHtmlDoc = {
32
+ compositions: [
33
+ { type: 'Container' },
34
+ { type: 'Slot', name: 'default' },
35
+ ],
36
+ };
37
+ const input = {
38
+ moduleInfo: {
39
+ name: 'myTestComponent',
40
+ namespace: 'c',
41
+ type: 'bundle',
42
+ files: {
43
+ 'myTestComponent.js': komaciJsDoc,
44
+ 'myTestComponent.html': komaciHtmlDoc,
45
+ },
46
+ },
47
+ srcFileMap: {
48
+ 'myTestComponent.js': 'export default class MyTestComponent extends LightningElement {\n @api recordId;\n}',
49
+ 'myTestComponent.html': '<template>\n <div>Test</div>\n</template>',
50
+ 'myTestComponent.css': '.test { color: red; }',
51
+ },
52
+ };
53
+ const testError = new Error('Unexpected token (34:14)');
54
+ testError.stack =
55
+ 'Error: Unexpected token (34:14)\n at Parser._raise (/path/parser.js:762:17)\n at generateAstFromSrcCode (/path/parser.ts:11:23)';
56
+ const result = (0, functionAstGeneration_1.produceErrorAdgFunction)((0, common_shared_1.initModuleMetadataObject)(), testError, input);
57
+ const generatedCode = (0, generator_1.default)((0, types_1.file)(result)).code;
58
+ // Verify error message is present
59
+ expect(generatedCode).toContain('Unexpected token (34:14)');
60
+ // Verify stack trace is present
61
+ expect(generatedCode).toContain('Parser._raise');
62
+ expect(generatedCode).toContain('generateAstFromSrcCode');
63
+ // Verify debug info section exists
64
+ expect(generatedCode).toContain('Extra Debug Info:');
65
+ // Verify file list
66
+ expect(generatedCode).toContain('Files in bundle:');
67
+ expect(generatedCode).toContain('myTestComponent.js');
68
+ expect(generatedCode).toContain('myTestComponent.html');
69
+ // Verify KomaciDoc structure info for JS file
70
+ expect(generatedCode).toContain('File: myTestComponent.js');
71
+ expect(generatedCode).toContain('Has adgs: yes (1)');
72
+ expect(generatedCode).toContain('Has imports: yes (2)');
73
+ expect(generatedCode).toContain('Has exports: yes');
74
+ // Verify KomaciDoc structure info for HTML file
75
+ expect(generatedCode).toContain('File: myTestComponent.html');
76
+ expect(generatedCode).toContain('Has compositions: yes (2)');
77
+ // Verify source file information
78
+ expect(generatedCode).toContain('Source Files:');
79
+ expect(generatedCode).toContain('myTestComponent.js:');
80
+ expect(generatedCode).toContain('chars');
81
+ expect(generatedCode).toContain('lines');
82
+ });
83
+ it('should handle bundle with no KomaciDoc gracefully', () => {
84
+ const input = {
85
+ moduleInfo: {
86
+ name: 'emptyComponent',
87
+ namespace: 'lightning',
88
+ type: 'bundle',
89
+ files: {
90
+ 'emptyComponent.js': {},
91
+ },
92
+ },
93
+ srcFileMap: {
94
+ 'emptyComponent.js': '',
95
+ },
96
+ };
97
+ const testError = new Error('No adgs found');
98
+ const result = (0, functionAstGeneration_1.produceErrorAdgFunction)((0, common_shared_1.initModuleMetadataObject)(), testError, input);
99
+ const generatedCode = (0, generator_1.default)((0, types_1.file)(result)).code;
100
+ expect(generatedCode).toContain('emptyComponent.js');
101
+ expect(generatedCode).toContain('Has adgs: no');
102
+ expect(generatedCode).toContain('Has imports: no');
103
+ expect(generatedCode).toContain('Has exports: no');
104
+ });
105
+ it('should include all source files with correct statistics', () => {
106
+ const input = {
107
+ moduleInfo: {
108
+ name: 'multiFileComponent',
109
+ namespace: 'c',
110
+ type: 'bundle',
111
+ files: {
112
+ 'multiFileComponent.js': {
113
+ adgs: [{}],
114
+ exports: { default: { type: 'AdgReference', value: 0 } },
115
+ },
116
+ },
117
+ },
118
+ srcFileMap: {
119
+ 'multiFileComponent.js': 'line1\nline2\nline3\nline4\nline5',
120
+ 'multiFileComponent.html': '<template>\n <div></div>\n</template>',
121
+ 'multiFileComponent.css': '.class { }',
122
+ 'helper.js': 'export const helper = () => {\n return true;\n}', // 3 lines
123
+ },
124
+ };
125
+ const testError = new Error('Test error');
126
+ const result = (0, functionAstGeneration_1.produceErrorAdgFunction)((0, common_shared_1.initModuleMetadataObject)(), testError, input);
127
+ const generatedCode = (0, generator_1.default)((0, types_1.file)(result)).code;
128
+ // Verify all files are listed
129
+ expect(generatedCode).toContain('multiFileComponent.js:');
130
+ expect(generatedCode).toContain('multiFileComponent.html:');
131
+ expect(generatedCode).toContain('multiFileComponent.css:');
132
+ expect(generatedCode).toContain('helper.js:');
133
+ // Verify line counts
134
+ expect(generatedCode).toContain('5 lines');
135
+ expect(generatedCode).toContain('3 lines');
136
+ expect(generatedCode).toContain('1 lines');
137
+ });
138
+ });
139
+ describe('with file module input', () => {
140
+ it('should include file-specific information for single file modules', () => {
141
+ const komaciDoc = {
142
+ adgs: [
143
+ {
144
+ properties: {
145
+ value: { isPublic: true },
146
+ },
147
+ },
148
+ ],
149
+ imports: [{ resourceName: 'lwc', names: ['api'] }],
150
+ exports: {
151
+ default: { type: 'AdgReference', value: 0 },
152
+ },
153
+ };
154
+ const input = {
155
+ moduleInfo: {
156
+ name: 'singleFile',
157
+ namespace: 'c',
158
+ type: 'file',
159
+ fileName: 'singleFile.js',
160
+ komaciDoc,
161
+ },
162
+ srcFileMap: {
163
+ 'singleFile.js': 'export default class SingleFile {\n @api value;\n}',
164
+ },
165
+ };
166
+ const testError = new Error('Parse error at line 42');
167
+ testError.stack =
168
+ 'Error: Parse error at line 42\n at parse (/path/to/parser.js:100:5)';
169
+ const result = (0, functionAstGeneration_1.produceErrorAdgFunction)((0, common_shared_1.initModuleMetadataObject)(), testError, input);
170
+ const generatedCode = (0, generator_1.default)((0, types_1.file)(result)).code;
171
+ // Verify error details
172
+ expect(generatedCode).toContain('Parse error at line 42');
173
+ expect(generatedCode).toContain('at parse');
174
+ // Verify debug info and file info
175
+ expect(generatedCode).toContain('Extra Debug Info:');
176
+ expect(generatedCode).toContain('File: singleFile.js');
177
+ // Verify KomaciDoc structure
178
+ expect(generatedCode).toContain('Has adgs: yes (1)');
179
+ expect(generatedCode).toContain('Has imports: yes (1)');
180
+ expect(generatedCode).toContain('Has exports: yes');
181
+ // Verify source info
182
+ expect(generatedCode).toContain('Source Files:');
183
+ expect(generatedCode).toContain('singleFile.js:');
184
+ });
185
+ it('should handle file module with empty KomaciDoc', () => {
186
+ const input = {
187
+ moduleInfo: {
188
+ name: 'emptyFile',
189
+ namespace: 'c',
190
+ type: 'file',
191
+ fileName: 'emptyFile.html',
192
+ komaciDoc: {},
193
+ },
194
+ };
195
+ const testError = new Error('Empty document');
196
+ const result = (0, functionAstGeneration_1.produceErrorAdgFunction)((0, common_shared_1.initModuleMetadataObject)(), testError, input);
197
+ const generatedCode = (0, generator_1.default)((0, types_1.file)(result)).code;
198
+ expect(generatedCode).toContain('emptyFile.html');
199
+ expect(generatedCode).toContain('Has adgs: no');
200
+ expect(generatedCode).toContain('Has imports: no');
201
+ expect(generatedCode).toContain('Has exports: no');
202
+ });
203
+ });
204
+ describe('edge cases', () => {
205
+ it('should work without GeneratorInput (backward compatibility)', () => {
206
+ const testError = new Error('Simple error');
207
+ testError.stack = 'Error: Simple error\n at test.js:1:1';
208
+ const result = (0, functionAstGeneration_1.produceErrorAdgFunction)((0, common_shared_1.initModuleMetadataObject)(), testError, undefined);
209
+ const generatedCode = (0, generator_1.default)((0, types_1.file)(result)).code;
210
+ // Should still have error and stack
211
+ expect(generatedCode).toContain('Simple error');
212
+ expect(generatedCode).toContain('test.js:1:1');
213
+ // But no debug info
214
+ expect(generatedCode).not.toContain('Files in bundle');
215
+ expect(generatedCode).not.toContain('Source Files');
216
+ });
217
+ it('should handle error without stack trace', () => {
218
+ const testError = new Error('Error with no stack');
219
+ testError.stack = undefined;
220
+ const input = {
221
+ moduleInfo: {
222
+ name: 'test',
223
+ namespace: 'c',
224
+ type: 'file',
225
+ fileName: 'test.js',
226
+ komaciDoc: {},
227
+ },
228
+ };
229
+ const result = (0, functionAstGeneration_1.produceErrorAdgFunction)((0, common_shared_1.initModuleMetadataObject)(), testError, input);
230
+ const generatedCode = (0, generator_1.default)((0, types_1.file)(result)).code;
231
+ expect(generatedCode).toContain('Error with no stack');
232
+ expect(generatedCode).toContain('Extra Debug Info:');
233
+ expect(generatedCode).toContain('File: test.js');
234
+ // Stack should be undefined, not the string "stack"
235
+ expect(generatedCode).toContain('"stack": undefined');
236
+ });
237
+ it('should handle srcFileMap with empty files', () => {
238
+ const input = {
239
+ moduleInfo: {
240
+ name: 'emptySource',
241
+ namespace: 'c',
242
+ type: 'bundle',
243
+ files: {
244
+ 'emptySource.js': {},
245
+ },
246
+ },
247
+ srcFileMap: {
248
+ 'emptySource.js': '',
249
+ 'emptySource.html': '', // Empty source
250
+ },
251
+ };
252
+ const testError = new Error('Empty files');
253
+ const result = (0, functionAstGeneration_1.produceErrorAdgFunction)((0, common_shared_1.initModuleMetadataObject)(), testError, input);
254
+ const generatedCode = (0, generator_1.default)((0, types_1.file)(result)).code;
255
+ expect(generatedCode).toContain('emptySource.js: 0 chars, 1 lines');
256
+ expect(generatedCode).toContain('emptySource.html: 0 chars, 1 lines');
257
+ });
258
+ it('should handle module with many imports and functions', () => {
259
+ const complexKomaciDoc = {
260
+ adgs: [
261
+ {
262
+ properties: {
263
+ prop1: { isPublic: true },
264
+ prop2: { isPublic: true },
265
+ prop3: { isPublic: false },
266
+ },
267
+ functions: [
268
+ {
269
+ type: 'WireFunction',
270
+ reference: {
271
+ type: 'ImportReference',
272
+ value: '0/names/0',
273
+ },
274
+ },
275
+ {
276
+ type: 'WireFunction',
277
+ reference: {
278
+ type: 'ImportReference',
279
+ value: '1/names/0',
280
+ },
281
+ },
282
+ {
283
+ type: 'WireFunction',
284
+ reference: {
285
+ type: 'ImportReference',
286
+ value: '2/names/0',
287
+ },
288
+ },
289
+ ],
290
+ },
291
+ ],
292
+ imports: [
293
+ { resourceName: 'lightning/uiRecordApi', names: ['getRecord'] },
294
+ { resourceName: 'lightning/uiRecordApi', names: ['getRecordUi'] },
295
+ {
296
+ resourceName: '@salesforce/apex/MyController.getData',
297
+ names: ['default'],
298
+ },
299
+ { resourceName: '@salesforce/user/Id', names: ['default'] },
300
+ { resourceName: 'c/childComponent', names: ['default'] },
301
+ ],
302
+ compositions: [
303
+ { type: 'Container' },
304
+ { type: 'Slot', name: 'default' },
305
+ {
306
+ type: 'ComposedAdg',
307
+ input: { type: 'ImportReference', value: '4/names/0' },
308
+ },
309
+ ],
310
+ exports: {
311
+ default: { type: 'AdgReference', value: 0 },
312
+ },
313
+ };
314
+ const input = {
315
+ moduleInfo: {
316
+ name: 'complexComponent',
317
+ namespace: 'c',
318
+ type: 'file',
319
+ fileName: 'complexComponent.js',
320
+ komaciDoc: complexKomaciDoc,
321
+ },
322
+ };
323
+ const testError = new Error('Complex component error');
324
+ const result = (0, functionAstGeneration_1.produceErrorAdgFunction)((0, common_shared_1.initModuleMetadataObject)(), testError, input);
325
+ const generatedCode = (0, generator_1.default)((0, types_1.file)(result)).code;
326
+ expect(generatedCode).toContain('Has adgs: yes (1)');
327
+ expect(generatedCode).toContain('Has imports: yes (5)');
328
+ expect(generatedCode).toContain('Has exports: yes');
329
+ // Note: file type modules don't show compositions in the debug output
330
+ // since compositions are part of the KomaciDoc structure
331
+ });
332
+ });
333
+ describe('real-world error scenarios', () => {
334
+ it('should provide useful debug info for Babel parse errors', () => {
335
+ const input = {
336
+ moduleInfo: {
337
+ name: 'syntaxError',
338
+ namespace: 'c',
339
+ type: 'bundle',
340
+ files: {
341
+ 'syntaxError.js': {
342
+ adgs: [
343
+ {
344
+ properties: {
345
+ value: { isPublic: true },
346
+ },
347
+ },
348
+ ],
349
+ exports: { default: { type: 'AdgReference', value: 0 } },
350
+ },
351
+ },
352
+ },
353
+ srcFileMap: {
354
+ 'syntaxError.js': `import { LightningElement } from 'lwc';
355
+ export default class SyntaxError extends LightningElement {
356
+ get computedValue() {
357
+ return this?.value ?? 'default'; // Line 4
358
+ }
359
+ }`,
360
+ },
361
+ };
362
+ const babelError = new Error('Unexpected token (4:21)');
363
+ babelError.stack = `Error: Unexpected token (4:21)
364
+ at Parser._raise (/node_modules/@babel/parser/lib/index.js:762:17)
365
+ at Parser.raiseWithData (/node_modules/@babel/parser/lib/index.js:755:17)
366
+ at Parser.raise (/node_modules/@babel/parser/lib/index.js:749:17)
367
+ at generateAstFromSrcCode (packages/@komaci/common-shared/src/parser.ts:11:23)
368
+ at generateResolvableModule (packages/@komaci/esm-generator/src/genericAstGeneration.ts:146:19)`;
369
+ const result = (0, functionAstGeneration_1.produceErrorAdgFunction)((0, common_shared_1.initModuleMetadataObject)(), babelError, input);
370
+ const generatedCode = (0, generator_1.default)((0, types_1.file)(result)).code;
371
+ // Developer can now see:
372
+ // 1. Debug info section
373
+ expect(generatedCode).toContain('Extra Debug Info:');
374
+ // 2. The exact error
375
+ expect(generatedCode).toContain('Unexpected token (4:21)');
376
+ // 3. Where it failed in the stack
377
+ expect(generatedCode).toContain('Parser._raise');
378
+ expect(generatedCode).toContain('generateAstFromSrcCode');
379
+ // 4. What the source looks like
380
+ expect(generatedCode).toContain('syntaxError.js:');
381
+ expect(generatedCode).toContain('6 lines');
382
+ // 5. What was in the KomaciDoc
383
+ expect(generatedCode).toContain('Has adgs: yes (1)');
384
+ });
385
+ });
386
+ });
387
+ //# sourceMappingURL=produceErrorAdgFunction-debug.spec.js.map
@@ -2,6 +2,7 @@ import { NodePath } from '@babel/core';
2
2
  import * as t from '@babel/types';
3
3
  import { AdgMetadata, HoistedFunctionMetadata, IdKeys, ImportMetadata, ModuleMetadata, GqlMetadata } from '@komaci/common-shared';
4
4
  import { Composition } from '@komaci/types';
5
+ import { GeneratorInput } from './types';
5
6
  /**
6
7
  * Take a local function (getter, template string, etc) and prepare it for the resolvable module
7
8
  * - sanitize the function
@@ -84,7 +85,7 @@ export declare function getInlineFunctionFromTemplateCompositions(moduleMetadata
84
85
  * @param error The error that was thrown
85
86
  * @returns A default export representing the error state for this resolvable module
86
87
  */
87
- export declare function produceErrorAdgFunction(moduleMetadata: ModuleMetadata, error: Error): t.Program;
88
+ export declare function produceErrorAdgFunction(moduleMetadata: ModuleMetadata, error: Error, generatorInput?: GeneratorInput | undefined): t.Program;
88
89
  /**
89
90
  * Helper function to return the static metadata assignemnt expression statement.
90
91
  * @param adgName the name of the adg function to associate the adgMeta object with.
@@ -490,13 +490,54 @@ exports.getInlineFunctionFromTemplateCompositions = getInlineFunctionFromTemplat
490
490
  * @param error The error that was thrown
491
491
  * @returns A default export representing the error state for this resolvable module
492
492
  */
493
- function produceErrorAdgFunction(moduleMetadata, error) {
493
+ function produceErrorAdgFunction(moduleMetadata, error, generatorInput = undefined) {
494
+ let extraDebugInfo = '';
495
+ if (generatorInput) {
496
+ // Log KomaciDocument structure
497
+ if (generatorInput.moduleInfo.type === 'bundle') {
498
+ const files = generatorInput.moduleInfo.files;
499
+ extraDebugInfo += `Files in bundle: ${Object.keys(files).join(', ')}\n`;
500
+ Object.entries(files).forEach(([fileName, komaciDoc]) => {
501
+ extraDebugInfo += `\n File: ${fileName}:\n`;
502
+ extraDebugInfo += ` - Has adgs: ${komaciDoc?.adgs ? `yes (${komaciDoc.adgs.length})` : 'no'}\n`;
503
+ extraDebugInfo += ` - Has imports: ${komaciDoc?.imports ? `yes (${komaciDoc.imports.length})` : 'no'}\n`;
504
+ extraDebugInfo += ` - Has exports: ${komaciDoc?.exports ? 'yes' : 'no'}\n`;
505
+ extraDebugInfo += ` - Has compositions: ${komaciDoc?.compositions
506
+ ? `yes (${komaciDoc.compositions.length})`
507
+ : 'no'}\n`;
508
+ });
509
+ }
510
+ else {
511
+ const fileInfo = generatorInput.moduleInfo;
512
+ extraDebugInfo += `File: ${fileInfo.fileName}\n`;
513
+ extraDebugInfo += ` - Has adgs: ${fileInfo.komaciDoc?.adgs
514
+ ? `yes (${fileInfo.komaciDoc.adgs.length})`
515
+ : 'no'}\n`;
516
+ extraDebugInfo += ` - Has imports: ${fileInfo.komaciDoc?.imports
517
+ ? `yes (${fileInfo.komaciDoc.imports.length})`
518
+ : 'no'}\n`;
519
+ extraDebugInfo += ` - Has exports: ${fileInfo.komaciDoc?.exports ? 'yes' : 'no'}\n`;
520
+ }
521
+ // Log source files
522
+ if (generatorInput.srcFileMap) {
523
+ extraDebugInfo += '\n Source Files:\n';
524
+ Object.entries(generatorInput.srcFileMap).forEach(([fileName, source]) => {
525
+ extraDebugInfo += ` - ${fileName}: ${source.length} chars, ${source.split('\n').length} lines\n`;
526
+ });
527
+ }
528
+ }
494
529
  const functionValues = {
495
530
  error: {
496
531
  type: 'PrimitiveValue',
497
532
  value: error instanceof Error
498
- ? error.message
499
- : common_shared_1.ERROR_PREFIX + 'Something that is not an error was thrown',
533
+ ? error.message + `\n\nExtra Debug Info:\n\n${extraDebugInfo}`
534
+ : common_shared_1.ERROR_PREFIX +
535
+ 'Something that is not an error was thrown' +
536
+ `\n\nExtra Debug Info:\n\n${extraDebugInfo}`,
537
+ },
538
+ stack: {
539
+ type: 'PrimitiveValue',
540
+ value: error instanceof Error ? error.stack : 'No stack trace available',
500
541
  },
501
542
  };
502
543
  const registerAdgImport = t.importDeclaration([t.importDefaultSpecifier(t.identifier('registerAdgFunction'))], t.stringLiteral('komaci/registerAdgFunction'));
package/build/index.js CHANGED
@@ -42,7 +42,7 @@ function generateKomaciModule(input) {
42
42
  }
43
43
  catch (e) {
44
44
  const moduleMetadata = (0, common_shared_1.initModuleMetadataObject)();
45
- const babelOutput = (0, generator_1.default)(t.file((0, functionAstGeneration_1.produceErrorAdgFunction)(moduleMetadata, e)));
45
+ const babelOutput = (0, generator_1.default)(t.file((0, functionAstGeneration_1.produceErrorAdgFunction)(moduleMetadata, e, input)));
46
46
  return babelOutput.code;
47
47
  }
48
48
  }
@@ -134,7 +134,7 @@ function processGeneratorInputAndState(input) {
134
134
  if (fileExt == 'html') {
135
135
  filesMap['html'] = filesObj;
136
136
  }
137
- else if (fileExt === 'js') {
137
+ else if (fileExt === 'js' || fileExt === 'ts') {
138
138
  filesMap['js'] = filesObj;
139
139
  }
140
140
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@komaci/esm-generator",
3
- "version": "260.31.0",
3
+ "version": "262.9.0",
4
4
  "description": "Komaci generator for ADG ES modules",
5
5
  "homepage": "https://komaci.dev/",
6
6
  "repository": {