woodml-parser 1.0.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.
Files changed (82) hide show
  1. package/README.md +181 -0
  2. package/dist/cli.d.ts +7 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +554 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/cost.d.ts +94 -0
  7. package/dist/cost.d.ts.map +1 -0
  8. package/dist/cost.js +340 -0
  9. package/dist/cost.js.map +1 -0
  10. package/dist/cost.test.d.ts +2 -0
  11. package/dist/cost.test.d.ts.map +1 -0
  12. package/dist/cost.test.js +241 -0
  13. package/dist/cost.test.js.map +1 -0
  14. package/dist/example.d.ts +6 -0
  15. package/dist/example.d.ts.map +1 -0
  16. package/dist/example.js +136 -0
  17. package/dist/example.js.map +1 -0
  18. package/dist/formulas.d.ts +23 -0
  19. package/dist/formulas.d.ts.map +1 -0
  20. package/dist/formulas.js +442 -0
  21. package/dist/formulas.js.map +1 -0
  22. package/dist/formulas.test.d.ts +5 -0
  23. package/dist/formulas.test.d.ts.map +1 -0
  24. package/dist/formulas.test.js +360 -0
  25. package/dist/formulas.test.js.map +1 -0
  26. package/dist/index.d.ts +23 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +93 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/integration.test.d.ts +6 -0
  31. package/dist/integration.test.d.ts.map +1 -0
  32. package/dist/integration.test.js +271 -0
  33. package/dist/integration.test.js.map +1 -0
  34. package/dist/optimizer.d.ts +119 -0
  35. package/dist/optimizer.d.ts.map +1 -0
  36. package/dist/optimizer.js +423 -0
  37. package/dist/optimizer.js.map +1 -0
  38. package/dist/optimizer.test.d.ts +2 -0
  39. package/dist/optimizer.test.d.ts.map +1 -0
  40. package/dist/optimizer.test.js +225 -0
  41. package/dist/optimizer.test.js.map +1 -0
  42. package/dist/parser.d.ts +59 -0
  43. package/dist/parser.d.ts.map +1 -0
  44. package/dist/parser.js +305 -0
  45. package/dist/parser.js.map +1 -0
  46. package/dist/parser.test.d.ts +5 -0
  47. package/dist/parser.test.d.ts.map +1 -0
  48. package/dist/parser.test.js +486 -0
  49. package/dist/parser.test.js.map +1 -0
  50. package/dist/pdf.d.ts +36 -0
  51. package/dist/pdf.d.ts.map +1 -0
  52. package/dist/pdf.js +316 -0
  53. package/dist/pdf.js.map +1 -0
  54. package/dist/svg.d.ts +73 -0
  55. package/dist/svg.d.ts.map +1 -0
  56. package/dist/svg.js +613 -0
  57. package/dist/svg.js.map +1 -0
  58. package/dist/svg.test.d.ts +5 -0
  59. package/dist/svg.test.d.ts.map +1 -0
  60. package/dist/svg.test.js +333 -0
  61. package/dist/svg.test.js.map +1 -0
  62. package/dist/templates.d.ts +126 -0
  63. package/dist/templates.d.ts.map +1 -0
  64. package/dist/templates.js +448 -0
  65. package/dist/templates.js.map +1 -0
  66. package/dist/templates.test.d.ts +5 -0
  67. package/dist/templates.test.d.ts.map +1 -0
  68. package/dist/templates.test.js +630 -0
  69. package/dist/templates.test.js.map +1 -0
  70. package/dist/types.d.ts +250 -0
  71. package/dist/types.d.ts.map +1 -0
  72. package/dist/types.js +7 -0
  73. package/dist/types.js.map +1 -0
  74. package/dist/units.d.ts +53 -0
  75. package/dist/units.d.ts.map +1 -0
  76. package/dist/units.js +359 -0
  77. package/dist/units.js.map +1 -0
  78. package/dist/units.test.d.ts +5 -0
  79. package/dist/units.test.d.ts.map +1 -0
  80. package/dist/units.test.js +364 -0
  81. package/dist/units.test.js.map +1 -0
  82. package/package.json +46 -0
