@hirokisakabe/pom 5.1.0 → 5.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +10 -11
  2. package/dist/autoFit/autoFit.d.ts +2 -1
  3. package/dist/autoFit/autoFit.d.ts.map +1 -1
  4. package/dist/autoFit/autoFit.js +7 -7
  5. package/dist/autoFit/strategies/reduceFontSize.js +1 -1
  6. package/dist/autoFit/strategies/reduceGapAndPadding.js +1 -1
  7. package/dist/autoFit/strategies/reduceTableRowHeight.js +1 -1
  8. package/dist/autoFit/strategies/uniformScale.js +1 -1
  9. package/dist/buildContext.d.ts +12 -0
  10. package/dist/buildContext.d.ts.map +1 -0
  11. package/dist/buildContext.js +8 -0
  12. package/dist/buildPptx.d.ts +1 -1
  13. package/dist/buildPptx.d.ts.map +1 -1
  14. package/dist/buildPptx.js +15 -15
  15. package/dist/calcYogaLayout/calcYogaLayout.d.ts +3 -1
  16. package/dist/calcYogaLayout/calcYogaLayout.d.ts.map +1 -1
  17. package/dist/calcYogaLayout/calcYogaLayout.js +85 -341
  18. package/dist/calcYogaLayout/measureText.d.ts +1 -5
  19. package/dist/calcYogaLayout/measureText.d.ts.map +1 -1
  20. package/dist/calcYogaLayout/measureText.js +2 -10
  21. package/dist/icons/renderIcon.d.ts +1 -1
  22. package/dist/icons/renderIcon.d.ts.map +1 -1
  23. package/dist/icons/renderIcon.js +3 -4
  24. package/dist/parseXml/coercionRules.d.ts +35 -0
  25. package/dist/parseXml/coercionRules.d.ts.map +1 -0
  26. package/dist/parseXml/coercionRules.js +477 -0
  27. package/dist/parseXml/inputSchema.d.ts +326 -64
  28. package/dist/parseXml/inputSchema.d.ts.map +1 -1
  29. package/dist/parseXml/inputSchema.js +13 -3
  30. package/dist/parseXml/parseXml.d.ts.map +1 -1
  31. package/dist/parseXml/parseXml.js +40 -270
  32. package/dist/registry/definitions/box.d.ts +3 -0
  33. package/dist/registry/definitions/box.d.ts.map +1 -0
  34. package/dist/registry/definitions/box.js +6 -0
  35. package/dist/registry/definitions/chart.d.ts +3 -0
  36. package/dist/registry/definitions/chart.d.ts.map +1 -0
  37. package/dist/registry/definitions/chart.js +8 -0
  38. package/dist/registry/definitions/compositeNodes.d.ts +8 -0
  39. package/dist/registry/definitions/compositeNodes.d.ts.map +1 -0
  40. package/dist/registry/definitions/compositeNodes.js +81 -0
  41. package/dist/registry/definitions/icon.d.ts +3 -0
  42. package/dist/registry/definitions/icon.d.ts.map +1 -0
  43. package/dist/registry/definitions/icon.js +28 -0
  44. package/dist/registry/definitions/image.d.ts +3 -0
  45. package/dist/registry/definitions/image.d.ts.map +1 -0
  46. package/dist/registry/definitions/image.js +34 -0
  47. package/dist/registry/definitions/layer.d.ts +3 -0
  48. package/dist/registry/definitions/layer.d.ts.map +1 -0
  49. package/dist/registry/definitions/layer.js +49 -0
  50. package/dist/registry/definitions/line.d.ts +3 -0
  51. package/dist/registry/definitions/line.d.ts.map +1 -0
  52. package/dist/registry/definitions/line.js +26 -0
  53. package/dist/registry/definitions/list.d.ts +4 -0
  54. package/dist/registry/definitions/list.d.ts.map +1 -0
  55. package/dist/registry/definitions/list.js +53 -0
  56. package/dist/registry/definitions/shape.d.ts +3 -0
  57. package/dist/registry/definitions/shape.d.ts.map +1 -0
  58. package/dist/registry/definitions/shape.js +37 -0
  59. package/dist/registry/definitions/stack.d.ts +4 -0
  60. package/dist/registry/definitions/stack.d.ts.map +1 -0
  61. package/dist/registry/definitions/stack.js +78 -0
  62. package/dist/registry/definitions/table.d.ts +3 -0
  63. package/dist/registry/definitions/table.d.ts.map +1 -0
  64. package/dist/registry/definitions/table.js +16 -0
  65. package/dist/registry/definitions/text.d.ts +3 -0
  66. package/dist/registry/definitions/text.d.ts.map +1 -0
  67. package/dist/registry/definitions/text.js +35 -0
  68. package/dist/registry/index.d.ts +2 -0
  69. package/dist/registry/index.d.ts.map +1 -0
  70. package/dist/registry/index.js +34 -0
  71. package/dist/registry/nodeRegistry.d.ts +7 -0
  72. package/dist/registry/nodeRegistry.d.ts.map +1 -0
  73. package/dist/registry/nodeRegistry.js +13 -0
  74. package/dist/registry/types.d.ts +26 -0
  75. package/dist/registry/types.d.ts.map +1 -0
  76. package/dist/registry/types.js +1 -0
  77. package/dist/renderPptx/renderPptx.d.ts +2 -1
  78. package/dist/renderPptx/renderPptx.d.ts.map +1 -1
  79. package/dist/renderPptx/renderPptx.js +30 -61
  80. package/dist/renderPptx/types.d.ts +2 -0
  81. package/dist/renderPptx/types.d.ts.map +1 -1
  82. package/dist/renderPptx/utils/backgroundBorder.d.ts.map +1 -1
  83. package/dist/renderPptx/utils/backgroundBorder.js +1 -1
  84. package/dist/shared/freeYogaTree.d.ts.map +1 -0
  85. package/dist/shared/measureImage.d.ts +13 -3
  86. package/dist/shared/measureImage.d.ts.map +1 -1
  87. package/dist/shared/measureImage.js +14 -19
  88. package/dist/shared/walkTree.d.ts.map +1 -0
  89. package/dist/toPositioned/toPositioned.d.ts +8 -1
  90. package/dist/toPositioned/toPositioned.d.ts.map +1 -1
  91. package/dist/toPositioned/toPositioned.js +32 -189
  92. package/dist/types.d.ts +371 -37
  93. package/dist/types.d.ts.map +1 -1
  94. package/dist/types.js +20 -1
  95. package/package.json +3 -3
  96. package/dist/autoFit/freeYogaTree.d.ts.map +0 -1
  97. package/dist/autoFit/walkTree.d.ts.map +0 -1
  98. package/dist/renderPptx/nodes/index.d.ts +0 -15
  99. package/dist/renderPptx/nodes/index.d.ts.map +0 -1
  100. package/dist/renderPptx/nodes/index.js +0 -14
  101. /package/dist/{autoFit → shared}/freeYogaTree.d.ts +0 -0
  102. /package/dist/{autoFit → shared}/freeYogaTree.js +0 -0
  103. /package/dist/{autoFit → shared}/walkTree.d.ts +0 -0
  104. /package/dist/{autoFit → shared}/walkTree.js +0 -0
@@ -1,7 +1,6 @@
1
1
  import { XMLParser } from "fast-xml-parser";
2
- import { z } from "zod";
3
- import { inputTextNodeSchema, inputUlNodeSchema, inputOlNodeSchema, inputLiNodeSchema, inputImageNodeSchema, inputTableNodeSchema, inputShapeNodeSchema, inputChartNodeSchema, inputTimelineNodeSchema, inputMatrixNodeSchema, inputTreeNodeSchema, inputFlowNodeSchema, inputProcessArrowNodeSchema, inputPyramidNodeSchema, inputLineNodeSchema, inputIconNodeSchema, inputBaseNodeSchema, } from "./inputSchema.js";
4
- import { alignItemsSchema, justifyContentSchema, shadowStyleSchema, processArrowStepSchema, pyramidLevelSchema, timelineItemSchema, matrixAxisSchema, matrixQuadrantsSchema, matrixItemSchema, flowNodeItemSchema, flowConnectionSchema, chartDataSchema, tableColumnSchema, tableCellSchema, } from "../types.js";
2
+ import { inputTextNodeSchema, inputUlNodeSchema, inputOlNodeSchema, inputImageNodeSchema, inputTableNodeSchema, inputShapeNodeSchema, inputChartNodeSchema, inputTimelineNodeSchema, inputMatrixNodeSchema, inputTreeNodeSchema, inputFlowNodeSchema, inputProcessArrowNodeSchema, inputPyramidNodeSchema, inputLineNodeSchema, inputIconNodeSchema, } from "./inputSchema.js";
3
+ import { NODE_COERCION_MAP, CHILD_ELEMENT_COERCION_MAP, coerceWithRule, coerceFallback, getObjectShapeFromRule, isBooleanObjectUnionRule, } from "./coercionRules.js";
5
4
  // ===== ParseXmlError =====