@@ -0,0 +1,630 @@
1
+ "use strict";
2
+ /**
3
+ * Unit Tests for WoodML Template System
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const node_test_1 = require("node:test");
10
+ const node_assert_1 = __importDefault(require("node:assert"));
11
+ const templates_1 = require("./templates");
12
+ const SIMPLE_TEMPLATE = {
13
+ name: 'simple_box',
14
+ description: 'A simple box with four sides and a bottom',
15
+ version: '1.0',
16
+ params: {
17
+ width: 'dimension',
18
+ depth: 'dimension',
19
+ height: 'dimension',
20
+ material: 'material_ref',
21
+ },
22
+ defaults: {
23
+ material: 'pine',
24
+ },
25
+ parts: [
26
+ {
27
+ id: 'front',
28
+ material: '${material}',
29
+ dimensions: {
30
+ length: '${width}',
31
+ width: '${height}',
32
+ thickness: '1/2"',
33
+ },
34
+ },
35
+ {
36
+ id: 'side',
37
+ material: '${material}',
38
+ dimensions: {
39
+ length: '${depth}',
40
+ width: '${height}',
41
+ thickness: '1/2"',
42
+ },
43
+ quantity: 2,
44
+ },
45
+ {
46
+ id: 'bottom',
47
+ material: '${material}',
48
+ dimensions: {
49
+ length: '${width}',
50
+ width: '${depth}',
51
+ thickness: '1/4"',
52
+ },
53
+ },
54
+ ],
55
+ joinery: [
56
+ {
57
+ type: 'rabbet',
58
+ parts: ['front', 'side'],
59
+ depth: '1/4"',
60
+ },
61
+ ],
62
+ };
63
+ const OPTIONAL_PARAMS_TEMPLATE = {
64
+ name: 'box_with_options',
65
+ params: {
66
+ width: 'dimension',
67
+ height: 'dimension',
68
+ custom_thickness: { type: 'dimension', optional: true },
69
+ },
70
+ defaults: {
71
+ custom_thickness: '3/4"',
72
+ },
73
+ parts: [
74
+ {
75
+ id: 'panel',
76
+ dimensions: {
77
+ length: '${width}',
78
+ width: '${height}',
79
+ thickness: '${custom_thickness}',
80
+ },
81
+ },
82
+ ],
83
+ };
84
+ const REPEAT_TEMPLATE = {
85
+ name: 'shelf_unit',
86
+ params: {
87
+ width: 'dimension',
88
+ depth: 'dimension',
89
+ num_shelves: 'number',
90
+ },
91
+ parts: [
92
+ {
93
+ id: 'shelf_${i}',
94
+ repeat: '${num_shelves}',
95
+ as: 'i',
96
+ dimensions: {
97
+ length: '${width}',
98
+ width: '${depth}',
99
+ thickness: '3/4"',
100
+ },
101
+ },
102
+ ],
103
+ };
104
+ (0, node_test_1.describe)('TemplateParser', () => {
105
+ (0, node_test_1.describe)('registerTemplate', () => {
106
+ (0, node_test_1.it)('should register a template', () => {
107
+ const parser = (0, templates_1.createTemplateParser)();
108
+ parser.registerTemplate(SIMPLE_TEMPLATE);
109
+ const template = parser.getTemplate('simple_box');
110
+ node_assert_1.default.ok(template);
111
+ node_assert_1.default.strictEqual(template.name, 'simple_box');
112
+ });
113
+ (0, node_test_1.it)('should list registered templates', () => {
114
+ const parser = (0, templates_1.createTemplateParser)();
115
+ parser.registerTemplate(SIMPLE_TEMPLATE);
116
+ parser.registerTemplate(OPTIONAL_PARAMS_TEMPLATE);
117
+ const templates = parser.listTemplates();
118
+ node_assert_1.default.strictEqual(templates.length, 2);
119
+ node_assert_1.default.ok(templates.includes('simple_box'));
120
+ node_assert_1.default.ok(templates.includes('box_with_options'));
121
+ });
122
+ });
123
+ (0, node_test_1.describe)('validateParams', () => {
124
+ (0, node_test_1.it)('should pass with all required params', () => {
125
+ const parser = (0, templates_1.createTemplateParser)();
126
+ parser.registerTemplate(SIMPLE_TEMPLATE);
127
+ const errors = parser.validateParams(SIMPLE_TEMPLATE, {
128
+ width: '12"',
129
+ depth: '8"',
130
+ height: '6"',
131
+ });
132
+ node_assert_1.default.strictEqual(errors.length, 0);
133
+ });
134
+ (0, node_test_1.it)('should fail on missing required param', () => {
135
+ const parser = (0, templates_1.createTemplateParser)();
136
+ const errors = parser.validateParams(SIMPLE_TEMPLATE, {
137
+ width: '12"',
138
+ depth: '8"',
139
+ // height is missing!
140
+ });
141
+ node_assert_1.default.ok(errors.length > 0);
142
+ node_assert_1.default.ok(errors.some(e => e.includes('height')));
143
+ });
144
+ (0, node_test_1.it)('should accept optional params', () => {
145
+ const parser = (0, templates_1.createTemplateParser)();
146
+ const errors = parser.validateParams(OPTIONAL_PARAMS_TEMPLATE, {
147
+ width: '24"',
148
+ height: '12"',
149
+ // custom_thickness is optional
150
+ });
151
+ node_assert_1.default.strictEqual(errors.length, 0);
152
+ });
153
+ (0, node_test_1.it)('should use defaults for missing params', () => {
154
+ const parser = (0, templates_1.createTemplateParser)();
155
+ // material has a default, so this should pass
156
+ const errors = parser.validateParams(SIMPLE_TEMPLATE, {
157
+ width: '12"',
158
+ depth: '8"',
159
+ height: '6"',
160
+ // material has default 'pine'
161
+ });
162
+ node_assert_1.default.strictEqual(errors.length, 0);
163
+ });
164
+ (0, node_test_1.it)('should validate dimension format', () => {
165
+ const parser = (0, templates_1.createTemplateParser)();
166
+ const errors = parser.validateParams(SIMPLE_TEMPLATE, {
167
+ width: 'not a dimension',
168
+ depth: '8"',
169
+ height: '6"',
170
+ });
171
+ node_assert_1.default.ok(errors.length > 0);
172
+ node_assert_1.default.ok(errors.some(e => e.includes('width')));
173
+ });
174
+ (0, node_test_1.it)('should validate min constraint for dimensions', () => {
175
+ const parser = (0, templates_1.createTemplateParser)();
176
+ const CONSTRAINED_TEMPLATE = {
177
+ name: 'constrained',
178
+ params: {
179
+ width: { type: 'dimension', min: '6"', max: '48"' },
180
+ },
181
+ parts: [],
182
+ };
183
+ const errors = parser.validateParams(CONSTRAINED_TEMPLATE, {
184
+ width: '4"', // Below minimum
185
+ });
186
+ node_assert_1.default.ok(errors.length > 0);
187
+ node_assert_1.default.ok(errors.some(e => e.includes('at least')));
188
+ });
189
+ (0, node_test_1.it)('should validate max constraint for dimensions', () => {
190
+ const parser = (0, templates_1.createTemplateParser)();
191
+ const CONSTRAINED_TEMPLATE = {
192
+ name: 'constrained',
193
+ params: {
194
+ width: { type: 'dimension', min: '6"', max: '48"' },
195
+ },
196
+ parts: [],
197
+ };
198
+ const errors = parser.validateParams(CONSTRAINED_TEMPLATE, {
199
+ width: '60"', // Above maximum
200
+ });
201
+ node_assert_1.default.ok(errors.length > 0);
202
+ node_assert_1.default.ok(errors.some(e => e.includes('at most')));
203
+ });
204
+ (0, node_test_1.it)('should pass when value is within constraints', () => {
205
+ const parser = (0, templates_1.createTemplateParser)();
206
+ const CONSTRAINED_TEMPLATE = {
207
+ name: 'constrained',
208
+ params: {
209
+ width: { type: 'dimension', min: '6"', max: '48"' },
210
+ },
211
+ parts: [],
212
+ };
213
+ const errors = parser.validateParams(CONSTRAINED_TEMPLATE, {
214
+ width: '24"', // Within range
215
+ });
216
+ node_assert_1.default.strictEqual(errors.length, 0);
217
+ });
218
+ (0, node_test_1.it)('should validate min constraint for numbers', () => {
219
+ const parser = (0, templates_1.createTemplateParser)();
220
+ const CONSTRAINED_TEMPLATE = {
221
+ name: 'constrained',
222
+ params: {
223
+ count: { type: 'number', min: 1, max: 10 },
224
+ },
225
+ parts: [],
226
+ };
227
+ const errors = parser.validateParams(CONSTRAINED_TEMPLATE, {
228
+ count: 0, // Below minimum
229
+ });
230
+ node_assert_1.default.ok(errors.length > 0);
231
+ node_assert_1.default.ok(errors.some(e => e.includes('at least')));
232
+ });
233
+ (0, node_test_1.it)('should validate max constraint for numbers', () => {
234
+ const parser = (0, templates_1.createTemplateParser)();
235
+ const CONSTRAINED_TEMPLATE = {
236
+ name: 'constrained',
237
+ params: {
238
+ count: { type: 'number', min: 1, max: 10 },
239
+ },
240
+ parts: [],
241
+ };
242
+ const errors = parser.validateParams(CONSTRAINED_TEMPLATE, {
243
+ count: 15, // Above maximum
244
+ });
245
+ node_assert_1.default.ok(errors.length > 0);
246
+ node_assert_1.default.ok(errors.some(e => e.includes('at most')));
247
+ });
248
+ });
249
+ (0, node_test_1.describe)('instantiate', () => {
250
+ (0, node_test_1.it)('should instantiate a simple template', () => {
251
+ const parser = (0, templates_1.createTemplateParser)();
252
+ parser.registerTemplate(SIMPLE_TEMPLATE);
253
+ const result = parser.instantiate('simple_box', 'my_box', {
254
+ width: '12"',
255
+ depth: '8"',
256
+ height: '6"',
257
+ material: 'walnut',
258
+ });
259
+ node_assert_1.default.strictEqual(result.parts.length, 3);
260
+ // Check part IDs are prefixed
261
+ node_assert_1.default.ok(result.parts.some(p => p.id === 'my_box.front'));
262
+ node_assert_1.default.ok(result.parts.some(p => p.id === 'my_box.side'));
263
+ node_assert_1.default.ok(result.parts.some(p => p.id === 'my_box.bottom'));
264
+ });
265
+ (0, node_test_1.it)('should substitute parameters in dimensions', () => {
266
+ const parser = (0, templates_1.createTemplateParser)();
267
+ parser.registerTemplate(SIMPLE_TEMPLATE);
268
+ const result = parser.instantiate('simple_box', 'test', {
269
+ width: '24"',
270
+ depth: '18"',
271
+ height: '12"',
272
+ material: 'oak',
273
+ });
274
+ const front = result.parts.find(p => p.id === 'test.front');
275
+ node_assert_1.default.ok(front);
276
+ node_assert_1.default.ok(front.dimensions);
277
+ // The substituted value should contain the resolved dimension
278
+ node_assert_1.default.ok(front.dimensions.length?.includes('24'));
279
+ });
280
+ (0, node_test_1.it)('should substitute material references', () => {
281
+ const parser = (0, templates_1.createTemplateParser)();
282
+ parser.registerTemplate(SIMPLE_TEMPLATE);
283
+ const result = parser.instantiate('simple_box', 'test', {
284
+ width: '12"',
285
+ depth: '8"',
286
+ height: '6"',
287
+ material: 'walnut',
288
+ });
289
+ const front = result.parts.find(p => p.id === 'test.front');
290
+ node_assert_1.default.ok(front);
291
+ node_assert_1.default.strictEqual(front.material, 'walnut');
292
+ });
293
+ (0, node_test_1.it)('should use default values', () => {
294
+ const parser = (0, templates_1.createTemplateParser)();
295
+ parser.registerTemplate(SIMPLE_TEMPLATE);
296
+ const result = parser.instantiate('simple_box', 'test', {
297
+ width: '12"',
298
+ depth: '8"',
299
+ height: '6"',
300
+ // material will use default 'pine'
301
+ });
302
+ const front = result.parts.find(p => p.id === 'test.front');
303
+ node_assert_1.default.ok(front);
304
+ node_assert_1.default.strictEqual(front.material, 'pine');
305
+ });
306
+ (0, node_test_1.it)('should preserve quantity', () => {
307
+ const parser = (0, templates_1.createTemplateParser)();
308
+ parser.registerTemplate(SIMPLE_TEMPLATE);
309
+ const result = parser.instantiate('simple_box', 'test', {
310
+ width: '12"',
311
+ depth: '8"',
312
+ height: '6"',
313
+ });
314
+ const side = result.parts.find(p => p.id === 'test.side');
315
+ node_assert_1.default.ok(side);
316
+ node_assert_1.default.strictEqual(side.quantity, 2);
317
+ });
318
+ (0, node_test_1.it)('should generate joinery with prefixed part IDs', () => {
319
+ const parser = (0, templates_1.createTemplateParser)();
320
+ parser.registerTemplate(SIMPLE_TEMPLATE);
321
+ const result = parser.instantiate('simple_box', 'test', {
322
+ width: '12"',
323
+ depth: '8"',
324
+ height: '6"',
325
+ });
326
+ node_assert_1.default.strictEqual(result.joinery.length, 1);
327
+ node_assert_1.default.strictEqual(result.joinery[0].type, 'rabbet');
328
+ node_assert_1.default.deepStrictEqual(result.joinery[0].parts, ['test.front', 'test.side']);
329
+ });
330
+ (0, node_test_1.it)('should throw on missing template', () => {
331
+ const parser = (0, templates_1.createTemplateParser)();
332
+ node_assert_1.default.throws(() => {
333
+ parser.instantiate('nonexistent', 'test', {});
334
+ }, /Template not found/);
335
+ });
336
+ (0, node_test_1.it)('should throw on invalid params', () => {
337
+ const parser = (0, templates_1.createTemplateParser)();
338
+ parser.registerTemplate(SIMPLE_TEMPLATE);
339
+ node_assert_1.default.throws(() => {
340
+ parser.instantiate('simple_box', 'test', {
341
+ width: '12"',
342
+ // Missing depth and height
343
+ });
344
+ }, /Template validation failed/);
345
+ });
346
+ });
347
+ (0, node_test_1.describe)('repeat functionality', () => {
348
+ (0, node_test_1.it)('should expand repeat parts', () => {
349
+ const parser = (0, templates_1.createTemplateParser)();
350
+ parser.registerTemplate(REPEAT_TEMPLATE);
351
+ const result = parser.instantiate('shelf_unit', 'unit', {
352
+ width: '36"',
353
+ depth: '12"',
354
+ num_shelves: 4,
355
+ });
356
+ node_assert_1.default.strictEqual(result.parts.length, 4);
357
+ // Check each shelf has correct ID pattern
358
+ for (let i = 0; i < 4; i++) {
359
+ node_assert_1.default.ok(result.parts.some(p => p.id === `unit.shelf_${i}`), `Missing shelf_${i}`);
360
+ }
361
+ });
362
+ });
363
+ (0, node_test_1.describe)('parseTemplateDefinition', () => {
364
+ (0, node_test_1.it)('should parse template from object', () => {
365
+ const parser = (0, templates_1.createTemplateParser)();
366
+ const data = {
367
+ template: {
368
+ name: 'test_template',
369
+ params: {
370
+ width: 'dimension',
371
+ height: 'dimension',
372
+ },
373
+ parts: [
374
+ {
375
+ id: 'panel',
376
+ dimensions: {
377
+ length: '${width}',
378
+ width: '${height}',
379
+ thickness: '3/4"',
380
+ },
381
+ },
382
+ ],
383
+ },
384
+ };
385
+ const template = parser.parseTemplateDefinition(data);
386
+ node_assert_1.default.strictEqual(template.name, 'test_template');
387
+ node_assert_1.default.ok(template.params.width);
388
+ node_assert_1.default.ok(template.params.height);
389
+ node_assert_1.default.strictEqual(template.parts.length, 1);
390
+ });
391
+ (0, node_test_1.it)('should parse optional params', () => {
392
+ const parser = (0, templates_1.createTemplateParser)();
393
+ const data = {
394
+ template: {
395
+ name: 'test',
396
+ params: {
397
+ required_param: 'dimension',
398
+ optional_param: 'dimension?',
399
+ },
400
+ parts: [],
401
+ },
402
+ };
403
+ const template = parser.parseTemplateDefinition(data);
404
+ // Simple string param
405
+ node_assert_1.default.strictEqual(template.params.required_param, 'dimension');
406
+ // Optional param becomes object
407
+ const optParam = template.params.optional_param;
408
+ node_assert_1.default.ok(typeof optParam === 'object');
409
+ node_assert_1.default.strictEqual(optParam.type, 'dimension');
410
+ node_assert_1.default.strictEqual(optParam.optional, true);
411
+ });
412
+ (0, node_test_1.it)('should parse constrained params', () => {
413
+ const parser = (0, templates_1.createTemplateParser)();
414
+ const data = {
415
+ template: {
416
+ name: 'test',
417
+ params: {
418
+ width: {
419
+ type: 'dimension',
420
+ min: '6"',
421
+ max: '48"',
422
+ description: 'Panel width',
423
+ },
424
+ joint_type: {
425
+ type: 'enum',
426
+ values: ['dovetail', 'box_joint', 'rabbet'],
427
+ },
428
+ },
429
+ parts: [],
430
+ },
431
+ };
432
+ const template = parser.parseTemplateDefinition(data);
433
+ const width = template.params.width;
434
+ node_assert_1.default.ok(typeof width === 'object');
435
+ node_assert_1.default.strictEqual(width.type, 'dimension');
436
+ node_assert_1.default.strictEqual(width.min, '6"');
437
+ node_assert_1.default.strictEqual(width.max, '48"');
438
+ node_assert_1.default.strictEqual(width.description, 'Panel width');
439
+ const jointType = template.params.joint_type;
440
+ node_assert_1.default.ok(typeof jointType === 'object');
441
+ node_assert_1.default.strictEqual(jointType.type, 'enum');
442
+ node_assert_1.default.deepStrictEqual(jointType.values, ['dovetail', 'box_joint', 'rabbet']);
443
+ });
444
+ (0, node_test_1.it)('should throw on missing name', () => {
445
+ const parser = (0, templates_1.createTemplateParser)();
446
+ node_assert_1.default.throws(() => {
447
+ parser.parseTemplateDefinition({
448
+ template: {
449
+ params: { width: 'dimension' },
450
+ parts: [],
451
+ },
452
+ });
453
+ }, /missing required "name"/);
454
+ });
455
+ (0, node_test_1.it)('should throw on missing params', () => {
456
+ const parser = (0, templates_1.createTemplateParser)();
457
+ node_assert_1.default.throws(() => {
458
+ parser.parseTemplateDefinition({
459
+ template: {
460
+ name: 'test',
461
+ parts: [],
462
+ },
463
+ });
464
+ }, /missing required "params"/);
465
+ });
466
+ });
467
+ });
468
+ (0, node_test_1.describe)('createTemplateParser', () => {
469
+ (0, node_test_1.it)('should create parser with default imperial units', () => {
470
+ const parser = (0, templates_1.createTemplateParser)();
471
+ node_assert_1.default.ok(parser);
472
+ });
473
+ (0, node_test_1.it)('should create parser with metric units', () => {
474
+ const parser = (0, templates_1.createTemplateParser)('metric');
475
+ node_assert_1.default.ok(parser);
476
+ });
477
+ });
478
+ (0, node_test_1.describe)('nested templates', () => {
479
+ const PANEL_TEMPLATE = {
480
+ name: 'panel',
481
+ params: {
482
+ width: 'dimension',
483
+ height: 'dimension',
484
+ thickness: 'dimension',
485
+ material: 'material_ref',
486
+ },
487
+ defaults: {
488
+ thickness: '3/4"',
489
+ material: 'plywood',
490
+ },
491
+ parts: [
492
+ {
493
+ id: 'panel',
494
+ material: '${material}',
495
+ dimensions: {
496
+ length: '${width}',
497
+ width: '${height}',
498
+ thickness: '${thickness}',
499
+ },
500
+ },
501
+ ],
502
+ };
503
+ const CABINET_TEMPLATE = {
504
+ name: 'cabinet',
505
+ params: {
506
+ width: 'dimension',
507
+ height: 'dimension',
508
+ depth: 'dimension',
509
+ material: 'material_ref',
510
+ },
511
+ defaults: {
512
+ material: 'maple',
513
+ },
514
+ parts: [
515
+ {
516
+ id: 'top',
517
+ use: 'panel',
518
+ params: {
519
+ width: '${width}',
520
+ height: '${depth}',
521
+ material: '${material}',
522
+ },
523
+ },
524
+ {
525
+ id: 'bottom',
526
+ use: 'panel',
527
+ params: {
528
+ width: '${width}',
529
+ height: '${depth}',
530
+ material: '${material}',
531
+ },
532
+ },
533
+ {
534
+ id: 'left_side',
535
+ use: 'panel',
536
+ params: {
537
+ width: '${depth}',
538
+ height: '${height}',
539
+ material: '${material}',
540
+ },
541
+ },
542
+ {
543
+ id: 'right_side',
544
+ use: 'panel',
545
+ params: {
546
+ width: '${depth}',
547
+ height: '${height}',
548
+ material: '${material}',
549
+ },
550
+ },
551
+ ],
552
+ };
553
+ (0, node_test_1.it)('should instantiate nested templates', () => {
554
+ const parser = (0, templates_1.createTemplateParser)();
555
+ parser.registerTemplate(PANEL_TEMPLATE);
556
+ parser.registerTemplate(CABINET_TEMPLATE);
557
+ const result = parser.instantiate('cabinet', 'my_cabinet', {
558
+ width: '24"',
559
+ height: '30"',
560
+ depth: '12"',
561
+ material: 'walnut',
562
+ });
563
+ // Each nested template produces 1 panel
564
+ node_assert_1.default.strictEqual(result.parts.length, 4);
565
+ // Check IDs are properly nested
566
+ node_assert_1.default.ok(result.parts.some(p => p.id.includes('top')));
567
+ node_assert_1.default.ok(result.parts.some(p => p.id.includes('bottom')));
568
+ node_assert_1.default.ok(result.parts.some(p => p.id.includes('left_side')));
569
+ node_assert_1.default.ok(result.parts.some(p => p.id.includes('right_side')));
570
+ });
571
+ (0, node_test_1.it)('should pass parameters to nested templates', () => {
572
+ const parser = (0, templates_1.createTemplateParser)();
573
+ parser.registerTemplate(PANEL_TEMPLATE);
574
+ parser.registerTemplate(CABINET_TEMPLATE);
575
+ const result = parser.instantiate('cabinet', 'cab', {
576
+ width: '24"',
577
+ height: '30"',
578
+ depth: '12"',
579
+ material: 'cherry',
580
+ });
581
+ // All parts should have the passed material
582
+ for (const part of result.parts) {
583
+ node_assert_1.default.strictEqual(part.material, 'cherry');
584
+ }
585
+ });
586
+ (0, node_test_1.it)('should throw on missing nested template', () => {
587
+ const parser = (0, templates_1.createTemplateParser)();
588
+ parser.registerTemplate(CABINET_TEMPLATE);
589
+ // Deliberately NOT registering PANEL_TEMPLATE
590
+ node_assert_1.default.throws(() => {
591
+ parser.instantiate('cabinet', 'cab', {
592
+ width: '24"',
593
+ height: '30"',
594
+ depth: '12"',
595
+ });
596
+ }, /Nested template not found/);
597
+ });
598
+ (0, node_test_1.it)('should use nested template defaults', () => {
599
+ const parser = (0, templates_1.createTemplateParser)();
600
+ parser.registerTemplate(PANEL_TEMPLATE);
601
+ // Template that uses panel without specifying thickness
602
+ const SIMPLE_PANEL_USER = {
603
+ name: 'simple_shelf',
604
+ params: {
605
+ width: 'dimension',
606
+ depth: 'dimension',
607
+ },
608
+ parts: [
609
+ {
610
+ id: 'shelf',
611
+ use: 'panel',
612
+ params: {
613
+ width: '${width}',
614
+ height: '${depth}',
615
+ // thickness and material will use defaults
616
+ },
617
+ },
618
+ ],
619
+ };
620
+ parser.registerTemplate(SIMPLE_PANEL_USER);
621
+ const result = parser.instantiate('simple_shelf', 'test', {
622
+ width: '36"',
623
+ depth: '10"',
624
+ });
625
+ node_assert_1.default.strictEqual(result.parts.length, 1);
626
+ // Part should use panel's default material
627
+ node_assert_1.default.strictEqual(result.parts[0].material, 'plywood');
628
+ });
629
+ });
630
+ //# sourceMappingURL=templates.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.test.js","sourceRoot":"","sources":["../src/templates.test.ts"],"names":[],"mappings":"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"}