6
5
  export class ParseXmlError extends Error {
7
6
  errors;
@@ -36,52 +35,16 @@ const TAG_TO_TYPE = {
36
35
  };
37
36
  // Reverse mapping: node type → tag name
38
37
  const TYPE_TO_TAG = Object.fromEntries(Object.entries(TAG_TO_TYPE).map(([tag, type]) => [type, tag]));
39
- function extractShape(schema) {
40
- return schema.shape;
41
- }
42
- const leafNodeShapes = {
43
- text: extractShape(inputTextNodeSchema),
44
- image: extractShape(inputImageNodeSchema),
45
- table: extractShape(inputTableNodeSchema),
46
- shape: extractShape(inputShapeNodeSchema),
47
- chart: extractShape(inputChartNodeSchema),
48
- timeline: extractShape(inputTimelineNodeSchema),
49
- matrix: extractShape(inputMatrixNodeSchema),
50
- tree: extractShape(inputTreeNodeSchema),
51
- flow: extractShape(inputFlowNodeSchema),
52
- processArrow: extractShape(inputProcessArrowNodeSchema),
53
- pyramid: extractShape(inputPyramidNodeSchema),
54
- line: extractShape(inputLineNodeSchema),
55
- ul: extractShape(inputUlNodeSchema),
56
- ol: extractShape(inputOlNodeSchema),
57
- icon: extractShape(inputIconNodeSchema),
58
- };
59
- const containerShapes = {
60
- box: extractShape(inputBaseNodeSchema.extend({ shadow: shadowStyleSchema.optional() })),
61
- vstack: extractShape(inputBaseNodeSchema.extend({
62
- gap: z.number().optional(),
63
- alignItems: alignItemsSchema.optional(),
64
- justifyContent: justifyContentSchema.optional(),
65
- shadow: shadowStyleSchema.optional(),
66
- })),
67
- hstack: extractShape(inputBaseNodeSchema.extend({
68
- gap: z.number().optional(),
69
- alignItems: alignItemsSchema.optional(),
70
- justifyContent: justifyContentSchema.optional(),
71
- shadow: shadowStyleSchema.optional(),
72
- })),
73
- layer: extractShape(inputBaseNodeSchema),
74
- };
75
38
  const CONTAINER_TYPES = new Set(["box", "vstack", "hstack", "layer"]);
76
39
  const TEXT_CONTENT_NODES = new Set(["text", "shape"]);
77
40
  // Attributes allowed on any node (e.g., x/y for Layer children positioning)
78
41
  const UNIVERSAL_ATTRS = new Set(["x", "y"]);
79
42
  // ===== Validation helpers =====
80
43
  function getKnownAttributes(nodeType) {
81
- const shape = leafNodeShapes[nodeType] ?? containerShapes[nodeType];
82
- if (!shape)
44
+ const rules = NODE_COERCION_MAP[nodeType];
45
+ if (!rules)
83
46
  return [];
84
- return Object.keys(shape).filter((k) => k !== "type");
47
+ return Object.keys(rules);
85
48
  }
86
49
  function levenshteinDistance(a, b) {
87
50
  const m = a.length;
@@ -115,10 +78,10 @@ function findClosestMatch(input, candidates) {
115
78
  return bestMatch;
116
79
  }
117
80
  function getKnownChildAttributes(tagName) {
118
- const shape = childElementShapes[tagName];
119
- if (!shape)
81
+ const rules = CHILD_ELEMENT_COERCION_MAP[tagName];
82
+ if (!rules)
120
83
  return [];
121
- return Object.keys(shape);
84
+ return Object.keys(rules);
122
85
  }
123
86
  // ===== Leaf node Zod validation schemas =====
124
87
  const leafNodeValidationSchemas = {
@@ -229,165 +192,11 @@ function validateLeafNode(nodeType, result, errors) {
229
192
  }
230
193
  }
231
194
  }
232
- function getDef(schema) {
233
- return schema._def;
234
- }
235
- function getPropertySchema(nodeType, propertyName) {
236
- const shape = leafNodeShapes[nodeType] ?? containerShapes[nodeType];
237
- if (!shape)
238
- return undefined;
239
- return shape[propertyName];
240
- }
241
- function getZodType(schema) {
242
- const def = getDef(schema);
243
- return (def.type ?? def.typeName ?? "");
244
- }
245
- function unwrapSchema(schema) {
246
- const typeName = getZodType(schema);
247
- const def = getDef(schema);
248
- switch (typeName) {
249
- case "optional":
250
- case "default":
251
- case "nullable":
252
- return unwrapSchema(def.innerType);
253
- case "lazy":
254
- return unwrapSchema(def.getter());
255
- case "pipe":
256
- return unwrapSchema(def.in);
257
- default:
258
- return schema;
259
- }
260
- }
261
- function resolveZodTypeName(schema) {
262
- return getZodType(unwrapSchema(schema));
263
- }
264
- // ===== Value coercion =====
265
- // Returns { value, error } — if error is non-null, coercion failed.
266
- function coerceValue(value, schema) {
267
- const unwrapped = unwrapSchema(schema);
268
- const typeName = getZodType(unwrapped);
269
- const def = getDef(unwrapped);
270
- switch (typeName) {
271
- case "number": {
272
- const num = Number(value);
273
- if (isNaN(num)) {
274
- return {
275
- value: undefined,
276
- error: `Cannot convert "${value}" to number`,
277
- };
278
- }
279
- return { value: num, error: null };
280
- }
281
- case "boolean":
282
- if (value !== "true" && value !== "false") {
283
- return {
284
- value: undefined,
285
- error: `Cannot convert "${value}" to boolean (expected "true" or "false")`,
286
- };
287
- }
288
- return { value: value === "true", error: null };
289
- case "string":
290
- case "enum":
291
- return { value, error: null };
292
- case "literal": {
293
- const values = def.values;
294
- const singleValue = def.value;
295
- return { value: values?.[0] ?? singleValue, error: null };
296
- }
297
- case "array":
298
- case "object":
299
- case "record":
300
- case "tuple":
301
- try {
302
- return { value: JSON.parse(value), error: null };
303
- }
304
- catch {
305
- return {
306
- value: undefined,
307
- error: `Cannot parse JSON value: "${value}"`,
308
- };
309
- }
310
- case "union": {
311
- const options = def.options;
312
- return { value: coerceUnionValue(value, options), error: null };
313
- }
314
- default:
315
- return { value: coerceFallback(value), error: null };
316
- }
317
- }
318
- function coerceUnionValue(value, options) {
319
- const typeNames = options.map((opt) => resolveZodTypeName(opt));
320
- // Try boolean
321
- if ((value === "true" || value === "false") &&
322
- typeNames.includes("boolean")) {
323
- return value === "true";
324
- }
325
- // Try number
326
- if (typeNames.includes("number")) {
327
- const num = Number(value);
328
- if (!isNaN(num) && value !== "") {
329
- return num;
330
- }
331
- }
332
- // Try literal
333
- for (let i = 0; i < options.length; i++) {
334
- if (typeNames[i] === "literal") {
335
- const unwrapped = unwrapSchema(options[i]);
336
- const def = getDef(unwrapped);
337
- const values = def.values;
338
- const singleValue = def.value;
339
- const litVal = values?.[0] ?? singleValue;
340
- if (litVal != null && `${litVal}` === value)
341
- return litVal;
342
- }
343
- }
344
- // Try JSON parse for objects/arrays
345
- if (typeNames.some((t) => ["array", "object", "record", "tuple"].includes(t))) {
346
- if (value.startsWith("{") || value.startsWith("[")) {
347
- try {
348
- return JSON.parse(value);
349
- }
350
- catch {
351
- /* ignore */
352
- }
353
- }
354
- }
355
- // Fallback to string
356
- return value;
357
- }
358
- function coerceFallback(value) {
359
- if (value === "true")
360
- return true;
361
- if (value === "false")
362
- return false;
363
- const num = Number(value);
364
- if (value !== "" && !isNaN(num))
365
- return num;
366
- if (value.startsWith("{") || value.startsWith("[")) {
367
- try {
368
- return JSON.parse(value);
369
- }
370
- catch {
371
- /* ignore */
372
- }
373
- }
374
- return value;
195
+ // ===== Coercion rule lookup =====
196
+ function getCoercionRule(nodeType, propertyName) {
197
+ return NODE_COERCION_MAP[nodeType]?.[propertyName];
375
198
  }
376
199
  // ===== Dot notation helpers =====
377
- /**
378
- * Checks if a schema is a union containing both boolean and object types.
379
- * Used to allow `endArrow="true" endArrow.type="triangle"` coexistence.
380
- */
381
- function isBooleanObjectUnion(schema) {
382
- const unwrapped = unwrapSchema(schema);
383
- const typeName = getZodType(unwrapped);
384
- if (typeName !== "union")
385
- return false;
386
- const def = getDef(unwrapped);
387
- const options = def.options;
388
- const typeNames = options.map((opt) => getZodType(unwrapSchema(opt)));
389
- return typeNames.includes("boolean") && typeNames.includes("object");
390
- }
391
200
  // ===== Dot notation expansion =====
392
201
  function expandDotNotation(attrs) {
393
202
  const regular = {};
@@ -407,26 +216,13 @@ function expandDotNotation(attrs) {
407
216
  }
408
217
  return { regular, dotGroups };
409
218
  }
410
- function coerceDotGroup(prefix, subAttrs, schema, tagName, errors) {
411
- const unwrapped = unwrapSchema(schema);
412
- const typeName = getZodType(unwrapped);
413
- let objectSchema;
414
- if (typeName === "object") {
415
- objectSchema = unwrapped;
416
- }
417
- else if (typeName === "union") {
418
- const def = getDef(unwrapped);
419
- const options = def.options;
420
- objectSchema = options.find((opt) => getZodType(unwrapSchema(opt)) === "object");
421
- if (objectSchema)
422
- objectSchema = unwrapSchema(objectSchema);
423
- }
219
+ function coerceDotGroup(prefix, subAttrs, rule, tagName, errors) {
220
+ const objectShape = getObjectShapeFromRule(rule);
424
221
  const obj = {};
425
- if (objectSchema) {
426
- const shape = extractShape(objectSchema);
222
+ if (objectShape) {
427
223
  for (const [subKey, subValue] of Object.entries(subAttrs)) {
428
- if (shape[subKey]) {
429
- const coerced = coerceValue(subValue, shape[subKey]);
224
+ if (objectShape[subKey]) {
225
+ const coerced = coerceWithRule(subValue, objectShape[subKey]);
430
226
  if (coerced.error !== null) {
431
227
  errors.push(`<${tagName}>: ${prefix}.${subKey}: ${coerced.error}`);
432
228
  }
@@ -435,7 +231,7 @@ function coerceDotGroup(prefix, subAttrs, schema, tagName, errors) {
435
231
  }
436
232
  }
437
233
  else {
438
- const knownSubKeys = Object.keys(shape);
234
+ const knownSubKeys = Object.keys(objectShape);
439
235
  const suggestion = findClosestMatch(subKey, knownSubKeys);
440
236
  errors.push(`<${tagName}>: Unknown sub-attribute "${prefix}.${subKey}"${suggestion ? `. Did you mean "${prefix}.${suggestion}"?` : ""}`);
441
237
  }
@@ -488,30 +284,16 @@ function getTextContent(node) {
488
284
  }
489
285
  return textParts.length > 0 ? textParts.join("") : undefined;
490
286
  }
491
- // ===== Child element schemas for type coercion =====
492
- const childElementShapes = {
493
- ProcessArrowStep: extractShape(processArrowStepSchema),
494
- PyramidLevel: extractShape(pyramidLevelSchema),
495
- TimelineItem: extractShape(timelineItemSchema),
496
- MatrixAxes: extractShape(matrixAxisSchema),
497
- MatrixQuadrants: extractShape(matrixQuadrantsSchema),
498
- MatrixItem: extractShape(matrixItemSchema),
499
- FlowNode: extractShape(flowNodeItemSchema),
500
- FlowConnection: extractShape(flowConnectionSchema),
501
- TableColumn: extractShape(tableColumnSchema),
502
- TableCell: extractShape(tableCellSchema),
503
- Li: extractShape(inputLiNodeSchema),
504
- };
505
287
  function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
506
- const shape = childElementShapes[tagName];
288
+ const rules = CHILD_ELEMENT_COERCION_MAP[tagName];
507
289
  const result = {};
508
290
  const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);
509
291
  // Process dot-notation attributes
510
292
  for (const [prefix, subAttrs] of Object.entries(dotGroups)) {
511
- if (shape && shape[prefix]) {
512
- result[prefix] = coerceDotGroup(prefix, subAttrs, shape[prefix], `${parentTagName}.${tagName}`, errors);
293
+ if (rules && rules[prefix]) {
294
+ result[prefix] = coerceDotGroup(prefix, subAttrs, rules[prefix], `${parentTagName}.${tagName}`, errors);
513
295
  }
514
- else if (shape) {
296
+ else if (rules) {
515
297
  const knownAttrs = getKnownChildAttributes(tagName);
516
298
  const suggestion = findClosestMatch(prefix, knownAttrs);
517
299
  errors.push(`<${parentTagName}>.<${tagName}>: Unknown attribute "${prefix}"${suggestion ? `. Did you mean "${suggestion}"?` : ""}`);
@@ -527,11 +309,11 @@ function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
527
309
  // Process regular attributes
528
310
  for (const [key, value] of Object.entries(regularAttrs)) {
529
311
  if (key in dotGroups) {
530
- // When the schema is a union of boolean and object,
312
+ // When the rule is a union of boolean and object,
531
313
  // allow boolean shorthand to coexist with dot-notation by ignoring the boolean value.
532
- if (shape &&
533
- shape[key] &&
534
- isBooleanObjectUnion(shape[key]) &&
314
+ if (rules &&
315
+ rules[key] &&
316
+ isBooleanObjectUnionRule(rules[key]) &&
535
317
  (value === "true" || value === "false")) {
536
318
  // Silently skip the boolean value; dot-notation takes priority
537
319
  continue;
@@ -539,8 +321,8 @@ function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
539
321
  errors.push(`<${parentTagName}>.<${tagName}>: Attribute "${key}" conflicts with dot-notation attributes. Use one or the other, not both`);
540
322
  continue;
541
323
  }
542
- if (shape && shape[key]) {
543
- const coerced = coerceValue(value, shape[key]);
324
+ if (rules && rules[key]) {
325
+ const coerced = coerceWithRule(value, rules[key]);
544
326
  if (coerced.error !== null) {
545
327
  errors.push(`<${parentTagName}>.<${tagName}>: ${coerced.error}`);
546
328
  }
@@ -548,7 +330,7 @@ function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
548
330
  result[key] = coerced.value;
549
331
  }
550
332
  }
551
- else if (shape) {
333
+ else if (rules) {
552
334
  // Unknown attribute on child element
553
335
  const knownAttrs = getKnownChildAttributes(tagName);
554
336
  const suggestion = findClosestMatch(key, knownAttrs);
@@ -642,7 +424,6 @@ function convertFlowChildren(childElements, result, errors) {
642
424
  }
643
425
  }
644
426
  function convertChartChildren(childElements, result, errors) {
645
- const dataShape = extractShape(chartDataSchema);
646
427
  const data = [];
647
428
  for (const child of childElements) {
648
429
  const tag = getTagName(child);
@@ -656,19 +437,8 @@ function convertChartChildren(childElements, result, errors) {
656
437
  values: [],
657
438
  };
658
439
  if (attrs.name !== undefined) {
659
- const nameSchema = dataShape.name;
660
- if (nameSchema) {
661
- const coerced = coerceValue(attrs.name, nameSchema);
662
- if (coerced.error !== null) {
663
- errors.push(`<Chart>.<ChartSeries>: ${coerced.error}`);
664
- }
665
- else {
666
- series.name = coerced.value;
667
- }
668
- }
669
- else {
670
- series.name = attrs.name;
671
- }
440
+ // chartDataSchema.name z.string().optional() なのでそのまま文字列として使用
441
+ series.name = attrs.name;
672
442
  }
673
443
  for (const dp of getChildElements(child)) {
674
444
  const dpTag = getTagName(dp);
@@ -838,9 +608,9 @@ function convertPomNode(nodeType, tagName, attrs, childElements, textContent, er
838
608
  for (const [prefix, subAttrs] of Object.entries(dotGroups)) {
839
609
  if (prefix === "type")
840
610
  continue;
841
- const propSchema = getPropertySchema(nodeType, prefix);
842
- if (propSchema) {
843
- result[prefix] = coerceDotGroup(prefix, subAttrs, propSchema, tagName, errors);
611
+ const rule = getCoercionRule(nodeType, prefix);
612
+ if (rule) {
613
+ result[prefix] = coerceDotGroup(prefix, subAttrs, rule, tagName, errors);
844
614
  }
845
615
  else {
846
616
  const knownAttrs = getKnownAttributes(nodeType);
@@ -858,11 +628,11 @@ function convertPomNode(nodeType, tagName, attrs, childElements, textContent, er
858
628
  continue;
859
629
  // Conflict check: dot-notation and regular attribute for the same key
860
630
  if (key in dotGroups) {
861
- // When the schema is a union of boolean and object (e.g., endArrow),
631
+ // When the rule is a union of boolean and object (e.g., endArrow),
862
632
  // allow boolean shorthand to coexist with dot-notation by ignoring the boolean value.
863
- const propSchemaForConflict = getPropertySchema(nodeType, key);
864
- if (propSchemaForConflict &&
865
- isBooleanObjectUnion(propSchemaForConflict) &&
633
+ const ruleForConflict = getCoercionRule(nodeType, key);
634
+ if (ruleForConflict &&
635
+ isBooleanObjectUnionRule(ruleForConflict) &&
866
636
  (value === "true" || value === "false")) {
867
637
  // Silently skip the boolean value; dot-notation takes priority
868
638
  continue;
@@ -870,9 +640,9 @@ function convertPomNode(nodeType, tagName, attrs, childElements, textContent, er
870
640
  errors.push(`<${tagName}>: Attribute "${key}" conflicts with dot-notation attributes (e.g., "${key}.xxx"). Use one or the other, not both`);
871
641
  continue;
872
642
  }
873
- const propSchema = getPropertySchema(nodeType, key);
874
- if (propSchema) {
875
- const coerced = coerceValue(value, propSchema);
643
+ const rule = getCoercionRule(nodeType, key);
644
+ if (rule) {
645
+ const coerced = coerceWithRule(value, rule);
876
646
  if (coerced.error !== null) {
877
647
  errors.push(`<${tagName}>: ${coerced.error}`);
878
648
  }
@@ -0,0 +1,3 @@
1
+ import type { NodeDefinition } from "../types.ts";
2
+ export declare const boxNodeDef: NodeDefinition;
3
+ //# sourceMappingURL=box.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/box.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,eAAO,MAAM,UAAU,EAAE,cAKxB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export const boxNodeDef = {
2
+ type: "box",
3
+ category: "single-child",
4
+ // applyYogaStyle: デフォルトで十分(共通スタイルのみ)
5
+ // render: category ベースの子要素再帰で対応
6
+ };
@@ -0,0 +1,3 @@
1
+ import type { NodeDefinition } from "../types.ts";
2
+ export declare const chartNodeDef: NodeDefinition;
3
+ //# sourceMappingURL=chart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/chart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,eAAO,MAAM,YAAY,EAAE,cAM1B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { renderChartNode } from "../../renderPptx/nodes/chart.js";
2
+ export const chartNodeDef = {
3
+ type: "chart",
4
+ category: "leaf",
5
+ render(node, ctx) {
6
+ renderChartNode(node, ctx);
7
+ },
8
+ };
@@ -0,0 +1,8 @@
1
+ import type { NodeDefinition } from "../types.ts";
2
+ export declare const timelineNodeDef: NodeDefinition;
3
+ export declare const matrixNodeDef: NodeDefinition;
4
+ export declare const treeNodeDef: NodeDefinition;
5
+ export declare const flowNodeDef: NodeDefinition;
6
+ export declare const processArrowNodeDef: NodeDefinition;
7
+ export declare const pyramidNodeDef: NodeDefinition;
8
+ //# sourceMappingURL=compositeNodes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compositeNodes.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/compositeNodes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAQ,MAAM,aAAa,CAAC;AAqDxD,eAAO,MAAM,eAAe,EAAE,cAS7B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,cAS3B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,cASzB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,cASzB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,cAYjC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,cAS5B,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { measureProcessArrow, measureTimeline, measureMatrix, measureTree, measureFlow, measurePyramid, } from "../../calcYogaLayout/measureCompositeNodes.js";
2
+ import { renderTimelineNode } from "../../renderPptx/nodes/timeline.js";
3
+ import { renderMatrixNode } from "../../renderPptx/nodes/matrix.js";
4
+ import { renderTreeNode } from "../../renderPptx/nodes/tree.js";
5
+ import { renderFlowNode } from "../../renderPptx/nodes/flow.js";
6
+ import { renderProcessArrowNode } from "../../renderPptx/nodes/processArrow.js";
7
+ import { renderPyramidNode } from "../../renderPptx/nodes/pyramid.js";
8
+ /**
9
+ * コンポジットノードの最小スケール閾値。
10
+ * renderPptx/utils/scaleToFit.ts の MIN_SCALE_THRESHOLD と同じ値を維持すること。
11
+ */
12
+ const MIN_SCALE_THRESHOLD = 0.5;
13
+ /** 制約付きサイズを閾値でクランプする */
14
+ function constrainWithMinScale(intrinsicSize, availableSize) {
15
+ const minSize = intrinsicSize * MIN_SCALE_THRESHOLD;
16
+ return Math.max(minSize, Math.min(intrinsicSize, availableSize));
17
+ }
18
+ /** コンポジットノード共通の measureFunc セットアップ */
19
+ function applyCompositeMeasure(measureFn) {
20
+ return (node, yn, yoga) => {
21
+ yn.setMeasureFunc((width, widthMode, height, heightMode) => {
22
+ const intrinsic = measureFn(node);
23
+ return {
24
+ width: widthMode !== yoga.MEASURE_MODE_UNDEFINED
25
+ ? constrainWithMinScale(intrinsic.width, width)
26
+ : intrinsic.width,
27
+ height: heightMode !== yoga.MEASURE_MODE_UNDEFINED
28
+ ? constrainWithMinScale(intrinsic.height, height)
29
+ : intrinsic.height,
30
+ };
31
+ });
32
+ };
33
+ }
34
+ export const timelineNodeDef = {
35
+ type: "timeline",
36
+ category: "leaf",
37
+ applyYogaStyle: applyCompositeMeasure(measureTimeline),
38
+ render(node, ctx) {
39
+ renderTimelineNode(node, ctx);
40
+ },
41
+ };
42
+ export const matrixNodeDef = {
43
+ type: "matrix",
44
+ category: "leaf",
45
+ applyYogaStyle: applyCompositeMeasure(measureMatrix),
46
+ render(node, ctx) {
47
+ renderMatrixNode(node, ctx);
48
+ },
49
+ };
50
+ export const treeNodeDef = {
51
+ type: "tree",
52
+ category: "leaf",
53
+ applyYogaStyle: applyCompositeMeasure(measureTree),
54
+ render(node, ctx) {
55
+ renderTreeNode(node, ctx);
56
+ },
57
+ };
58
+ export const flowNodeDef = {
59
+ type: "flow",
60
+ category: "leaf",
61
+ applyYogaStyle: applyCompositeMeasure(measureFlow),
62
+ render(node, ctx) {
63
+ renderFlowNode(node, ctx);
64
+ },
65
+ };
66
+ export const processArrowNodeDef = {
67
+ type: "processArrow",
68
+ category: "leaf",
69
+ applyYogaStyle: applyCompositeMeasure(measureProcessArrow),
70
+ render(node, ctx) {
71
+ renderProcessArrowNode(node, ctx);
72
+ },
73
+ };
74
+ export const pyramidNodeDef = {
75
+ type: "pyramid",
76
+ category: "leaf",
77
+ applyYogaStyle: applyCompositeMeasure(measurePyramid),
78
+ render(node, ctx) {
79
+ renderPyramidNode(node, ctx);
80
+ },
81
+ };
@@ -0,0 +1,3 @@
1
+ import type { NodeDefinition } from "../types.ts";
2
+ export declare const iconNodeDef: NodeDefinition;
3
+ //# sourceMappingURL=icon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/icon.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,eAAO,MAAM,WAAW,EAAE,cAiCzB,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { rasterizeIcon } from "../../icons/index.js";
2
+ import { omitYogaNode } from "../../toPositioned/toPositioned.js";
3
+ import { renderIconNode } from "../../renderPptx/nodes/icon.js";
4
+ export const iconNodeDef = {
5
+ type: "icon",
6
+ category: "leaf",
7
+ applyYogaStyle(node, yn) {
8
+ const n = node;
9
+ const size = n.size ?? 24;
10
+ yn.setMeasureFunc(() => ({ width: size, height: size }));
11
+ },
12
+ toPositioned(pom, absoluteX, absoluteY, layout, ctx) {
13
+ const n = pom;
14
+ const rasterSize = Math.max(Math.ceil(layout.width), Math.ceil(layout.height), n.size ?? 24);
15
+ const iconImageData = rasterizeIcon(n.name, rasterSize, n.color ?? "#000000", ctx.iconRasterCache);
16
+ return {
17
+ ...omitYogaNode(n),
18
+ x: absoluteX,
19
+ y: absoluteY,
20
+ w: layout.width,
21
+ h: layout.height,
22
+ iconImageData,
23
+ };
24
+ },
25
+ render(node, ctx) {
26
+ renderIconNode(node, ctx);
27
+ },
28
+ };
@@ -0,0 +1,3 @@
1
+ import type { NodeDefinition } from "../types.ts";
2
+ export declare const imageNodeDef: NodeDefinition;
3
+ //# sourceMappingURL=image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/image.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAQ,MAAM,aAAa,CAAC;AAOxD,eAAO,MAAM,YAAY,EAAE,cA+B1B,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { measureImage, getImageData } from "../../shared/measureImage.js";
2
+ import { renderImageNode } from "../../renderPptx/nodes/image.js";
3
+ import { omitYogaNode } from "../../toPositioned/toPositioned.js";
4
+ export const imageNodeDef = {
5
+ type: "image",
6
+ category: "leaf",
7
+ applyYogaStyle(node, yn, _yoga, ctx) {
8
+ const n = node;
9
+ const src = n.src;
10
+ yn.setMeasureFunc(() => {
11
+ const { widthPx, heightPx } = measureImage(src, ctx.imageSizeCache);
12
+ return { width: widthPx, height: heightPx };
13
+ });
14
+ },
15
+ toPositioned(pom, absoluteX, absoluteY, layout, ctx) {
16
+ const n = pom;
17
+ const imageData = getImageData(n.src, ctx.imageDataCache);
18
+ return {
19
+ ...omitYogaNode(n),
20
+ x: absoluteX,
21
+ y: absoluteY,
22
+ w: layout.width,
23
+ h: layout.height,
24
+ imageData,
25
+ };
26
+ },
27
+ render(node, ctx) {
28
+ renderImageNode(node, ctx);
29
+ },
30
+ collectImageSources(node) {
31
+ const n = node;
32
+ return [n.src];
33
+ },
34
+ };
@@ -0,0 +1,3 @@
1
+ import type { NodeDefinition } from "../types.ts";
2
+ export declare const layerNodeDef: NodeDefinition;
3
+ //# sourceMappingURL=layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/layer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,eAAO,MAAM,YAAY,EAAE,cAwD1B,CAAC"}