@hirokisakabe/pom 10.0.0 → 10.2.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.
- package/README.md +1 -1
- package/dist/autoFit/autoFit.js +55 -15
- package/dist/autoFit/autoFit.js.map +1 -1
- package/dist/autoFit/strategies/reduceFontSize.js.map +1 -1
- package/dist/buildContext.js +4 -4
- package/dist/buildContext.js.map +1 -1
- package/dist/buildPptx.d.ts +3 -2
- package/dist/buildPptx.d.ts.map +1 -1
- package/dist/buildPptx.js +1 -1
- package/dist/buildPptx.js.map +1 -1
- package/dist/calcYogaLayout/calcYogaLayout.js.map +1 -1
- package/dist/calcYogaLayout/fontLoader.d.ts +13 -0
- package/dist/calcYogaLayout/fontLoader.d.ts.map +1 -0
- package/dist/calcYogaLayout/fontLoader.js +70 -3
- package/dist/calcYogaLayout/fontLoader.js.map +1 -1
- package/dist/calcYogaLayout/measureText.d.ts.map +1 -1
- package/dist/calcYogaLayout/measureText.js +6 -6
- package/dist/calcYogaLayout/measureText.js.map +1 -1
- package/dist/diagnostics.d.ts +1 -1
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js.map +1 -1
- package/dist/extractSlideMastersAsPptx.d.ts.map +1 -1
- package/dist/extractThemeTokensFromPptx.d.ts +0 -1
- package/dist/extractThemeTokensFromPptx.d.ts.map +1 -1
- package/dist/icons/renderIcon.js +12 -10
- package/dist/icons/renderIcon.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/parseXml/coercionRules.js.map +1 -1
- package/dist/parseXml/parseXml.d.ts +0 -1
- package/dist/parseXml/parseXml.d.ts.map +1 -1
- package/dist/parseXml/parseXml.js.map +1 -1
- package/dist/parseXml/serializeXml.d.ts +0 -1
- package/dist/parseXml/serializeXml.d.ts.map +1 -1
- package/dist/parseXml/serializeXml.js.map +1 -1
- package/dist/registry/definitions/icon.js +1 -1
- package/dist/registry/definitions/list.js +1 -1
- package/dist/registry/definitions/list.js.map +1 -1
- package/dist/registry/definitions/shape.js +1 -1
- package/dist/registry/definitions/shape.js.map +1 -1
- package/dist/registry/definitions/text.js +1 -1
- package/dist/registry/definitions/text.js.map +1 -1
- package/dist/renderPptx/authoringContext.js +101 -0
- package/dist/renderPptx/authoringContext.js.map +1 -0
- package/dist/renderPptx/{pptxAuthoring.js → glimpseAdapter.js} +83 -152
- package/dist/renderPptx/glimpseAdapter.js.map +1 -0
- package/dist/renderPptx/nodes/arrow.js +49 -7
- package/dist/renderPptx/nodes/arrow.js.map +1 -1
- package/dist/renderPptx/nodes/chart.js +2 -2
- package/dist/renderPptx/nodes/chart.js.map +1 -1
- package/dist/renderPptx/nodes/icon.js +1 -1
- package/dist/renderPptx/nodes/icon.js.map +1 -1
- package/dist/renderPptx/nodes/list.js +11 -19
- package/dist/renderPptx/nodes/list.js.map +1 -1
- package/dist/renderPptx/nodes/shape.js +18 -19
- package/dist/renderPptx/nodes/shape.js.map +1 -1
- package/dist/renderPptx/nodes/table.js +12 -21
- package/dist/renderPptx/nodes/table.js.map +1 -1
- package/dist/renderPptx/nodes/text.js +16 -1
- package/dist/renderPptx/nodes/text.js.map +1 -1
- package/dist/renderPptx/renderPptx.js +93 -40
- package/dist/renderPptx/renderPptx.js.map +1 -1
- package/dist/renderPptx/utils/connectorSites.js +58 -0
- package/dist/renderPptx/utils/connectorSites.js.map +1 -0
- package/dist/renderPptx/utils/glimpsePicture.js +2 -4
- package/dist/renderPptx/utils/glimpsePicture.js.map +1 -1
- package/dist/renderPptx/utils/glimpseShape.js +3 -3
- package/dist/renderPptx/utils/glimpseShape.js.map +1 -1
- package/dist/renderPptx/utils/glimpseTextBox.js +3 -30
- package/dist/renderPptx/utils/glimpseTextBox.js.map +1 -1
- package/dist/renderPptx/utils/straightLine.js.map +1 -1
- package/dist/renderPptx/writablePptx.d.ts +1 -1
- package/dist/renderPptx/writablePptx.d.ts.map +1 -1
- package/dist/types.d.ts +0 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/package.json +10 -6
- package/dist/renderPptx/pptxAuthoring.js.map +0 -1
package/dist/diagnostics.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/diagnostics.d.ts
|
|
2
|
-
type DiagnosticCode = "IMAGE_MEASURE_FAILED" | "IMAGE_NOT_PREFETCHED" | "AUTOFIT_OVERFLOW" | "SCALE_BELOW_THRESHOLD" | "MASTER_PPTX_PARSE_FAILED" | "ARROW_REF_NOT_FOUND" | "DUPLICATE_NODE_ID" | "PER_SIDE_BORDER_WITH_RADIUS" | "NODE_OUT_OF_BOUNDS" | "NODE_OVERLAP";
|
|
2
|
+
type DiagnosticCode = "IMAGE_MEASURE_FAILED" | "IMAGE_NOT_PREFETCHED" | "AUTOFIT_OVERFLOW" | "SCALE_BELOW_THRESHOLD" | "MASTER_PPTX_PARSE_FAILED" | "ARROW_REF_NOT_FOUND" | "ARROW_REF_NOT_CONNECTABLE" | "DUPLICATE_NODE_ID" | "PER_SIDE_BORDER_WITH_RADIUS" | "NODE_OUT_OF_BOUNDS" | "NODE_OVERLAP";
|
|
3
3
|
interface Diagnostic {
|
|
4
4
|
code: DiagnosticCode;
|
|
5
5
|
message: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.d.ts","names":[],"sources":["../src/diagnostics.ts"],"mappings":";KAAY
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","names":[],"sources":["../src/diagnostics.ts"],"mappings":";KAAY;UAaK;EACf,MAAM;EACN;;cAWW,yBAAyB;WACR,aAAa;EAAb,YAAA,aAAa"}
|
package/dist/diagnostics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.js","names":[],"sources":["../src/diagnostics.ts"],"sourcesContent":["export type DiagnosticCode =\n | \"IMAGE_MEASURE_FAILED\"\n | \"IMAGE_NOT_PREFETCHED\"\n | \"AUTOFIT_OVERFLOW\"\n | \"SCALE_BELOW_THRESHOLD\"\n | \"MASTER_PPTX_PARSE_FAILED\"\n | \"ARROW_REF_NOT_FOUND\"\n | \"DUPLICATE_NODE_ID\"\n | \"PER_SIDE_BORDER_WITH_RADIUS\"\n | \"NODE_OUT_OF_BOUNDS\"\n | \"NODE_OVERLAP\";\n\nexport interface Diagnostic {\n code: DiagnosticCode;\n message: string;\n}\n\nexport class DiagnosticCollector {\n readonly items: Diagnostic[] = [];\n\n add(code: DiagnosticCode, message: string): void {\n this.items.push({ code, message });\n }\n}\n\nexport class DiagnosticsError extends Error {\n constructor(public readonly diagnostics: Diagnostic[]) {\n const summary = diagnostics\n .map((d) => `[${d.code}] ${d.message}`)\n .join(\"\\n\");\n super(`Build completed with diagnostics:\\n${summary}`);\n this.name = \"DiagnosticsError\";\n }\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"diagnostics.js","names":[],"sources":["../src/diagnostics.ts"],"sourcesContent":["export type DiagnosticCode =\n | \"IMAGE_MEASURE_FAILED\"\n | \"IMAGE_NOT_PREFETCHED\"\n | \"AUTOFIT_OVERFLOW\"\n | \"SCALE_BELOW_THRESHOLD\"\n | \"MASTER_PPTX_PARSE_FAILED\"\n | \"ARROW_REF_NOT_FOUND\"\n | \"ARROW_REF_NOT_CONNECTABLE\"\n | \"DUPLICATE_NODE_ID\"\n | \"PER_SIDE_BORDER_WITH_RADIUS\"\n | \"NODE_OUT_OF_BOUNDS\"\n | \"NODE_OVERLAP\";\n\nexport interface Diagnostic {\n code: DiagnosticCode;\n message: string;\n}\n\nexport class DiagnosticCollector {\n readonly items: Diagnostic[] = [];\n\n add(code: DiagnosticCode, message: string): void {\n this.items.push({ code, message });\n }\n}\n\nexport class DiagnosticsError extends Error {\n constructor(public readonly diagnostics: Diagnostic[]) {\n const summary = diagnostics\n .map((d) => `[${d.code}] ${d.message}`)\n .join(\"\\n\");\n super(`Build completed with diagnostics:\\n${summary}`);\n this.name = \"DiagnosticsError\";\n }\n}\n"],"mappings":";AAkBA,IAAa,sBAAb,MAAiC;CAC/B,QAA+B,CAAC;CAEhC,IAAI,MAAsB,SAAuB;EAC/C,KAAK,MAAM,KAAK;GAAE;GAAM;EAAQ,CAAC;CACnC;AACF;AAEA,IAAa,mBAAb,cAAsC,MAAM;CACd;CAA5B,YAAY,aAA2C;EACrD,MAAM,UAAU,YACb,KAAK,MAAM,IAAI,EAAE,KAAK,IAAI,EAAE,SAAS,CAAC,CACtC,KAAK,IAAI;EACZ,MAAM,sCAAsC,SAAS;EAJ3B,KAAA,cAAA;EAK1B,KAAK,OAAO;CACd;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractSlideMastersAsPptx.d.ts","names":[],"sources":["../src/extractSlideMastersAsPptx.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"extractSlideMastersAsPptx.d.ts","names":[],"sources":["../src/extractSlideMastersAsPptx.ts"],"mappings":";;;;;;;;;iBAyMsB,0BACpB,YAAY,cAAc,aACzB,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractThemeTokensFromPptx.d.ts","names":[],"sources":["../src/extractThemeTokensFromPptx.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"extractThemeTokensFromPptx.d.ts","names":[],"sources":["../src/extractThemeTokensFromPptx.ts"],"mappings":";;;;;;;;iBA0MgB,2BACd,YAAY,cAAc,aACzB,QAAQ"}
|
package/dist/icons/renderIcon.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import { ICON_DATA } from "./iconData.js";
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
|
-
import { existsSync } from "node:fs";
|
|
4
|
-
import { readFile } from "node:fs/promises";
|
|
5
|
-
import { dirname, join } from "node:path";
|
|
6
|
-
import { fileURLToPath } from "node:url";
|
|
7
2
|
//#region src/icons/renderIcon.ts
|
|
8
3
|
const RESVG_PKG = ["@resvg", "resvg-wasm"].join("/");
|
|
9
4
|
let resvgModule;
|
|
10
5
|
let wasmInitPromise;
|
|
11
|
-
function getNodeRequire() {
|
|
6
|
+
function getNodeRequire(createRequire) {
|
|
12
7
|
return new Function("url", "createRequire", "return createRequire(url)")(import.meta.url, createRequire);
|
|
13
8
|
}
|
|
14
9
|
/**
|
|
@@ -16,10 +11,15 @@ function getNodeRequire() {
|
|
|
16
11
|
* バンドル環境(esbuild)では同ディレクトリの index_bg.wasm を参照し、
|
|
17
12
|
* 非バンドル環境では createRequire で node_modules から解決する。
|
|
18
13
|
*/
|
|
19
|
-
function resolveWasmPath() {
|
|
14
|
+
async function resolveWasmPath(require) {
|
|
15
|
+
const [{ existsSync }, { dirname, join }, { fileURLToPath }] = await Promise.all([
|
|
16
|
+
import("node:fs"),
|
|
17
|
+
import("node:path"),
|
|
18
|
+
import("node:url")
|
|
19
|
+
]);
|
|
20
20
|
const localPath = join(dirname(fileURLToPath(import.meta.url)), "index_bg.wasm");
|
|
21
21
|
if (existsSync(localPath)) return localPath;
|
|
22
|
-
return
|
|
22
|
+
return require.resolve(`${RESVG_PKG}/index_bg.wasm`);
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* WASM モジュールを初期化し、Resvg クラスを返す。
|
|
@@ -27,8 +27,10 @@ function resolveWasmPath() {
|
|
|
27
27
|
*/
|
|
28
28
|
function ensureWasmInitialized() {
|
|
29
29
|
if (!wasmInitPromise) wasmInitPromise = (async () => {
|
|
30
|
-
const
|
|
31
|
-
const
|
|
30
|
+
const [{ createRequire }, { readFile }] = await Promise.all([import("node:module"), import("node:fs/promises")]);
|
|
31
|
+
const require = getNodeRequire(createRequire);
|
|
32
|
+
const mod = require(RESVG_PKG);
|
|
33
|
+
const wasmBuffer = await readFile(await resolveWasmPath(require));
|
|
32
34
|
await mod.initWasm(wasmBuffer);
|
|
33
35
|
resvgModule = mod;
|
|
34
36
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderIcon.js","names":[],"sources":["../../src/icons/renderIcon.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"renderIcon.js","names":[],"sources":["../../src/icons/renderIcon.ts"],"sourcesContent":["import { ICON_DATA } from \"./iconData.ts\";\n\n// @resvg/resvg-wasm を遅延ロードする。\n// バンドラ(webpack / Turbopack)のスタティック解析が require / require.resolve を\n// 追跡してエラーにするのを避けるため、Function コンストラクタで Node.js の require を\n// 取得し、モジュール名は文字列結合で構築する。\n// Turbopack が動的 require / import を Webpack 同等に解析できるようになれば\n// 隠蔽自体が不要になり、apps/website 側の outputFileTracingIncludes 設定もまとめて\n// 撤去できる。\n// 上流 issue: https://github.com/vercel/next.js/issues/85238\ntype ResvgWasm = typeof import(\"@resvg/resvg-wasm\");\nconst RESVG_PKG = [\"@resvg\", \"resvg-wasm\"].join(\"/\");\nlet resvgModule: ResvgWasm | undefined;\nlet wasmInitPromise: Promise<void> | undefined;\n\n// Function コンストラクタを使って require を取得することでバンドラの静的解析から\n// 完全に隠蔽する。実行時は createRequire で生成した require が利用される。\nfunction getNodeRequire(\n createRequire: typeof import(\"node:module\").createRequire,\n): NodeJS.Require {\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n const factory = new Function(\n \"url\",\n \"createRequire\",\n \"return createRequire(url)\",\n ) as (\n url: string,\n createRequire: typeof import(\"node:module\").createRequire,\n ) => NodeJS.Require;\n return factory(import.meta.url, createRequire);\n}\n\n/**\n * WASM バイナリのパスを解決する。\n * バンドル環境(esbuild)では同ディレクトリの index_bg.wasm を参照し、\n * 非バンドル環境では createRequire で node_modules から解決する。\n */\nasync function resolveWasmPath(require: NodeJS.Require): Promise<string> {\n const [{ existsSync }, { dirname, join }, { fileURLToPath }] =\n await Promise.all([\n import(\"node:fs\"),\n import(\"node:path\"),\n import(\"node:url\"),\n ]);\n const dir = dirname(fileURLToPath(import.meta.url));\n const localPath = join(dir, \"index_bg.wasm\");\n if (existsSync(localPath)) return localPath;\n return require.resolve(`${RESVG_PKG}/index_bg.wasm`);\n}\n\n/**\n * WASM モジュールを初期化し、Resvg クラスを返す。\n * 並行呼び出しでも安全(Promise をキャッシュ)。\n */\nfunction ensureWasmInitialized(): Promise<void> {\n if (!wasmInitPromise) {\n wasmInitPromise = (async () => {\n const [{ createRequire }, { readFile }] = await Promise.all([\n import(\"node:module\"),\n import(\"node:fs/promises\"),\n ]);\n const require = getNodeRequire(createRequire);\n const mod = require(RESVG_PKG) as ResvgWasm;\n const wasmPath = await resolveWasmPath(require);\n const wasmBuffer = await readFile(wasmPath);\n await mod.initWasm(wasmBuffer);\n resvgModule = mod;\n })();\n }\n return wasmInitPromise;\n}\n\nfunction getResvg() {\n if (!resvgModule) throw new Error(\"WASM not initialized\");\n return resvgModule.Resvg;\n}\n\nfunction buildIconSvg(name: string, size: number, color: string): string {\n const pathData = ICON_DATA[name];\n if (!pathData) {\n throw new Error(`Unknown icon name: \"${name}\"`);\n }\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${color}\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${pathData}</svg>`;\n}\n\nexport async function rasterizeIcon(\n name: string,\n size: number,\n color: string,\n cache: Map<string, string>,\n): Promise<string> {\n const key = `${name}|${size}|${color}`;\n const cached = cache.get(key);\n if (cached) return cached;\n\n await ensureWasmInitialized();\n const Resvg = getResvg();\n const svg = buildIconSvg(name, size, color);\n const resvg = new Resvg(svg, { fitTo: { mode: \"width\", value: size } });\n const pngData = resvg.render();\n const pngBuffer = pngData.asPng();\n const result = `image/png;base64,${Buffer.from(pngBuffer).toString(\"base64\")}`;\n cache.set(key, result);\n return result;\n}\n\n/**\n * インライン SVG 文字列を指定サイズでラスタライズし、base64 PNG を返す。\n * color が指定された場合、SVG ルートに stroke / fill 属性を設定する。\n */\nexport async function rasterizeSvgContent(\n svgContent: string,\n width: number,\n color: string | undefined,\n cache: Map<string, string>,\n height?: number,\n): Promise<string> {\n const h = height ?? width;\n const key = `svg:${svgContent}|${width}|${h}|${color ?? \"\"}`;\n const cached = cache.get(key);\n if (cached) return cached;\n\n // SVG に xmlns / width / height を設定し、color があれば stroke / fill を注入\n let svg = svgContent;\n\n // xmlns が無ければ追加\n if (!svg.includes(\"xmlns\")) {\n svg = svg.replace(\"<svg\", '<svg xmlns=\"http://www.w3.org/2000/svg\"');\n }\n\n // width / height を上書き\n svg = svg.replace(/<svg([^>]*)>/, (match, attrs: string) => {\n let newAttrs = attrs\n .replace(/\\bwidth\\s*=\\s*\"[^\"]*\"/g, \"\")\n .replace(/\\bheight\\s*=\\s*\"[^\"]*\"/g, \"\");\n newAttrs += ` width=\"${width}\" height=\"${h}\"`;\n\n // color 指定時は stroke / fill を設定(プリセットアイコンとの一貫性)\n if (color) {\n if (!attrs.includes(\"stroke=\")) {\n newAttrs += ` stroke=\"${color}\"`;\n }\n if (!attrs.includes(\"fill=\")) {\n newAttrs += ` fill=\"none\"`;\n }\n }\n\n return `<svg${newAttrs}>`;\n });\n\n await ensureWasmInitialized();\n const Resvg = getResvg();\n const resvg = new Resvg(svg, { fitTo: { mode: \"width\", value: width } });\n const pngData = resvg.render();\n const pngBuffer = pngData.asPng();\n const result = `image/png;base64,${Buffer.from(pngBuffer).toString(\"base64\")}`;\n cache.set(key, result);\n return result;\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { FALLBACK_THEME_TOKENS, MasterImageObject, MasterLineObject, MasterObject, MasterRectObject, MasterTextObject, POMNode, SlideMasterBackground, SlideMasterMargin, SlideMasterOptions, SlideNumberOptions, ThemeTokens } from "./types.js";
|
|
2
2
|
import { ParseXmlError, parseXml } from "./parseXml/parseXml.js";
|
|
3
3
|
import { serializeXml } from "./parseXml/serializeXml.js";
|
|
4
|
+
import { FontInput } from "./calcYogaLayout/fontLoader.js";
|
|
4
5
|
import { TextMeasurementMode } from "./calcYogaLayout/measureText.js";
|
|
5
6
|
import { Diagnostic, DiagnosticCode, DiagnosticsError } from "./diagnostics.js";
|
|
6
7
|
import { PptxOutputType, PptxWriteFileOptions, PptxWriteOptions, WritablePptx } from "./renderPptx/writablePptx.js";
|
|
7
8
|
import { BuildPptxResult, buildPptx } from "./buildPptx.js";
|
|
8
9
|
import { extractThemeTokensFromPptx } from "./extractThemeTokensFromPptx.js";
|
|
9
10
|
import { extractSlideMastersAsPptx } from "./extractSlideMastersAsPptx.js";
|
|
10
|
-
export { type BuildPptxResult, type Diagnostic, type DiagnosticCode, DiagnosticsError, FALLBACK_THEME_TOKENS, type MasterImageObject, type MasterLineObject, type MasterObject, type MasterRectObject, type MasterTextObject, type POMNode, ParseXmlError, type PptxOutputType, type PptxWriteFileOptions, type PptxWriteOptions, type SlideMasterBackground, type SlideMasterMargin, type SlideMasterOptions, type SlideNumberOptions, type TextMeasurementMode, type ThemeTokens, type WritablePptx, buildPptx, extractSlideMastersAsPptx, extractThemeTokensFromPptx, parseXml, serializeXml };
|
|
11
|
+
export { type BuildPptxResult, type Diagnostic, type DiagnosticCode, DiagnosticsError, FALLBACK_THEME_TOKENS, type FontInput, type MasterImageObject, type MasterLineObject, type MasterObject, type MasterRectObject, type MasterTextObject, type POMNode, ParseXmlError, type PptxOutputType, type PptxWriteFileOptions, type PptxWriteOptions, type SlideMasterBackground, type SlideMasterMargin, type SlideMasterOptions, type SlideNumberOptions, type TextMeasurementMode, type ThemeTokens, type WritablePptx, buildPptx, extractSlideMastersAsPptx, extractThemeTokensFromPptx, parseXml, serializeXml };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coercionRules.js","names":[],"sources":["../../src/parseXml/coercionRules.ts"],"sourcesContent":["/**\n * 明示的な型変換ルール定義\n *\n * Zod の内部構造(_def)に依存せず、XML 属性値の文字列→適切な型への変換ルールを\n * 静的に定義する。各ノードタイプ・子要素タイプごとに変換テーブルを持つ。\n */\n\n// ===== CoercionRule 型定義 =====\nexport type CoercionRule =\n | \"number\"\n | \"boolean\"\n | \"string\" // string, enum を含む\n | \"json\" // array, object, record, tuple → JSON.parse\n | { type: \"literal\"; value: string | number | boolean }\n | { type: \"union\"; options: CoercionRule[] }\n | { type: \"object\"; shape: Record<string, CoercionRule> };\n\n// ===== 変換関数 =====\n\nexport function coerceWithRule(\n value: string,\n rule: CoercionRule,\n): { value: unknown; error: string | null } {\n if (rule === \"number\") {\n if (value === \"\") {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to number`,\n };\n }\n const num = Number(value);\n if (isNaN(num)) {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to number`,\n };\n }\n return { value: num, error: null };\n }\n if (rule === \"boolean\") {\n if (value !== \"true\" && value !== \"false\") {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to boolean (expected \"true\" or \"false\")`,\n };\n }\n return { value: value === \"true\", error: null };\n }\n if (rule === \"string\") {\n return { value, error: null };\n }\n if (rule === \"json\") {\n try {\n return { value: JSON.parse(value), error: null };\n } catch {\n return {\n value: undefined,\n error: `Cannot parse JSON value: \"${value}\"`,\n };\n }\n }\n // オブジェクト型のルール\n if (rule.type === \"literal\") {\n return { value: rule.value, error: null };\n }\n if (rule.type === \"union\") {\n return { value: coerceUnionWithRules(value, rule.options), error: null };\n }\n if (rule.type === \"object\") {\n try {\n return { value: JSON.parse(value), error: null };\n } catch {\n return {\n value: undefined,\n error: `Cannot parse JSON value: \"${value}\"`,\n };\n }\n }\n return { value: coerceFallback(value), error: null };\n}\n\nexport function coerceUnionWithRules(\n value: string,\n options: CoercionRule[],\n): unknown {\n // boolean を試行\n if ((value === \"true\" || value === \"false\") && options.includes(\"boolean\")) {\n return value === \"true\";\n }\n\n // number を試行\n if (options.includes(\"number\")) {\n const num = Number(value);\n if (!isNaN(num) && value !== \"\") {\n return num;\n }\n }\n\n // literal を試行\n for (const opt of options) {\n if (typeof opt === \"object\" && opt.type === \"literal\") {\n if (`${opt.value as string | number}` === value) return opt.value;\n }\n }\n\n // object/json を試行(JSON パース)\n if (\n options.some(\n (opt) =>\n opt === \"json\" || (typeof opt === \"object\" && opt.type === \"object\"),\n )\n ) {\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch {\n /* ignore */\n }\n }\n }\n\n // string にフォールバック\n return value;\n}\n\nexport function coerceFallback(value: string): unknown {\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n const num = Number(value);\n if (value !== \"\" && !isNaN(num)) return num;\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch {\n /* ignore */\n }\n }\n return value;\n}\n\n/**\n * CoercionRule からオブジェクト型の shape を取得する。\n * dot notation の展開で使用。\n */\nexport function getObjectShapeFromRule(\n rule: CoercionRule,\n): Record<string, CoercionRule> | undefined {\n if (typeof rule === \"object\" && rule.type === \"object\") {\n return rule.shape;\n }\n if (typeof rule === \"object\" && rule.type === \"union\") {\n const objectOpt = rule.options.find(\n (opt): opt is { type: \"object\"; shape: Record<string, CoercionRule> } =>\n typeof opt === \"object\" && opt.type === \"object\",\n );\n return objectOpt?.shape;\n }\n return undefined;\n}\n\n/**\n * boolean と object の union かどうかを判定する。\n * endArrow=\"true\" と endArrow.type=\"triangle\" の共存を許可するために使用。\n */\nexport function isBooleanObjectUnionRule(rule: CoercionRule): boolean {\n if (typeof rule === \"string\") return false;\n if (rule.type !== \"union\") return false;\n const hasBoolean = rule.options.includes(\"boolean\");\n const hasObject = rule.options.some(\n (opt) => typeof opt === \"object\" && opt.type === \"object\",\n );\n return hasBoolean && hasObject;\n}\n\ntype ResolvedMixedNotationShorthand =\n | { mode: \"merge\"; value: Record<string, unknown> }\n | { mode: \"ignore\" }\n | { mode: \"conflict\" };\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isDirectionalBoxShape(shape: Record<string, CoercionRule>): boolean {\n const keys = Object.keys(shape).sort();\n return (\n keys.length === 4 &&\n keys[0] === \"bottom\" &&\n keys[1] === \"left\" &&\n keys[2] === \"right\" &&\n keys[3] === \"top\"\n );\n}\n\n/**\n * 同一属性で shorthand と dot notation を併用したときに、\n * shorthand 側をどのように扱うかを解決する。\n *\n * - merge: shorthand をオブジェクト化して dot notation 側で上書き\n * - ignore: boolean shorthand を無視して dot notation を優先\n * - conflict: 併用不可(従来どおりエラー)\n */\nexport function resolveMixedNotationShorthand(\n value: string,\n rule: CoercionRule,\n): ResolvedMixedNotationShorthand {\n const objectShape = getObjectShapeFromRule(rule);\n if (!objectShape) return { mode: \"conflict\" };\n\n if (\n isBooleanObjectUnionRule(rule) &&\n (value === \"true\" || value === \"false\")\n ) {\n return { mode: \"ignore\" };\n }\n\n const coerced = coerceWithRule(value, rule);\n if (coerced.error !== null) return { mode: \"conflict\" };\n\n if (isPlainObject(coerced.value)) {\n return { mode: \"merge\", value: coerced.value };\n }\n\n if (typeof coerced.value === \"number\" && isDirectionalBoxShape(objectShape)) {\n return {\n mode: \"merge\",\n value: {\n top: coerced.value,\n right: coerced.value,\n bottom: coerced.value,\n left: coerced.value,\n },\n };\n }\n\n return { mode: \"conflict\" };\n}\n\n// ===== 共通変換ルール =====\n\nconst LENGTH_RULE: CoercionRule = {\n type: \"union\",\n options: [\"number\", { type: \"literal\", value: \"max\" }, \"string\"],\n};\n\nconst PADDING_RULE: CoercionRule = {\n type: \"union\",\n options: [\n \"number\",\n {\n type: \"object\",\n shape: {\n top: \"number\",\n right: \"number\",\n bottom: \"number\",\n left: \"number\",\n },\n },\n ],\n};\n\nconst BORDER_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\", dashType: \"string\" },\n};\n\nconst FILL_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", transparency: \"number\" },\n};\n\nconst SHADOW_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n type: \"string\",\n opacity: \"number\",\n blur: \"number\",\n angle: \"number\",\n offset: \"number\",\n color: \"string\",\n },\n};\n\nconst UNDERLINE_RULE: CoercionRule = {\n type: \"union\",\n options: [\n \"boolean\",\n { type: \"object\", shape: { style: \"string\", color: \"string\" } },\n ],\n};\n\nconst TEXT_GLOW_RULE: CoercionRule = {\n type: \"object\",\n shape: { size: \"number\", opacity: \"number\", color: \"string\" },\n};\n\nconst TEXT_OUTLINE_RULE: CoercionRule = {\n type: \"object\",\n shape: { size: \"number\", color: \"string\" },\n};\n\nconst LINE_ARROW_RULE: CoercionRule = {\n type: \"union\",\n options: [\"boolean\", { type: \"object\", shape: { type: \"string\" } }],\n};\n\nconst BACKGROUND_IMAGE_RULE: CoercionRule = {\n type: \"object\",\n shape: { src: \"string\", sizing: \"string\" },\n};\n\nconst TREE_CONNECTOR_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\" },\n};\n\nconst FLOW_CONNECTOR_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n color: \"string\",\n width: \"number\",\n arrowType: \"string\",\n labelColor: \"string\",\n },\n};\n\nconst IMAGE_SIZING_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n type: \"string\",\n w: \"number\",\n h: \"number\",\n x: \"number\",\n y: \"number\",\n },\n};\n\n// ===== Base node 属性 =====\nconst BASE_RULES: Record<string, CoercionRule> = {\n id: \"string\",\n w: LENGTH_RULE,\n h: LENGTH_RULE,\n grow: \"number\",\n minW: \"number\",\n maxW: \"number\",\n minH: \"number\",\n maxH: \"number\",\n padding: PADDING_RULE,\n margin: PADDING_RULE,\n backgroundColor: \"string\",\n backgroundGradient: \"string\",\n backgroundImage: BACKGROUND_IMAGE_RULE,\n border: BORDER_STYLE_RULE,\n borderTop: BORDER_STYLE_RULE,\n borderRight: BORDER_STYLE_RULE,\n borderBottom: BORDER_STYLE_RULE,\n borderLeft: BORDER_STYLE_RULE,\n borderRadius: \"number\",\n opacity: \"number\",\n zIndex: \"number\",\n position: \"string\",\n top: \"number\",\n right: \"number\",\n bottom: \"number\",\n left: \"number\",\n alignSelf: \"string\",\n shadow: SHADOW_STYLE_RULE,\n};\n\n// テキスト系の共通属性\nconst TEXT_STYLE_RULES: Record<string, CoercionRule> = {\n fontSize: \"number\",\n color: \"string\",\n textAlign: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n subscript: \"boolean\",\n superscript: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n lineHeight: \"number\",\n};\n\n// ===== ノードタイプ別の変換ルールマップ =====\nexport const NODE_COERCION_MAP: Record<string, Record<string, CoercionRule>> = {\n text: {\n ...BASE_RULES,\n text: \"string\",\n rotate: \"number\",\n ...TEXT_STYLE_RULES,\n textGradient: \"string\",\n letterSpacing: \"number\",\n glow: TEXT_GLOW_RULE,\n outline: TEXT_OUTLINE_RULE,\n },\n ul: {\n ...BASE_RULES,\n items: \"json\",\n ...TEXT_STYLE_RULES,\n },\n ol: {\n ...BASE_RULES,\n items: \"json\",\n ...TEXT_STYLE_RULES,\n numberType: \"string\",\n numberStartAt: \"number\",\n },\n image: {\n ...BASE_RULES,\n src: \"string\",\n sizing: IMAGE_SIZING_RULE,\n rotate: \"number\",\n },\n icon: {\n ...BASE_RULES,\n name: \"string\",\n size: \"number\",\n color: \"string\",\n variant: \"string\",\n bgColor: \"string\",\n glow: TEXT_GLOW_RULE,\n outline: TEXT_OUTLINE_RULE,\n rotate: \"number\",\n },\n svg: {\n ...BASE_RULES,\n color: \"string\",\n },\n table: {\n ...BASE_RULES,\n columns: \"json\",\n rows: \"json\",\n defaultRowHeight: \"number\",\n cellBorder: BORDER_STYLE_RULE,\n },\n shape: {\n ...BASE_RULES,\n shapeType: \"string\",\n text: \"string\",\n rotate: \"number\",\n fill: FILL_STYLE_RULE,\n line: BORDER_STYLE_RULE,\n glow: TEXT_GLOW_RULE,\n outline: TEXT_OUTLINE_RULE,\n ...TEXT_STYLE_RULES,\n },\n chart: {\n ...BASE_RULES,\n chartType: \"string\",\n data: \"json\",\n showLegend: \"boolean\",\n showTitle: \"boolean\",\n title: \"string\",\n chartColors: \"json\",\n radarStyle: \"string\",\n sparkline: \"boolean\",\n },\n timeline: {\n ...BASE_RULES,\n direction: \"string\",\n items: \"json\",\n dateColor: \"string\",\n titleColor: \"string\",\n descriptionColor: \"string\",\n connectorColor: \"string\",\n connectorGradient: \"string\",\n useColorForDate: \"boolean\",\n fontFamily: \"string\",\n },\n matrix: {\n ...BASE_RULES,\n axes: \"json\",\n quadrants: \"json\",\n items: \"json\",\n axisLabelColor: \"string\",\n quadrantLabelColor: \"string\",\n itemLabelColor: \"string\",\n },\n tree: {\n ...BASE_RULES,\n layout: \"string\",\n nodeShape: \"string\",\n data: \"json\",\n textColor: \"string\",\n connectorStyle: TREE_CONNECTOR_STYLE_RULE,\n nodeWidth: \"number\",\n nodeHeight: \"number\",\n levelGap: \"number\",\n siblingGap: \"number\",\n },\n flow: {\n ...BASE_RULES,\n direction: \"string\",\n nodes: \"json\",\n connections: \"json\",\n connectorStyle: FLOW_CONNECTOR_STYLE_RULE,\n nodeWidth: \"number\",\n nodeHeight: \"number\",\n nodeGap: \"number\",\n },\n processArrow: {\n ...BASE_RULES,\n direction: \"string\",\n steps: \"json\",\n itemWidth: \"number\",\n itemHeight: \"number\",\n gap: \"number\",\n fontSize: \"number\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n },\n pyramid: {\n ...BASE_RULES,\n direction: \"string\",\n levels: \"json\",\n fontSize: \"number\",\n bold: \"boolean\",\n fontFamily: \"string\",\n },\n line: {\n ...BASE_RULES,\n x1: \"number\",\n y1: \"number\",\n x2: \"number\",\n y2: \"number\",\n color: \"string\",\n lineWidth: \"number\",\n dashType: \"string\",\n beginArrow: LINE_ARROW_RULE,\n endArrow: LINE_ARROW_RULE,\n },\n arrow: {\n ...BASE_RULES,\n from: \"string\",\n to: \"string\",\n color: \"string\",\n lineWidth: \"number\",\n dashType: \"string\",\n beginArrow: LINE_ARROW_RULE,\n endArrow: LINE_ARROW_RULE,\n },\n // コンテナノード\n vstack: {\n ...BASE_RULES,\n gap: \"number\",\n alignItems: \"string\",\n justifyContent: \"string\",\n flexWrap: \"string\",\n },\n hstack: {\n ...BASE_RULES,\n gap: \"number\",\n alignItems: \"string\",\n justifyContent: \"string\",\n flexWrap: \"string\",\n },\n layer: {\n ...BASE_RULES,\n },\n};\n\n// ===== 子要素の変換ルールマップ =====\nexport const CHILD_ELEMENT_COERCION_MAP: Record<\n string,\n Record<string, CoercionRule>\n> = {\n ProcessArrowStep: {\n label: \"string\",\n color: \"string\",\n textColor: \"string\",\n },\n PyramidLevel: {\n label: \"string\",\n color: \"string\",\n textColor: \"string\",\n },\n TimelineItem: {\n date: \"string\",\n title: \"string\",\n description: \"string\",\n color: \"string\",\n dateColor: \"string\",\n },\n MatrixAxes: {\n x: \"string\",\n y: \"string\",\n },\n MatrixQuadrants: {\n topLeft: \"string\",\n topRight: \"string\",\n bottomLeft: \"string\",\n bottomRight: \"string\",\n },\n MatrixItem: {\n label: \"string\",\n x: \"number\",\n y: \"number\",\n color: \"string\",\n textColor: \"string\",\n },\n FlowNode: {\n id: \"string\",\n shape: \"string\",\n text: \"string\",\n color: \"string\",\n textColor: \"string\",\n width: \"number\",\n height: \"number\",\n },\n FlowConnection: {\n from: \"string\",\n to: \"string\",\n label: \"string\",\n color: \"string\",\n labelColor: \"string\",\n },\n Col: {\n width: \"number\",\n },\n Td: {\n text: \"string\",\n fontSize: \"number\",\n color: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n subscript: \"boolean\",\n superscript: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n textAlign: \"string\",\n backgroundColor: \"string\",\n colspan: \"number\",\n rowspan: \"number\",\n },\n Li: {\n text: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n subscript: \"boolean\",\n superscript: \"boolean\",\n highlight: \"string\",\n color: \"string\",\n fontSize: \"number\",\n fontFamily: \"string\",\n },\n B: {},\n I: {},\n Span: {\n color: \"string\",\n fontFamily: \"string\",\n fontSize: \"number\",\n letterSpacing: \"number\",\n },\n};\n"],"mappings":";AAmBA,SAAgB,eACd,OACA,MAC0C;CAC1C,IAAI,SAAS,UAAU;EACrB,IAAI,UAAU,IACZ,OAAO;GACL,OAAO,KAAA;GACP,OAAO,mBAAmB,MAAM;EAClC;EAEF,MAAM,MAAM,OAAO,KAAK;EACxB,IAAI,MAAM,GAAG,GACX,OAAO;GACL,OAAO,KAAA;GACP,OAAO,mBAAmB,MAAM;EAClC;EAEF,OAAO;GAAE,OAAO;GAAK,OAAO;EAAK;CACnC;CACA,IAAI,SAAS,WAAW;EACtB,IAAI,UAAU,UAAU,UAAU,SAChC,OAAO;GACL,OAAO,KAAA;GACP,OAAO,mBAAmB,MAAM;EAClC;EAEF,OAAO;GAAE,OAAO,UAAU;GAAQ,OAAO;EAAK;CAChD;CACA,IAAI,SAAS,UACX,OAAO;EAAE;EAAO,OAAO;CAAK;CAE9B,IAAI,SAAS,QACX,IAAI;EACF,OAAO;GAAE,OAAO,KAAK,MAAM,KAAK;GAAG,OAAO;EAAK;CACjD,QAAQ;EACN,OAAO;GACL,OAAO,KAAA;GACP,OAAO,6BAA6B,MAAM;EAC5C;CACF;CAGF,IAAI,KAAK,SAAS,WAChB,OAAO;EAAE,OAAO,KAAK;EAAO,OAAO;CAAK;CAE1C,IAAI,KAAK,SAAS,SAChB,OAAO;EAAE,OAAO,qBAAqB,OAAO,KAAK,OAAO;EAAG,OAAO;CAAK;CAEzE,IAAI,KAAK,SAAS,UAChB,IAAI;EACF,OAAO;GAAE,OAAO,KAAK,MAAM,KAAK;GAAG,OAAO;EAAK;CACjD,QAAQ;EACN,OAAO;GACL,OAAO,KAAA;GACP,OAAO,6BAA6B,MAAM;EAC5C;CACF;CAEF,OAAO;EAAE,OAAO,eAAe,KAAK;EAAG,OAAO;CAAK;AACrD;AAEA,SAAgB,qBACd,OACA,SACS;CAET,KAAK,UAAU,UAAU,UAAU,YAAY,QAAQ,SAAS,SAAS,GACvE,OAAO,UAAU;CAInB,IAAI,QAAQ,SAAS,QAAQ,GAAG;EAC9B,MAAM,MAAM,OAAO,KAAK;EACxB,IAAI,CAAC,MAAM,GAAG,KAAK,UAAU,IAC3B,OAAO;CAEX;CAGA,KAAK,MAAM,OAAO,SAChB,IAAI,OAAO,QAAQ,YAAY,IAAI,SAAS;MACtC,GAAG,IAAI,YAA+B,OAAO,OAAO,IAAI;CAAA;CAKhE,IACE,QAAQ,MACL,QACC,QAAQ,UAAW,OAAO,QAAQ,YAAY,IAAI,SAAS,QAC/D;MAEI,MAAM,WAAW,GAAG,KAAK,MAAM,WAAW,GAAG,GAC/C,IAAI;GACF,OAAO,KAAK,MAAM,KAAK;EACzB,QAAQ,CAER;;CAKJ,OAAO;AACT;AAEA,SAAgB,eAAe,OAAwB;CACrD,IAAI,UAAU,QAAQ,OAAO;CAC7B,IAAI,UAAU,SAAS,OAAO;CAC9B,MAAM,MAAM,OAAO,KAAK;CACxB,IAAI,UAAU,MAAM,CAAC,MAAM,GAAG,GAAG,OAAO;CACxC,IAAI,MAAM,WAAW,GAAG,KAAK,MAAM,WAAW,GAAG,GAC/C,IAAI;EACF,OAAO,KAAK,MAAM,KAAK;CACzB,QAAQ,CAER;CAEF,OAAO;AACT;;;;;AAMA,SAAgB,uBACd,MAC0C;CAC1C,IAAI,OAAO,SAAS,YAAY,KAAK,SAAS,UAC5C,OAAO,KAAK;CAEd,IAAI,OAAO,SAAS,YAAY,KAAK,SAAS,SAK5C,OAJkB,KAAK,QAAQ,MAC5B,QACC,OAAO,QAAQ,YAAY,IAAI,SAAS,QAE7B,CAAC,EAAE;AAGtB;;;;;AAMA,SAAgB,yBAAyB,MAA6B;CACpE,IAAI,OAAO,SAAS,UAAU,OAAO;CACrC,IAAI,KAAK,SAAS,SAAS,OAAO;CAClC,MAAM,aAAa,KAAK,QAAQ,SAAS,SAAS;CAClD,MAAM,YAAY,KAAK,QAAQ,MAC5B,QAAQ,OAAO,QAAQ,YAAY,IAAI,SAAS,QACnD;CACA,OAAO,cAAc;AACvB;AAOA,SAAS,cAAc,OAAkD;CACvE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,sBAAsB,OAA8C;CAC3E,MAAM,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,KAAK;CACrC,OACE,KAAK,WAAW,KAChB,KAAK,OAAO,YACZ,KAAK,OAAO,UACZ,KAAK,OAAO,WACZ,KAAK,OAAO;AAEhB;;;;;;;;;AAUA,SAAgB,8BACd,OACA,MACgC;CAChC,MAAM,cAAc,uBAAuB,IAAI;CAC/C,IAAI,CAAC,aAAa,OAAO,EAAE,MAAM,WAAW;CAE5C,IACE,yBAAyB,IAAI,MAC5B,UAAU,UAAU,UAAU,UAE/B,OAAO,EAAE,MAAM,SAAS;CAG1B,MAAM,UAAU,eAAe,OAAO,IAAI;CAC1C,IAAI,QAAQ,UAAU,MAAM,OAAO,EAAE,MAAM,WAAW;CAEtD,IAAI,cAAc,QAAQ,KAAK,GAC7B,OAAO;EAAE,MAAM;EAAS,OAAO,QAAQ;CAAM;CAG/C,IAAI,OAAO,QAAQ,UAAU,YAAY,sBAAsB,WAAW,GACxE,OAAO;EACL,MAAM;EACN,OAAO;GACL,KAAK,QAAQ;GACb,OAAO,QAAQ;GACf,QAAQ,QAAQ;GAChB,MAAM,QAAQ;EAChB;CACF;CAGF,OAAO,EAAE,MAAM,WAAW;AAC5B;AAIA,MAAM,cAA4B;CAChC,MAAM;CACN,SAAS;EAAC;EAAU;GAAE,MAAM;GAAW,OAAO;EAAM;EAAG;CAAQ;AACjE;AAEA,MAAM,eAA6B;CACjC,MAAM;CACN,SAAS,CACP,UACA;EACE,MAAM;EACN,OAAO;GACL,KAAK;GACL,OAAO;GACP,QAAQ;GACR,MAAM;EACR;CACF,CACF;AACF;AAEA,MAAM,oBAAkC;CACtC,MAAM;CACN,OAAO;EAAE,OAAO;EAAU,OAAO;EAAU,UAAU;CAAS;AAChE;AAEA,MAAM,kBAAgC;CACpC,MAAM;CACN,OAAO;EAAE,OAAO;EAAU,cAAc;CAAS;AACnD;AAEA,MAAM,oBAAkC;CACtC,MAAM;CACN,OAAO;EACL,MAAM;EACN,SAAS;EACT,MAAM;EACN,OAAO;EACP,QAAQ;EACR,OAAO;CACT;AACF;AAEA,MAAM,iBAA+B;CACnC,MAAM;CACN,SAAS,CACP,WACA;EAAE,MAAM;EAAU,OAAO;GAAE,OAAO;GAAU,OAAO;EAAS;CAAE,CAChE;AACF;AAEA,MAAM,iBAA+B;CACnC,MAAM;CACN,OAAO;EAAE,MAAM;EAAU,SAAS;EAAU,OAAO;CAAS;AAC9D;AAEA,MAAM,oBAAkC;CACtC,MAAM;CACN,OAAO;EAAE,MAAM;EAAU,OAAO;CAAS;AAC3C;AAEA,MAAM,kBAAgC;CACpC,MAAM;CACN,SAAS,CAAC,WAAW;EAAE,MAAM;EAAU,OAAO,EAAE,MAAM,SAAS;CAAE,CAAC;AACpE;AAEA,MAAM,wBAAsC;CAC1C,MAAM;CACN,OAAO;EAAE,KAAK;EAAU,QAAQ;CAAS;AAC3C;AAEA,MAAM,4BAA0C;CAC9C,MAAM;CACN,OAAO;EAAE,OAAO;EAAU,OAAO;CAAS;AAC5C;AAEA,MAAM,4BAA0C;CAC9C,MAAM;CACN,OAAO;EACL,OAAO;EACP,OAAO;EACP,WAAW;EACX,YAAY;CACd;AACF;AAEA,MAAM,oBAAkC;CACtC,MAAM;CACN,OAAO;EACL,MAAM;EACN,GAAG;EACH,GAAG;EACH,GAAG;EACH,GAAG;CACL;AACF;AAGA,MAAM,aAA2C;CAC/C,IAAI;CACJ,GAAG;CACH,GAAG;CACH,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,SAAS;CACT,QAAQ;CACR,iBAAiB;CACjB,oBAAoB;CACpB,iBAAiB;CACjB,QAAQ;CACR,WAAW;CACX,aAAa;CACb,cAAc;CACd,YAAY;CACZ,cAAc;CACd,SAAS;CACT,QAAQ;CACR,UAAU;CACV,KAAK;CACL,OAAO;CACP,QAAQ;CACR,MAAM;CACN,WAAW;CACX,QAAQ;AACV;AAGA,MAAM,mBAAiD;CACrD,UAAU;CACV,OAAO;CACP,WAAW;CACX,MAAM;CACN,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,WAAW;CACX,aAAa;CACb,WAAW;CACX,YAAY;CACZ,YAAY;AACd;AAGA,MAAa,oBAAkE;CAC7E,MAAM;EACJ,GAAG;EACH,MAAM;EACN,QAAQ;EACR,GAAG;EACH,cAAc;EACd,eAAe;EACf,MAAM;EACN,SAAS;CACX;CACA,IAAI;EACF,GAAG;EACH,OAAO;EACP,GAAG;CACL;CACA,IAAI;EACF,GAAG;EACH,OAAO;EACP,GAAG;EACH,YAAY;EACZ,eAAe;CACjB;CACA,OAAO;EACL,GAAG;EACH,KAAK;EACL,QAAQ;EACR,QAAQ;CACV;CACA,MAAM;EACJ,GAAG;EACH,MAAM;EACN,MAAM;EACN,OAAO;EACP,SAAS;EACT,SAAS;EACT,MAAM;EACN,SAAS;EACT,QAAQ;CACV;CACA,KAAK;EACH,GAAG;EACH,OAAO;CACT;CACA,OAAO;EACL,GAAG;EACH,SAAS;EACT,MAAM;EACN,kBAAkB;EAClB,YAAY;CACd;CACA,OAAO;EACL,GAAG;EACH,WAAW;EACX,MAAM;EACN,QAAQ;EACR,MAAM;EACN,MAAM;EACN,MAAM;EACN,SAAS;EACT,GAAG;CACL;CACA,OAAO;EACL,GAAG;EACH,WAAW;EACX,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,aAAa;EACb,YAAY;EACZ,WAAW;CACb;CACA,UAAU;EACR,GAAG;EACH,WAAW;EACX,OAAO;EACP,WAAW;EACX,YAAY;EACZ,kBAAkB;EAClB,gBAAgB;EAChB,mBAAmB;EACnB,iBAAiB;EACjB,YAAY;CACd;CACA,QAAQ;EACN,GAAG;EACH,MAAM;EACN,WAAW;EACX,OAAO;EACP,gBAAgB;EAChB,oBAAoB;EACpB,gBAAgB;CAClB;CACA,MAAM;EACJ,GAAG;EACH,QAAQ;EACR,WAAW;EACX,MAAM;EACN,WAAW;EACX,gBAAgB;EAChB,WAAW;EACX,YAAY;EACZ,UAAU;EACV,YAAY;CACd;CACA,MAAM;EACJ,GAAG;EACH,WAAW;EACX,OAAO;EACP,aAAa;EACb,gBAAgB;EAChB,WAAW;EACX,YAAY;EACZ,SAAS;CACX;CACA,cAAc;EACZ,GAAG;EACH,WAAW;EACX,OAAO;EACP,WAAW;EACX,YAAY;EACZ,KAAK;EACL,UAAU;EACV,MAAM;EACN,QAAQ;EACR,WAAW;EACX,QAAQ;EACR,WAAW;EACX,YAAY;CACd;CACA,SAAS;EACP,GAAG;EACH,WAAW;EACX,QAAQ;EACR,UAAU;EACV,MAAM;EACN,YAAY;CACd;CACA,MAAM;EACJ,GAAG;EACH,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,OAAO;EACP,WAAW;EACX,UAAU;EACV,YAAY;EACZ,UAAU;CACZ;CACA,OAAO;EACL,GAAG;EACH,MAAM;EACN,IAAI;EACJ,OAAO;EACP,WAAW;EACX,UAAU;EACV,YAAY;EACZ,UAAU;CACZ;CAEA,QAAQ;EACN,GAAG;EACH,KAAK;EACL,YAAY;EACZ,gBAAgB;EAChB,UAAU;CACZ;CACA,QAAQ;EACN,GAAG;EACH,KAAK;EACL,YAAY;EACZ,gBAAgB;EAChB,UAAU;CACZ;CACA,OAAO,EACL,GAAG,WACL;AACF;AAGA,MAAa,6BAGT;CACF,kBAAkB;EAChB,OAAO;EACP,OAAO;EACP,WAAW;CACb;CACA,cAAc;EACZ,OAAO;EACP,OAAO;EACP,WAAW;CACb;CACA,cAAc;EACZ,MAAM;EACN,OAAO;EACP,aAAa;EACb,OAAO;EACP,WAAW;CACb;CACA,YAAY;EACV,GAAG;EACH,GAAG;CACL;CACA,iBAAiB;EACf,SAAS;EACT,UAAU;EACV,YAAY;EACZ,aAAa;CACf;CACA,YAAY;EACV,OAAO;EACP,GAAG;EACH,GAAG;EACH,OAAO;EACP,WAAW;CACb;CACA,UAAU;EACR,IAAI;EACJ,OAAO;EACP,MAAM;EACN,OAAO;EACP,WAAW;EACX,OAAO;EACP,QAAQ;CACV;CACA,gBAAgB;EACd,MAAM;EACN,IAAI;EACJ,OAAO;EACP,OAAO;EACP,YAAY;CACd;CACA,KAAK,EACH,OAAO,SACT;CACA,IAAI;EACF,MAAM;EACN,UAAU;EACV,OAAO;EACP,MAAM;EACN,QAAQ;EACR,WAAW;EACX,QAAQ;EACR,WAAW;EACX,aAAa;EACb,WAAW;EACX,YAAY;EACZ,WAAW;EACX,iBAAiB;EACjB,SAAS;EACT,SAAS;CACX;CACA,IAAI;EACF,MAAM;EACN,MAAM;EACN,QAAQ;EACR,WAAW;EACX,QAAQ;EACR,WAAW;EACX,aAAa;EACb,WAAW;EACX,OAAO;EACP,UAAU;EACV,YAAY;CACd;CACA,GAAG,CAAC;CACJ,GAAG,CAAC;CACJ,MAAM;EACJ,OAAO;EACP,YAAY;EACZ,UAAU;EACV,eAAe;CACjB;AACF"}
|
|
1
|
+
{"version":3,"file":"coercionRules.js","names":[],"sources":["../../src/parseXml/coercionRules.ts"],"sourcesContent":["/**\n * 明示的な型変換ルール定義\n *\n * Zod の内部構造(_def)に依存せず、XML 属性値の文字列→適切な型への変換ルールを\n * 静的に定義する。各ノードタイプ・子要素タイプごとに変換テーブルを持つ。\n */\n\n// ===== CoercionRule 型定義 =====\nexport type CoercionRule =\n | \"number\"\n | \"boolean\"\n | \"string\" // string, enum を含む\n | \"json\" // array, object, record, tuple → JSON.parse\n | { type: \"literal\"; value: string | number | boolean }\n | { type: \"union\"; options: CoercionRule[] }\n | { type: \"object\"; shape: Record<string, CoercionRule> };\n\n// ===== 変換関数 =====\n\nexport function coerceWithRule(\n value: string,\n rule: CoercionRule,\n): { value: unknown; error: string | null } {\n if (rule === \"number\") {\n if (value === \"\") {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to number`,\n };\n }\n const num = Number(value);\n if (isNaN(num)) {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to number`,\n };\n }\n return { value: num, error: null };\n }\n if (rule === \"boolean\") {\n if (value !== \"true\" && value !== \"false\") {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to boolean (expected \"true\" or \"false\")`,\n };\n }\n return { value: value === \"true\", error: null };\n }\n if (rule === \"string\") {\n return { value, error: null };\n }\n if (rule === \"json\") {\n try {\n return { value: JSON.parse(value), error: null };\n } catch {\n return {\n value: undefined,\n error: `Cannot parse JSON value: \"${value}\"`,\n };\n }\n }\n // オブジェクト型のルール\n if (rule.type === \"literal\") {\n return { value: rule.value, error: null };\n }\n if (rule.type === \"union\") {\n return { value: coerceUnionWithRules(value, rule.options), error: null };\n }\n if (rule.type === \"object\") {\n try {\n return { value: JSON.parse(value), error: null };\n } catch {\n return {\n value: undefined,\n error: `Cannot parse JSON value: \"${value}\"`,\n };\n }\n }\n return { value: coerceFallback(value), error: null };\n}\n\nexport function coerceUnionWithRules(\n value: string,\n options: CoercionRule[],\n): unknown {\n // boolean を試行\n if ((value === \"true\" || value === \"false\") && options.includes(\"boolean\")) {\n return value === \"true\";\n }\n\n // number を試行\n if (options.includes(\"number\")) {\n const num = Number(value);\n if (!isNaN(num) && value !== \"\") {\n return num;\n }\n }\n\n // literal を試行\n for (const opt of options) {\n if (typeof opt === \"object\" && opt.type === \"literal\") {\n if (`${opt.value as string | number}` === value) return opt.value;\n }\n }\n\n // object/json を試行(JSON パース)\n if (\n options.some(\n (opt) =>\n opt === \"json\" || (typeof opt === \"object\" && opt.type === \"object\"),\n )\n ) {\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch {\n /* ignore */\n }\n }\n }\n\n // string にフォールバック\n return value;\n}\n\nexport function coerceFallback(value: string): unknown {\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n const num = Number(value);\n if (value !== \"\" && !isNaN(num)) return num;\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch {\n /* ignore */\n }\n }\n return value;\n}\n\n/**\n * CoercionRule からオブジェクト型の shape を取得する。\n * dot notation の展開で使用。\n */\nexport function getObjectShapeFromRule(\n rule: CoercionRule,\n): Record<string, CoercionRule> | undefined {\n if (typeof rule === \"object\" && rule.type === \"object\") {\n return rule.shape;\n }\n if (typeof rule === \"object\" && rule.type === \"union\") {\n const objectOpt = rule.options.find(\n (opt): opt is { type: \"object\"; shape: Record<string, CoercionRule> } =>\n typeof opt === \"object\" && opt.type === \"object\",\n );\n return objectOpt?.shape;\n }\n return undefined;\n}\n\n/**\n * boolean と object の union かどうかを判定する。\n * endArrow=\"true\" と endArrow.type=\"triangle\" の共存を許可するために使用。\n */\nexport function isBooleanObjectUnionRule(rule: CoercionRule): boolean {\n if (typeof rule === \"string\") return false;\n if (rule.type !== \"union\") return false;\n const hasBoolean = rule.options.includes(\"boolean\");\n const hasObject = rule.options.some(\n (opt) => typeof opt === \"object\" && opt.type === \"object\",\n );\n return hasBoolean && hasObject;\n}\n\ntype ResolvedMixedNotationShorthand =\n | { mode: \"merge\"; value: Record<string, unknown> }\n | { mode: \"ignore\" }\n | { mode: \"conflict\" };\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isDirectionalBoxShape(shape: Record<string, CoercionRule>): boolean {\n const keys = Object.keys(shape).sort();\n return (\n keys.length === 4 &&\n keys[0] === \"bottom\" &&\n keys[1] === \"left\" &&\n keys[2] === \"right\" &&\n keys[3] === \"top\"\n );\n}\n\n/**\n * 同一属性で shorthand と dot notation を併用したときに、\n * shorthand 側をどのように扱うかを解決する。\n *\n * - merge: shorthand をオブジェクト化して dot notation 側で上書き\n * - ignore: boolean shorthand を無視して dot notation を優先\n * - conflict: 併用不可(従来どおりエラー)\n */\nexport function resolveMixedNotationShorthand(\n value: string,\n rule: CoercionRule,\n): ResolvedMixedNotationShorthand {\n const objectShape = getObjectShapeFromRule(rule);\n if (!objectShape) return { mode: \"conflict\" };\n\n if (\n isBooleanObjectUnionRule(rule) &&\n (value === \"true\" || value === \"false\")\n ) {\n return { mode: \"ignore\" };\n }\n\n const coerced = coerceWithRule(value, rule);\n if (coerced.error !== null) return { mode: \"conflict\" };\n\n if (isPlainObject(coerced.value)) {\n return { mode: \"merge\", value: coerced.value };\n }\n\n if (typeof coerced.value === \"number\" && isDirectionalBoxShape(objectShape)) {\n return {\n mode: \"merge\",\n value: {\n top: coerced.value,\n right: coerced.value,\n bottom: coerced.value,\n left: coerced.value,\n },\n };\n }\n\n return { mode: \"conflict\" };\n}\n\n// ===== 共通変換ルール =====\n\nconst LENGTH_RULE: CoercionRule = {\n type: \"union\",\n options: [\"number\", { type: \"literal\", value: \"max\" }, \"string\"],\n};\n\nconst PADDING_RULE: CoercionRule = {\n type: \"union\",\n options: [\n \"number\",\n {\n type: \"object\",\n shape: {\n top: \"number\",\n right: \"number\",\n bottom: \"number\",\n left: \"number\",\n },\n },\n ],\n};\n\nconst BORDER_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\", dashType: \"string\" },\n};\n\nconst FILL_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", transparency: \"number\" },\n};\n\nconst SHADOW_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n type: \"string\",\n opacity: \"number\",\n blur: \"number\",\n angle: \"number\",\n offset: \"number\",\n color: \"string\",\n },\n};\n\nconst UNDERLINE_RULE: CoercionRule = {\n type: \"union\",\n options: [\n \"boolean\",\n { type: \"object\", shape: { style: \"string\", color: \"string\" } },\n ],\n};\n\nconst TEXT_GLOW_RULE: CoercionRule = {\n type: \"object\",\n shape: { size: \"number\", opacity: \"number\", color: \"string\" },\n};\n\nconst TEXT_OUTLINE_RULE: CoercionRule = {\n type: \"object\",\n shape: { size: \"number\", color: \"string\" },\n};\n\nconst LINE_ARROW_RULE: CoercionRule = {\n type: \"union\",\n options: [\"boolean\", { type: \"object\", shape: { type: \"string\" } }],\n};\n\nconst BACKGROUND_IMAGE_RULE: CoercionRule = {\n type: \"object\",\n shape: { src: \"string\", sizing: \"string\" },\n};\n\nconst TREE_CONNECTOR_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\" },\n};\n\nconst FLOW_CONNECTOR_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n color: \"string\",\n width: \"number\",\n arrowType: \"string\",\n labelColor: \"string\",\n },\n};\n\nconst IMAGE_SIZING_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n type: \"string\",\n w: \"number\",\n h: \"number\",\n x: \"number\",\n y: \"number\",\n },\n};\n\n// ===== Base node 属性 =====\nconst BASE_RULES: Record<string, CoercionRule> = {\n id: \"string\",\n w: LENGTH_RULE,\n h: LENGTH_RULE,\n grow: \"number\",\n minW: \"number\",\n maxW: \"number\",\n minH: \"number\",\n maxH: \"number\",\n padding: PADDING_RULE,\n margin: PADDING_RULE,\n backgroundColor: \"string\",\n backgroundGradient: \"string\",\n backgroundImage: BACKGROUND_IMAGE_RULE,\n border: BORDER_STYLE_RULE,\n borderTop: BORDER_STYLE_RULE,\n borderRight: BORDER_STYLE_RULE,\n borderBottom: BORDER_STYLE_RULE,\n borderLeft: BORDER_STYLE_RULE,\n borderRadius: \"number\",\n opacity: \"number\",\n zIndex: \"number\",\n position: \"string\",\n top: \"number\",\n right: \"number\",\n bottom: \"number\",\n left: \"number\",\n alignSelf: \"string\",\n shadow: SHADOW_STYLE_RULE,\n};\n\n// テキスト系の共通属性\nconst TEXT_STYLE_RULES: Record<string, CoercionRule> = {\n fontSize: \"number\",\n color: \"string\",\n textAlign: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n subscript: \"boolean\",\n superscript: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n lineHeight: \"number\",\n};\n\n// ===== ノードタイプ別の変換ルールマップ =====\nexport const NODE_COERCION_MAP: Record<string, Record<string, CoercionRule>> = {\n text: {\n ...BASE_RULES,\n text: \"string\",\n rotate: \"number\",\n ...TEXT_STYLE_RULES,\n textGradient: \"string\",\n letterSpacing: \"number\",\n glow: TEXT_GLOW_RULE,\n outline: TEXT_OUTLINE_RULE,\n },\n ul: {\n ...BASE_RULES,\n items: \"json\",\n ...TEXT_STYLE_RULES,\n },\n ol: {\n ...BASE_RULES,\n items: \"json\",\n ...TEXT_STYLE_RULES,\n numberType: \"string\",\n numberStartAt: \"number\",\n },\n image: {\n ...BASE_RULES,\n src: \"string\",\n sizing: IMAGE_SIZING_RULE,\n rotate: \"number\",\n },\n icon: {\n ...BASE_RULES,\n name: \"string\",\n size: \"number\",\n color: \"string\",\n variant: \"string\",\n bgColor: \"string\",\n glow: TEXT_GLOW_RULE,\n outline: TEXT_OUTLINE_RULE,\n rotate: \"number\",\n },\n svg: {\n ...BASE_RULES,\n color: \"string\",\n },\n table: {\n ...BASE_RULES,\n columns: \"json\",\n rows: \"json\",\n defaultRowHeight: \"number\",\n cellBorder: BORDER_STYLE_RULE,\n },\n shape: {\n ...BASE_RULES,\n shapeType: \"string\",\n text: \"string\",\n rotate: \"number\",\n fill: FILL_STYLE_RULE,\n line: BORDER_STYLE_RULE,\n glow: TEXT_GLOW_RULE,\n outline: TEXT_OUTLINE_RULE,\n ...TEXT_STYLE_RULES,\n },\n chart: {\n ...BASE_RULES,\n chartType: \"string\",\n data: \"json\",\n showLegend: \"boolean\",\n showTitle: \"boolean\",\n title: \"string\",\n chartColors: \"json\",\n radarStyle: \"string\",\n sparkline: \"boolean\",\n },\n timeline: {\n ...BASE_RULES,\n direction: \"string\",\n items: \"json\",\n dateColor: \"string\",\n titleColor: \"string\",\n descriptionColor: \"string\",\n connectorColor: \"string\",\n connectorGradient: \"string\",\n useColorForDate: \"boolean\",\n fontFamily: \"string\",\n },\n matrix: {\n ...BASE_RULES,\n axes: \"json\",\n quadrants: \"json\",\n items: \"json\",\n axisLabelColor: \"string\",\n quadrantLabelColor: \"string\",\n itemLabelColor: \"string\",\n },\n tree: {\n ...BASE_RULES,\n layout: \"string\",\n nodeShape: \"string\",\n data: \"json\",\n textColor: \"string\",\n connectorStyle: TREE_CONNECTOR_STYLE_RULE,\n nodeWidth: \"number\",\n nodeHeight: \"number\",\n levelGap: \"number\",\n siblingGap: \"number\",\n },\n flow: {\n ...BASE_RULES,\n direction: \"string\",\n nodes: \"json\",\n connections: \"json\",\n connectorStyle: FLOW_CONNECTOR_STYLE_RULE,\n nodeWidth: \"number\",\n nodeHeight: \"number\",\n nodeGap: \"number\",\n },\n processArrow: {\n ...BASE_RULES,\n direction: \"string\",\n steps: \"json\",\n itemWidth: \"number\",\n itemHeight: \"number\",\n gap: \"number\",\n fontSize: \"number\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n },\n pyramid: {\n ...BASE_RULES,\n direction: \"string\",\n levels: \"json\",\n fontSize: \"number\",\n bold: \"boolean\",\n fontFamily: \"string\",\n },\n line: {\n ...BASE_RULES,\n x1: \"number\",\n y1: \"number\",\n x2: \"number\",\n y2: \"number\",\n color: \"string\",\n lineWidth: \"number\",\n dashType: \"string\",\n beginArrow: LINE_ARROW_RULE,\n endArrow: LINE_ARROW_RULE,\n },\n arrow: {\n ...BASE_RULES,\n from: \"string\",\n to: \"string\",\n color: \"string\",\n lineWidth: \"number\",\n dashType: \"string\",\n beginArrow: LINE_ARROW_RULE,\n endArrow: LINE_ARROW_RULE,\n },\n // コンテナノード\n vstack: {\n ...BASE_RULES,\n gap: \"number\",\n alignItems: \"string\",\n justifyContent: \"string\",\n flexWrap: \"string\",\n },\n hstack: {\n ...BASE_RULES,\n gap: \"number\",\n alignItems: \"string\",\n justifyContent: \"string\",\n flexWrap: \"string\",\n },\n layer: {\n ...BASE_RULES,\n },\n};\n\n// ===== 子要素の変換ルールマップ =====\nexport const CHILD_ELEMENT_COERCION_MAP: Record<\n string,\n Record<string, CoercionRule>\n> = {\n ProcessArrowStep: {\n label: \"string\",\n color: \"string\",\n textColor: \"string\",\n },\n PyramidLevel: {\n label: \"string\",\n color: \"string\",\n textColor: \"string\",\n },\n TimelineItem: {\n date: \"string\",\n title: \"string\",\n description: \"string\",\n color: \"string\",\n dateColor: \"string\",\n },\n MatrixAxes: {\n x: \"string\",\n y: \"string\",\n },\n MatrixQuadrants: {\n topLeft: \"string\",\n topRight: \"string\",\n bottomLeft: \"string\",\n bottomRight: \"string\",\n },\n MatrixItem: {\n label: \"string\",\n x: \"number\",\n y: \"number\",\n color: \"string\",\n textColor: \"string\",\n },\n FlowNode: {\n id: \"string\",\n shape: \"string\",\n text: \"string\",\n color: \"string\",\n textColor: \"string\",\n width: \"number\",\n height: \"number\",\n },\n FlowConnection: {\n from: \"string\",\n to: \"string\",\n label: \"string\",\n color: \"string\",\n labelColor: \"string\",\n },\n Col: {\n width: \"number\",\n },\n Td: {\n text: \"string\",\n fontSize: \"number\",\n color: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n subscript: \"boolean\",\n superscript: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n textAlign: \"string\",\n backgroundColor: \"string\",\n colspan: \"number\",\n rowspan: \"number\",\n },\n Li: {\n text: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n subscript: \"boolean\",\n superscript: \"boolean\",\n highlight: \"string\",\n color: \"string\",\n fontSize: \"number\",\n fontFamily: \"string\",\n },\n B: {},\n I: {},\n Span: {\n color: \"string\",\n fontFamily: \"string\",\n fontSize: \"number\",\n letterSpacing: \"number\",\n },\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseXml.d.ts","names":[],"sources":["../../src/parseXml/parseXml.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"parseXml.d.ts","names":[],"sources":["../../src/parseXml/parseXml.ts"],"mappings":";;cAiCa,sBAAsB;WACjB;EACJ,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0sCE,SAAS,oBAAoB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseXml.js","names":[],"sources":["../../src/parseXml/parseXml.ts"],"sourcesContent":["import { XMLBuilder, XMLParser } from \"fast-xml-parser\";\nimport type { z } from \"zod\";\nimport type { POMNode } from \"../types.ts\";\nimport {\n getNodeMetadata,\n getNodeMetadataByTag,\n NODE_METADATA,\n} from \"../registry/nodeMetadata.ts\";\nimport {\n INLINE_BOOLEAN_FORMATS,\n INLINE_FORMAT_TAG_LIST,\n INLINE_FORMAT_TAGS,\n INLINE_LINK_TAG,\n INLINE_MARK_TAG,\n INLINE_SPAN_TAG,\n MARK_DEFAULT_HIGHLIGHT_COLOR,\n formatExpectedTags,\n type NodeSpecificChildRule,\n type RepeatedChildRule,\n type TextRun,\n type XmlChildRule,\n} from \"../registry/xmlChildRules.ts\";\nimport {\n type CoercionRule,\n NODE_COERCION_MAP,\n CHILD_ELEMENT_COERCION_MAP,\n coerceWithRule,\n coerceFallback,\n getObjectShapeFromRule,\n resolveMixedNotationShorthand,\n} from \"./coercionRules.ts\";\n\n// ===== ParseXmlError =====\nexport class ParseXmlError extends Error {\n public readonly errors: string[];\n constructor(errors: string[]) {\n const message = `XML validation failed (${errors.length} error${errors.length > 1 ? \"s\" : \"\"}):\\n${errors.map((e) => ` - ${e}`).join(\"\\n\")}`;\n super(message);\n this.name = \"ParseXmlError\";\n this.errors = errors;\n }\n}\n\n// ===== Tag name → POM node type mapping =====\nexport const TAG_TO_TYPE: Record<string, string> = Object.fromEntries(\n NODE_METADATA.map((def) => [def.tagName, def.type]),\n);\n// Attributes allowed on any node (e.g., x/y for Layer children positioning)\nconst UNIVERSAL_ATTRS = new Set([\"x\", \"y\"]);\n\n// ===== Validation helpers =====\nfunction getKnownAttributes(nodeType: string): string[] {\n const rules = NODE_COERCION_MAP[nodeType];\n if (!rules) return [];\n return Object.keys(rules);\n}\n\nfunction levenshteinDistance(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array<number>(n + 1).fill(0),\n );\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] =\n a[i - 1] === b[j - 1]\n ? dp[i - 1][j - 1]\n : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);\n }\n }\n return dp[m][n];\n}\n\nfunction findClosestMatch(\n input: string,\n candidates: string[],\n): string | undefined {\n const threshold = Math.max(2, Math.floor(input.length / 2));\n let bestMatch: string | undefined;\n let bestDistance = Infinity;\n for (const candidate of candidates) {\n const dist = levenshteinDistance(\n input.toLowerCase(),\n candidate.toLowerCase(),\n );\n if (dist < bestDistance && dist <= threshold) {\n bestDistance = dist;\n bestMatch = candidate;\n }\n }\n return bestMatch;\n}\n\nfunction getKnownChildAttributes(tagName: string): string[] {\n const rules = CHILD_ELEMENT_COERCION_MAP[tagName];\n if (!rules) return [];\n return Object.keys(rules);\n}\n\nfunction formatZodIssue(\n issue: z.core.$ZodIssue,\n tagName: string,\n): string | null {\n const path = issue.path;\n // Skip children-related issues (validated recursively)\n if (path.length > 0 && path[0] === \"children\") return null;\n // Skip \"type\" field issues (set internally)\n if (path.length === 1 && path[0] === \"type\") return null;\n\n const attrName = path.length > 0 ? String(path[0]) : undefined;\n\n const code = issue.code;\n\n if (code === \"invalid_type\") {\n // Missing required attribute\n if (issue.input === undefined) {\n if (attrName) {\n return `<${tagName}>: Missing required attribute \"${attrName}\"`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n // Type mismatch\n if (attrName) {\n return `<${tagName}>: Invalid type for attribute \"${attrName}\". ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n\n if (code === \"invalid_value\") {\n if (attrName) {\n const values = (issue as unknown as { values: string[] }).values;\n if (values) {\n return `<${tagName}>: Invalid value for attribute \"${attrName}\". Expected: ${values.map((v) => `\"${v}\"`).join(\", \")}`;\n }\n return `<${tagName}>: Invalid value for attribute \"${attrName}\". ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n\n if (code === \"too_small\" || code === \"too_big\") {\n if (attrName) {\n return `<${tagName}>: Invalid value for attribute \"${attrName}\". ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n\n // Generic fallback\n if (attrName) {\n return `<${tagName}>: Attribute \"${attrName}\": ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n}\n\n// Properties that may be legitimately absent when using child element notation\n// or when the property is optional in practice (even if required in schema).\nfunction validateLeafNode(\n nodeType: string,\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const def = getNodeMetadata(nodeType as POMNode[\"type\"]);\n if (def.childPolicy.kind === \"pom-children\") return;\n const schema = def.schema;\n const tagName = def.tagName;\n const optionalChildProps = new Set(\n def.childPolicy.kind === \"custom\"\n ? (def.childPolicy.optionalProperties ?? [])\n : [],\n );\n const parseResult = schema.safeParse(result);\n if (!parseResult.success) {\n const seen = new Set<string>();\n for (const issue of parseResult.error.issues) {\n // Skip only top-level missing child-element properties (path.length === 1)\n // Nested issues (e.g., data.children[0].label) must still be reported\n if (\n optionalChildProps.size > 0 &&\n issue.path.length === 1 &&\n optionalChildProps.has(String(issue.path[0])) &&\n issue.code === \"invalid_type\" &&\n issue.input === undefined\n ) {\n continue;\n }\n // Skip issues for universal attributes (x, y)\n if (issue.path.length > 0 && UNIVERSAL_ATTRS.has(String(issue.path[0]))) {\n continue;\n }\n const msg = formatZodIssue(issue, tagName);\n if (msg && !seen.has(msg)) {\n seen.add(msg);\n errors.push(msg);\n }\n }\n }\n}\n\n// ===== Types for XML parser output (preserveOrder mode) =====\ntype XmlNode = XmlElement | XmlTextNode;\ntype XmlTextNode = { \"#text\": string };\ninterface XmlElement {\n [tagName: string]: XmlNode[] | Record<string, string> | undefined;\n \":@\"?: Record<string, string>;\n}\n\n// ===== Coercion rule lookup =====\n\nfunction getCoercionRule(\n nodeType: string,\n propertyName: string,\n): CoercionRule | undefined {\n return NODE_COERCION_MAP[nodeType]?.[propertyName];\n}\n\n// ===== Dot notation helpers =====\n\n// ===== Dot notation expansion =====\nfunction expandDotNotation(attrs: Record<string, string>): {\n regular: Record<string, string>;\n dotGroups: Record<string, Record<string, string>>;\n} {\n const regular: Record<string, string> = {};\n const dotGroups: Record<string, Record<string, string>> = {};\n\n for (const [key, value] of Object.entries(attrs)) {\n const dotIndex = key.indexOf(\".\");\n if (dotIndex > 0) {\n const prefix = key.substring(0, dotIndex);\n const suffix = key.substring(dotIndex + 1);\n if (!dotGroups[prefix]) dotGroups[prefix] = {};\n dotGroups[prefix][suffix] = value;\n } else {\n regular[key] = value;\n }\n }\n\n return { regular, dotGroups };\n}\n\nfunction coerceDotGroup(\n prefix: string,\n subAttrs: Record<string, string>,\n rule: CoercionRule,\n tagName: string,\n errors: string[],\n): Record<string, unknown> {\n const objectShape = getObjectShapeFromRule(rule);\n\n const obj: Record<string, unknown> = {};\n if (objectShape) {\n for (const [subKey, subValue] of Object.entries(subAttrs)) {\n if (objectShape[subKey]) {\n const coerced = coerceWithRule(subValue, objectShape[subKey]);\n if (coerced.error !== null) {\n errors.push(`<${tagName}>: ${prefix}.${subKey}: ${coerced.error}`);\n } else {\n obj[subKey] = coerced.value;\n }\n } else {\n const knownSubKeys = Object.keys(objectShape);\n const suggestion = findClosestMatch(subKey, knownSubKeys);\n errors.push(\n `<${tagName}>: Unknown sub-attribute \"${prefix}.${subKey}\"${suggestion ? `. Did you mean \"${prefix}.${suggestion}\"?` : \"\"}`,\n );\n }\n }\n } else {\n errors.push(\n `<${tagName}>: Attribute \"${prefix}\" does not support dot notation`,\n );\n }\n return obj;\n}\n\n// ===== XML node helpers =====\nfunction isTextNode(node: XmlNode): node is XmlTextNode {\n return \"#text\" in node;\n}\n\nfunction getTagName(node: XmlElement): string {\n for (const key of Object.keys(node)) {\n if (key !== \":@\") return key;\n }\n throw new Error(\"No tag name found in XML element\");\n}\n\nfunction getAttributes(node: XmlElement): Record<string, string> {\n const attrs: Record<string, string> = {};\n const rawAttrs = node[\":@\"];\n if (rawAttrs) {\n for (const [key, value] of Object.entries(rawAttrs)) {\n const attrName = key.startsWith(\"@_\") ? key.slice(2) : key;\n attrs[attrName] = value.trim();\n }\n }\n return attrs;\n}\n\nfunction getChildElements(node: XmlElement): XmlElement[] {\n const tagName = getTagName(node);\n const children = node[tagName] as XmlNode[] | undefined;\n if (!children) return [];\n return children.filter((child): child is XmlElement => !isTextNode(child));\n}\n\nfunction getTextContent(node: XmlElement): string | undefined {\n const tagName = getTagName(node);\n const children = node[tagName] as XmlNode[] | undefined;\n if (!children) return undefined;\n const textParts: string[] = [];\n for (const child of children) {\n if (isTextNode(child)) {\n textParts.push(child[\"#text\"]);\n }\n }\n return textParts.length > 0 ? textParts.join(\"\") : undefined;\n}\n\nfunction getRawChildren(node: XmlElement): XmlNode[] {\n const tagName = getTagName(node);\n return (node[tagName] as XmlNode[] | undefined) ?? [];\n}\n\nfunction hasInlineFormatChildren(childElements: XmlElement[]): boolean {\n return (\n childElements.length > 0 &&\n childElements.every((el) => INLINE_FORMAT_TAGS.has(getTagName(el)))\n );\n}\n\nfunction extractTextRuns(\n children: XmlNode[],\n inherited: Partial<Omit<TextRun, \"text\">> = {},\n): TextRun[] {\n const runs: TextRun[] = [];\n for (const child of children) {\n if (isTextNode(child)) {\n runs.push({ text: child[\"#text\"], ...inherited });\n continue;\n }\n const tag = getTagName(child);\n const innerChildren = getRawChildren(child);\n const booleanFormat = INLINE_BOOLEAN_FORMATS.find(\n (format) => format.tag === tag,\n );\n if (booleanFormat) {\n const next: Partial<Omit<TextRun, \"text\">> = {\n ...inherited,\n [booleanFormat.property]: true,\n };\n // subscript と superscript は OOXML の baseline 値として相互排他\n // (同時 true は描画結果が未定義になる)。後で立てた側を優先して反対側を解除する。\n if (booleanFormat.property === \"subscript\") delete next.superscript;\n if (booleanFormat.property === \"superscript\") delete next.subscript;\n runs.push(...extractTextRuns(innerChildren, next));\n } else if (tag === INLINE_LINK_TAG) {\n // href なしの <A> は外側の href を引き継がない(リンク解除として扱う)\n const next = { ...inherited };\n const href = getAttributes(child).href;\n if (href) {\n next.href = href;\n } else {\n delete next.href;\n }\n runs.push(...extractTextRuns(innerChildren, next));\n } else if (tag === INLINE_MARK_TAG) {\n const rawColor = getAttributes(child).color;\n const highlight =\n rawColor && rawColor.trim() ? rawColor : MARK_DEFAULT_HIGHLIGHT_COLOR;\n runs.push(...extractTextRuns(innerChildren, { ...inherited, highlight }));\n } else if (tag === INLINE_SPAN_TAG) {\n const spanAttrs = getAttributes(child);\n const next = { ...inherited };\n if (spanAttrs.color && spanAttrs.color.trim()) {\n next.color = spanAttrs.color;\n }\n if (spanAttrs.fontFamily && spanAttrs.fontFamily.trim()) {\n next.fontFamily = spanAttrs.fontFamily;\n }\n if (spanAttrs.fontSize && spanAttrs.fontSize.trim()) {\n next.fontSize = Number(spanAttrs.fontSize);\n }\n if (spanAttrs.letterSpacing && spanAttrs.letterSpacing.trim()) {\n next.letterSpacing = Number(spanAttrs.letterSpacing);\n }\n runs.push(...extractTextRuns(innerChildren, next));\n }\n }\n return runs;\n}\n\nfunction buildRunsAndText(\n node: XmlElement,\n): { runs: TextRun[]; text: string } | null {\n const rawChildren = getRawChildren(node);\n const childElements = rawChildren.filter(\n (c): c is XmlElement => !isTextNode(c),\n );\n if (!hasInlineFormatChildren(childElements)) return null;\n const runs = extractTextRuns(rawChildren);\n const text = runs.map((r) => r.text).join(\"\");\n return { runs, text };\n}\n\nfunction coerceChildAttrs(\n parentTagName: string,\n tagName: string,\n attrs: Record<string, string>,\n errors: string[],\n): Record<string, unknown> {\n const rules = CHILD_ELEMENT_COERCION_MAP[tagName];\n const result: Record<string, unknown> = {};\n const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);\n\n // Process dot-notation attributes\n for (const [prefix, subAttrs] of Object.entries(dotGroups)) {\n if (rules && rules[prefix]) {\n result[prefix] = coerceDotGroup(\n prefix,\n subAttrs,\n rules[prefix],\n `${parentTagName}.${tagName}`,\n errors,\n );\n } else if (rules) {\n const knownAttrs = getKnownChildAttributes(tagName);\n const suggestion = findClosestMatch(prefix, knownAttrs);\n errors.push(\n `<${parentTagName}>.<${tagName}>: Unknown attribute \"${prefix}\"${suggestion ? `. Did you mean \"${suggestion}\"?` : \"\"}`,\n );\n } else {\n result[prefix] = {};\n for (const [subKey, subValue] of Object.entries(subAttrs)) {\n (result[prefix] as Record<string, unknown>)[subKey] =\n coerceFallback(subValue);\n }\n }\n }\n\n // Process regular attributes\n for (const [key, value] of Object.entries(regularAttrs)) {\n if (key in dotGroups) {\n if (rules && rules[key]) {\n const resolved = resolveMixedNotationShorthand(value, rules[key]);\n if (resolved.mode === \"ignore\") {\n continue;\n }\n if (resolved.mode === \"merge\") {\n result[key] = {\n ...resolved.value,\n ...(result[key] as Record<string, unknown>),\n };\n continue;\n }\n }\n errors.push(\n `<${parentTagName}>.<${tagName}>: Attribute \"${key}\" conflicts with dot-notation attributes. Use one or the other, not both`,\n );\n continue;\n }\n if (rules && rules[key]) {\n const coerced = coerceWithRule(value, rules[key]);\n if (coerced.error !== null) {\n errors.push(`<${parentTagName}>.<${tagName}>: ${coerced.error}`);\n } else {\n result[key] = coerced.value;\n }\n } else if (rules) {\n // Unknown attribute on child element\n const knownAttrs = getKnownChildAttributes(tagName);\n const suggestion = findClosestMatch(key, knownAttrs);\n errors.push(\n `<${parentTagName}>.<${tagName}>: Unknown attribute \"${key}\"${suggestion ? `. Did you mean \"${suggestion}\"?` : \"\"}`,\n );\n } else {\n result[key] = coerceFallback(value);\n }\n }\n return result;\n}\n\n// ===== Child element converters =====\n\nfunction unknownChildError(\n childTag: string,\n parentTag: string,\n expectedTags: readonly string[],\n): string {\n return `Unknown child element <${childTag}> inside <${parentTag}>. Expected: ${formatExpectedTags(expectedTags)}`;\n}\n\n/** element の text content / インライン装飾を attrs の text / runs へ反映する */\nfunction applyTextAndRuns(\n element: XmlElement,\n attrs: Record<string, unknown>,\n): void {\n const runsResult = buildRunsAndText(element);\n if (runsResult) {\n attrs.runs = runsResult.runs;\n attrs.text = runsResult.text;\n } else {\n const textContent = getTextContent(element);\n if (textContent !== undefined && !(\"text\" in attrs)) {\n attrs.text = textContent;\n }\n }\n}\n\n/** RepeatedChildRule (単一種類の child tag の繰り返し → 配列 property) の汎用 converter */\nfunction convertRepeatedChildren(\n rule: RepeatedChildRule,\n parentTag: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const items: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n if (tag !== rule.childTag) {\n errors.push(unknownChildError(tag, parentTag, [rule.childTag]));\n continue;\n }\n const attrs = coerceChildAttrs(\n parentTag,\n tag,\n getAttributes(child),\n errors,\n );\n if (rule.allowsItemText) {\n applyTextAndRuns(child, attrs);\n }\n items.push(attrs);\n }\n result[rule.property] = items;\n}\n\n/** NodeSpecificChildRule を処理する専用 converter のシグネチャ */\ntype NodeSpecificChildConverter = (\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n) => void;\n\nfunction convertMatrixChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const items: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n switch (tag) {\n case \"MatrixAxes\":\n result.axes = coerceChildAttrs(\n tagName,\n tag,\n getAttributes(child),\n errors,\n );\n break;\n case \"MatrixQuadrants\":\n result.quadrants = coerceChildAttrs(\n tagName,\n tag,\n getAttributes(child),\n errors,\n );\n break;\n case \"MatrixItem\":\n items.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n default:\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n }\n }\n if (items.length > 0) {\n result.items = items;\n }\n}\n\nfunction convertFlowChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const nodes: Record<string, unknown>[] = [];\n const connections: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n switch (tag) {\n case \"FlowNode\":\n nodes.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n case \"FlowConnection\":\n connections.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n default:\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n }\n }\n if (nodes.length > 0) {\n result.nodes = nodes;\n }\n if (connections.length > 0) {\n result.connections = connections;\n }\n}\n\nfunction convertChartChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const data: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n if (tag !== \"ChartSeries\") {\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n continue;\n }\n const attrs = getAttributes(child);\n const series: Record<string, unknown> = {\n labels: [],\n values: [],\n };\n if (attrs.name !== undefined) {\n // chartDataSchema.name は z.string().optional() なのでそのまま文字列として使用\n series.name = attrs.name;\n }\n\n for (const dp of getChildElements(child)) {\n const dpTag = getTagName(dp);\n if (dpTag !== \"ChartDataPoint\") {\n errors.push(\n unknownChildError(dpTag, \"ChartSeries\", [\"ChartDataPoint\"]),\n );\n continue;\n }\n const dpAttrs = getAttributes(dp);\n if (dpAttrs.label === undefined) {\n errors.push('<ChartDataPoint> requires a \"label\" attribute');\n }\n if (dpAttrs.value === undefined) {\n errors.push('<ChartDataPoint> requires a \"value\" attribute');\n }\n if (dpAttrs.label === undefined || dpAttrs.value === undefined) {\n continue;\n }\n const numValue = Number(dpAttrs.value);\n if (isNaN(numValue)) {\n errors.push(\n `Cannot convert \"${dpAttrs.value}\" to number in <ChartDataPoint> \"value\" attribute`,\n );\n continue;\n }\n (series.labels as string[]).push(dpAttrs.label);\n (series.values as number[]).push(numValue);\n }\n data.push(series);\n }\n result.data = data;\n}\n\nfunction convertTableChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const columns: Record<string, unknown>[] = [];\n const rows: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n switch (tag) {\n case \"Col\":\n columns.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n case \"Tr\": {\n const rowAttrs = getAttributes(child);\n const cells: Record<string, unknown>[] = [];\n for (const cellEl of getChildElements(child)) {\n const cellTag = getTagName(cellEl);\n if (cellTag !== \"Td\") {\n errors.push(unknownChildError(cellTag, \"Tr\", [\"Td\"]));\n continue;\n }\n const cellAttrs = coerceChildAttrs(\n \"Tr\",\n cellTag,\n getAttributes(cellEl),\n errors,\n );\n applyTextAndRuns(cellEl, cellAttrs);\n cells.push(cellAttrs);\n }\n const row: Record<string, unknown> = { cells };\n if (rowAttrs.height !== undefined) {\n const h = Number(rowAttrs.height);\n if (isNaN(h)) {\n errors.push(\n `Cannot convert \"${rowAttrs.height}\" to number in <Tr> \"height\" attribute`,\n );\n } else {\n row.height = h;\n }\n }\n rows.push(row);\n break;\n }\n default:\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n }\n }\n if (columns.length > 0) {\n result.columns = columns;\n } else if (rows.length > 0) {\n // Col が未指定の場合、行のセル数(colspan 考慮)からデフォルトの columns を自動生成\n const maxCells = Math.max(\n ...rows.map((row) =>\n (row.cells as Record<string, unknown>[]).reduce(\n (sum, cell) => sum + ((cell.colspan as number) ?? 1),\n 0,\n ),\n ),\n );\n result.columns = Array.from({ length: maxCells }, () => ({}));\n }\n if (rows.length > 0) {\n result.rows = rows;\n }\n}\n\nfunction convertTreeItem(\n element: XmlElement,\n errors: string[],\n): Record<string, unknown> {\n const attrs = getAttributes(element);\n if (attrs.label === undefined) {\n errors.push('<TreeItem> requires a \"label\" attribute');\n }\n const item: Record<string, unknown> = {};\n if (attrs.label !== undefined) {\n item.label = attrs.label;\n }\n if (attrs.color !== undefined) {\n item.color = attrs.color;\n }\n if (attrs.textColor !== undefined) {\n item.textColor = attrs.textColor;\n }\n const children = getChildElements(element);\n if (children.length > 0) {\n item.children = children\n .map((child) => {\n const tag = getTagName(child);\n if (tag !== \"TreeItem\") {\n errors.push(unknownChildError(tag, \"TreeItem\", [\"TreeItem\"]));\n return null;\n }\n return convertTreeItem(child, errors);\n })\n .filter((item): item is Record<string, unknown> => item !== null);\n }\n return item;\n}\n\nfunction convertTreeChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n if (childElements.length !== 1) {\n errors.push(\n `<Tree> must have exactly 1 <TreeItem> child element, but got ${childElements.length}`,\n );\n return;\n }\n const child = childElements[0];\n const tag = getTagName(child);\n if (tag !== \"TreeItem\") {\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n return;\n }\n result.data = convertTreeItem(child, errors);\n}\n\n// SVG 要素を XML 文字列に再構築する\nconst svgBuilder = new XMLBuilder({\n preserveOrder: true,\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n});\n\nfunction serializeSvgElement(svgElement: XmlElement): string {\n return String(svgBuilder.build([svgElement]));\n}\n\nfunction convertSvgChildren(\n _rule: NodeSpecificChildRule,\n _tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n if (childElements.length !== 1) {\n errors.push(\n `<Svg>: Expected exactly one <svg> child element, but found ${childElements.length} child element(s)`,\n );\n return;\n }\n\n const child = childElements[0];\n const tag = getTagName(child);\n if (tag !== \"svg\") {\n errors.push(`<Svg>: Expected <svg> child element, but found <${tag}>`);\n return;\n }\n\n result.svgContent = serializeSvgElement(child);\n}\n\nfunction convertInlineRunsChildren(\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n node?: XmlElement,\n): void {\n // インラインフォーマットタグ以外の子要素がある場合はエラー\n for (const el of childElements) {\n const tag = getTagName(el);\n if (!INLINE_FORMAT_TAGS.has(tag)) {\n const allowedTags = INLINE_FORMAT_TAG_LIST.map((t) => `<${t}>`);\n const allowedList = `${allowedTags.slice(0, -1).join(\", \")}, and ${allowedTags[allowedTags.length - 1]}`;\n errors.push(\n `<${tagName}>: Unexpected child element <${tag}>. Only ${allowedList} are allowed inside <${tagName}>`,\n );\n return;\n }\n }\n if (!node || childElements.length === 0) return;\n const runsResult = buildRunsAndText(node);\n if (runsResult) {\n result.runs = runsResult.runs;\n result.text = runsResult.text;\n }\n}\n\n/** NodeSpecificChildRule を持つノードの専用 converter テーブル */\nconst NODE_SPECIFIC_CHILD_CONVERTERS: Record<\n string,\n NodeSpecificChildConverter\n> = {\n matrix: convertMatrixChildren,\n flow: convertFlowChildren,\n chart: convertChartChildren,\n table: convertTableChildren,\n tree: convertTreeChildren,\n svg: convertSvgChildren,\n};\n\n/** NodeMetadata の xmlChildRule に従って child element を変換する */\nfunction applyXmlChildRule(\n rule: XmlChildRule,\n nodeType: string,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n node?: XmlElement,\n): void {\n if (rule.kind === \"inline-runs\") {\n convertInlineRunsChildren(tagName, childElements, result, errors, node);\n return;\n }\n if (rule.kind === \"repeated\") {\n convertRepeatedChildren(rule, tagName, childElements, result, errors);\n return;\n }\n const converter = NODE_SPECIFIC_CHILD_CONVERTERS[nodeType];\n if (!converter) {\n throw new Error(\n `No node-specific child converter registered for node type: ${nodeType}`,\n );\n }\n converter(rule, tagName, childElements, result, errors);\n}\n\n// ===== Theme tokens =====\nconst THEME_TOKEN_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*$/;\nconst THEME_TOKEN_VALUE_PATTERN = /^[0-9A-Fa-f]{6}$/;\n// 値全体が \"$name\"(\"#\" プレフィックスは任意)のときトークン参照とみなす\nconst TOKEN_REF_PATTERN = /^(#?)\\$([A-Za-z][A-Za-z0-9_-]*)$/;\n// backgroundGradient / textGradient 文字列中に現れる \"$name\" 参照\nconst TOKEN_REF_IN_GRADIENT_PATTERN = /#?\\$([A-Za-z][A-Za-z0-9_-]*)/g;\n\nfunction parseThemeElement(\n element: XmlElement,\n tokens: Record<string, string>,\n errors: string[],\n): void {\n if (getChildElements(element).length > 0) {\n errors.push(\n `<Theme>: Child elements are not supported. Declare tokens as attributes (e.g. <Theme accent=\"1D4ED8\" />)`,\n );\n }\n for (const [name, rawValue] of Object.entries(getAttributes(element))) {\n if (!THEME_TOKEN_NAME_PATTERN.test(name)) {\n errors.push(\n `<Theme>: Invalid token name \"${name}\". Token names must start with a letter and contain only letters, digits, \"_\", and \"-\"`,\n );\n continue;\n }\n const value = rawValue.replace(/^#/, \"\");\n if (!THEME_TOKEN_VALUE_PATTERN.test(value)) {\n errors.push(\n `<Theme>: Invalid color value \"${rawValue}\" for token \"${name}\". Expected 6-digit hex (e.g. \"1D4ED8\")`,\n );\n continue;\n }\n tokens[name] = value;\n }\n}\n\n// トークン参照を解決する対象のキー判定。\n// pom の色属性は \"...Color\" / \"...Colors\" / \"highlight\" に統一されているため、\n// キー名ベースで判定することでテキスト内容(text 等)の \"$...\" を誤置換しない。\nfunction isColorKey(key: string): boolean {\n return /colors?$/i.test(key) || key === \"highlight\";\n}\n\nfunction resolveThemeToken(\n name: string,\n hashPrefix: string,\n tokens: Record<string, string>,\n themeDeclared: boolean,\n errors: string[],\n): string | undefined {\n const value = tokens[name];\n if (value !== undefined) {\n return `${hashPrefix}${value}`;\n }\n if (!themeDeclared) {\n errors.push(\n `Theme token \"$${name}\" is referenced, but no <Theme> is declared. Add a top-level <Theme ${name}=\"RRGGBB\" /> element`,\n );\n } else {\n const suggestion = findClosestMatch(name, Object.keys(tokens));\n errors.push(\n `Unknown theme token \"$${name}\"${suggestion ? `. Did you mean \"$${suggestion}\"?` : \"\"}`,\n );\n }\n return undefined;\n}\n\ninterface ThemeContext {\n tokens: Record<string, string>;\n declared: boolean;\n}\n\nfunction resolveThemeTokensDeep(\n value: unknown,\n key: string | null,\n tokens: Record<string, string>,\n themeDeclared: boolean,\n errors: string[],\n): unknown {\n if (typeof value === \"string\") {\n if (key === \"backgroundGradient\" || key === \"textGradient\") {\n return value.replace(\n TOKEN_REF_IN_GRADIENT_PATTERN,\n (matched, name: string) => {\n const resolved = resolveThemeToken(\n name,\n \"#\",\n tokens,\n themeDeclared,\n errors,\n );\n return resolved ?? matched;\n },\n );\n }\n if (key !== null && isColorKey(key)) {\n const match = TOKEN_REF_PATTERN.exec(value.trim());\n if (match) {\n const resolved = resolveThemeToken(\n match[2],\n match[1],\n tokens,\n themeDeclared,\n errors,\n );\n return resolved ?? value;\n }\n }\n return value;\n }\n if (Array.isArray(value)) {\n // 配列はキー文脈を維持して要素ごとに解決する(chartColors 等の文字列配列に対応)\n return value.map((item) =>\n resolveThemeTokensDeep(item, key, tokens, themeDeclared, errors),\n );\n }\n if (typeof value === \"object\" && value !== null) {\n const result: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n result[childKey] = resolveThemeTokensDeep(\n childValue,\n childKey,\n tokens,\n themeDeclared,\n errors,\n );\n }\n return result;\n }\n return value;\n}\n\n// ===== Node conversion =====\nfunction convertElement(\n node: XmlElement,\n errors: string[],\n theme: ThemeContext,\n): Record<string, unknown> | null {\n const tagName = getTagName(node);\n const def = getNodeMetadataByTag(tagName);\n const attrs = getAttributes(node);\n const childElements = getChildElements(node);\n const textContent = getTextContent(node);\n\n if (def) {\n return convertPomNode(\n def.type,\n tagName,\n attrs,\n childElements,\n textContent,\n errors,\n theme,\n node,\n );\n } else {\n errors.push(`Unknown tag: <${tagName}>`);\n return null;\n }\n}\n\nfunction convertPomNode(\n nodeType: string,\n tagName: string,\n attrs: Record<string, string>,\n childElements: XmlElement[],\n textContent: string | undefined,\n errors: string[],\n theme: ThemeContext,\n xmlNode?: XmlElement,\n): Record<string, unknown> {\n const result: Record<string, unknown> = { type: nodeType };\n const def = getNodeMetadata(nodeType as POMNode[\"type\"]);\n\n // Expand dot-notation attributes (e.g., fill.color=\"hex\" → { fill: { color: \"hex\" } })\n const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);\n\n for (const [prefix, subAttrs] of Object.entries(dotGroups)) {\n if (prefix === \"type\") continue;\n const rule = getCoercionRule(nodeType, prefix);\n if (rule) {\n result[prefix] = coerceDotGroup(prefix, subAttrs, rule, tagName, errors);\n } else {\n const knownAttrs = getKnownAttributes(nodeType);\n const suggestion = findClosestMatch(prefix, knownAttrs);\n if (suggestion) {\n errors.push(\n `<${tagName}>: Unknown attribute \"${prefix}\". Did you mean \"${suggestion}\"?`,\n );\n } else {\n errors.push(`<${tagName}>: Unknown attribute \"${prefix}\"`);\n }\n }\n }\n\n for (const [key, value] of Object.entries(regularAttrs)) {\n if (key === \"type\") continue;\n // Conflict check: dot-notation and regular attribute for the same key\n if (key in dotGroups) {\n const ruleForConflict = getCoercionRule(nodeType, key);\n if (ruleForConflict) {\n const resolved = resolveMixedNotationShorthand(value, ruleForConflict);\n if (resolved.mode === \"ignore\") {\n continue;\n }\n if (resolved.mode === \"merge\") {\n result[key] = {\n ...resolved.value,\n ...(result[key] as Record<string, unknown>),\n };\n continue;\n }\n }\n errors.push(\n `<${tagName}>: Attribute \"${key}\" conflicts with dot-notation attributes (e.g., \"${key}.xxx\"). Use one or the other, not both`,\n );\n continue;\n }\n const rule = getCoercionRule(nodeType, key);\n if (rule) {\n const coerced = coerceWithRule(value, rule);\n if (coerced.error !== null) {\n errors.push(`<${tagName}>: ${coerced.error}`);\n } else {\n result[key] = coerced.value;\n }\n } else if (UNIVERSAL_ATTRS.has(key)) {\n // Allow universal attributes (e.g., x/y for Layer children)\n result[key] = coerceFallback(value);\n } else {\n // Unknown attribute\n const knownAttrs = getKnownAttributes(nodeType);\n const suggestion = findClosestMatch(key, knownAttrs);\n if (suggestion) {\n errors.push(\n `<${tagName}>: Unknown attribute \"${key}\". Did you mean \"${suggestion}\"?`,\n );\n } else {\n errors.push(`<${tagName}>: Unknown attribute \"${key}\"`);\n }\n }\n }\n\n // Text content → text property for nodes that support it\n if (textContent !== undefined && def.textContentProperty) {\n if (!(def.textContentProperty in result)) {\n result[def.textContentProperty] = textContent;\n }\n }\n\n // Child element notation for complex properties\n const childRule = def.xmlChildRule;\n if (childRule && childElements.length > 0) {\n applyXmlChildRule(\n childRule,\n nodeType,\n tagName,\n childElements,\n result,\n errors,\n xmlNode,\n );\n }\n // Children for container nodes\n else if (def.childPolicy.kind === \"pom-children\") {\n const convertedChildren = childElements\n .map((child) => convertElement(child, errors, theme))\n .filter((child): child is Record<string, unknown> => child !== null);\n result.children = convertedChildren;\n }\n // Leaf nodes that shouldn't have child elements\n else if (!childRule && childElements.length > 0) {\n errors.push(\n `<${tagName}>: Unexpected child elements. <${tagName}> does not accept child elements`,\n );\n }\n\n // テーマトークン参照(色属性中の \"$name\")を Zod 検証より前に解決する。\n // children は各子ノードの convertPomNode で解決済みのためスキップする。\n for (const [key, value] of Object.entries(result)) {\n if (key === \"type\" || key === \"children\") continue;\n result[key] = resolveThemeTokensDeep(\n value,\n key,\n theme.tokens,\n theme.declared,\n errors,\n );\n }\n\n // Zod validation for leaf nodes\n if (def.childPolicy.kind !== \"pom-children\") {\n validateLeafNode(nodeType, result, errors);\n }\n\n // Icon: normalize color / bgColor\n if (nodeType === \"icon\") {\n if (typeof result.color === \"string\" && !result.color.startsWith(\"#\")) {\n result.color = `#${result.color}`;\n }\n if (typeof result.bgColor === \"string\" && !result.bgColor.startsWith(\"#\")) {\n result.bgColor = `#${result.bgColor}`;\n }\n }\n\n // Svg: normalize color and validate svgContent\n if (nodeType === \"svg\") {\n if (typeof result.color === \"string\" && !result.color.startsWith(\"#\")) {\n result.color = `#${result.color}`;\n }\n if (result.svgContent === undefined) {\n errors.push(\"<Svg>: A <svg> child element is required\");\n }\n }\n\n return result;\n}\n\n/**\n * XML 文字列を POMNode 配列に変換する。\n *\n * 最上位は `<Slide>` 要素と `<Theme>` 要素のみが許容される。各 `<Slide>` が\n * 1 つのスライドに対応し、その子要素がスライドのルート POMNode となる。\n * 子要素が複数ある場合は暗黙的に VStack でラップされる。\n *\n * `<Theme>` は文書全体に適用されるデザイントークン(配色)の宣言で、最大 1 つ\n * 置ける。属性名がトークン名、属性値が 6 桁 hex の色値となり、各ノードの色属性\n * から `$トークン名` で参照できる。参照は parse 時に解決されるため、返される\n * POMNode には解決済みの hex 値が入る(`<Theme>` 自体はノードにならない)。\n *\n * XML タグは POM ノードタイプにマッピングされ、属性値は Zod スキーマを参照して\n * 適切な型(number, boolean, array, object)に変換される。\n * 未知のタグ名が指定された場合はエラーがスローされる。\n *\n * @example\n * ```typescript\n * import { parseXml, buildPptx } from \"@hirokisakabe/pom\";\n *\n * const xml = `\n * <Slide>\n * <VStack gap=\"16\" padding=\"32\">\n * <Text fontSize=\"32\" bold=\"true\">売上レポート</Text>\n * </VStack>\n * </Slide>\n * `;\n *\n * const nodes = parseXml(xml);\n * const pptx = await buildPptx(nodes, { w: 1280, h: 720 });\n * ```\n */\nexport function parseXml(xmlString: string): POMNode[] {\n if (!xmlString.trim()) return [];\n\n const parser = new XMLParser({\n preserveOrder: true,\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n parseAttributeValue: false,\n parseTagValue: false,\n trimValues: false,\n });\n\n const wrappedXml = `<__root__>${xmlString}</__root__>`;\n const parsed: XmlElement[] = parser.parse(wrappedXml) as XmlElement[];\n\n if (!parsed || parsed.length === 0) return [];\n\n const rootElement = parsed[0];\n const rootChildren = (rootElement[\"__root__\"] ?? []) as XmlNode[];\n\n const errors: string[] = [];\n const topLevelElements = rootChildren.filter(\n (child): child is XmlElement => !isTextNode(child),\n );\n\n // <Theme> はスライドより先に収集する(出現位置によらず文書全体に適用)\n const theme: ThemeContext = { tokens: {}, declared: false };\n for (const element of topLevelElements) {\n if (getTagName(element) !== \"Theme\") continue;\n if (theme.declared) {\n errors.push(\n `Only one <Theme> element is allowed, but multiple were found`,\n );\n continue;\n }\n theme.declared = true;\n parseThemeElement(element, theme.tokens, errors);\n }\n\n const slideElements = topLevelElements.filter(\n (element) => getTagName(element) !== \"Theme\",\n );\n\n const nodes: POMNode[] = [];\n for (const slideEl of slideElements) {\n const tagName = getTagName(slideEl);\n if (tagName !== \"Slide\") {\n errors.push(\n `Top-level element must be <Slide> or <Theme>, but got <${tagName}>. Wrap your slide content in <Slide>...</Slide>.`,\n );\n continue;\n }\n if (Object.keys(getAttributes(slideEl)).length > 0) {\n errors.push(`<Slide>: Attributes are not supported`);\n }\n const slideChildren = getChildElements(slideEl);\n if (slideChildren.length === 0) {\n errors.push(`<Slide> must contain at least one child element`);\n continue;\n }\n const converted = slideChildren\n .map((child) => convertElement(child, errors, theme))\n .filter((c): c is Record<string, unknown> => c !== null);\n if (converted.length === 0) continue;\n if (converted.length === 1) {\n nodes.push(converted[0] as POMNode);\n } else {\n nodes.push({\n type: \"vstack\",\n children: converted,\n } as POMNode);\n }\n }\n\n if (errors.length > 0) {\n throw new ParseXmlError(errors);\n }\n\n return nodes;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"parseXml.js","names":[],"sources":["../../src/parseXml/parseXml.ts"],"sourcesContent":["import { XMLBuilder, XMLParser } from \"fast-xml-parser\";\nimport type { z } from \"zod\";\nimport type { POMNode } from \"../types.ts\";\nimport {\n getNodeMetadata,\n getNodeMetadataByTag,\n NODE_METADATA,\n} from \"../registry/nodeMetadata.ts\";\nimport {\n INLINE_BOOLEAN_FORMATS,\n INLINE_FORMAT_TAG_LIST,\n INLINE_FORMAT_TAGS,\n INLINE_LINK_TAG,\n INLINE_MARK_TAG,\n INLINE_SPAN_TAG,\n MARK_DEFAULT_HIGHLIGHT_COLOR,\n formatExpectedTags,\n type NodeSpecificChildRule,\n type RepeatedChildRule,\n type TextRun,\n type XmlChildRule,\n} from \"../registry/xmlChildRules.ts\";\nimport {\n type CoercionRule,\n NODE_COERCION_MAP,\n CHILD_ELEMENT_COERCION_MAP,\n coerceWithRule,\n coerceFallback,\n getObjectShapeFromRule,\n resolveMixedNotationShorthand,\n} from \"./coercionRules.ts\";\n\n// ===== ParseXmlError =====\nexport class ParseXmlError extends Error {\n public readonly errors: string[];\n constructor(errors: string[]) {\n const message = `XML validation failed (${errors.length} error${errors.length > 1 ? \"s\" : \"\"}):\\n${errors.map((e) => ` - ${e}`).join(\"\\n\")}`;\n super(message);\n this.name = \"ParseXmlError\";\n this.errors = errors;\n }\n}\n\n// ===== Tag name → POM node type mapping =====\nexport const TAG_TO_TYPE: Record<string, string> = Object.fromEntries(\n NODE_METADATA.map((def) => [def.tagName, def.type]),\n);\n// Attributes allowed on any node (e.g., x/y for Layer children positioning)\nconst UNIVERSAL_ATTRS = new Set([\"x\", \"y\"]);\n\n// ===== Validation helpers =====\nfunction getKnownAttributes(nodeType: string): string[] {\n const rules = NODE_COERCION_MAP[nodeType];\n if (!rules) return [];\n return Object.keys(rules);\n}\n\nfunction levenshteinDistance(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array<number>(n + 1).fill(0),\n );\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] =\n a[i - 1] === b[j - 1]\n ? dp[i - 1][j - 1]\n : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);\n }\n }\n return dp[m][n];\n}\n\nfunction findClosestMatch(\n input: string,\n candidates: string[],\n): string | undefined {\n const threshold = Math.max(2, Math.floor(input.length / 2));\n let bestMatch: string | undefined;\n let bestDistance = Infinity;\n for (const candidate of candidates) {\n const dist = levenshteinDistance(\n input.toLowerCase(),\n candidate.toLowerCase(),\n );\n if (dist < bestDistance && dist <= threshold) {\n bestDistance = dist;\n bestMatch = candidate;\n }\n }\n return bestMatch;\n}\n\nfunction getKnownChildAttributes(tagName: string): string[] {\n const rules = CHILD_ELEMENT_COERCION_MAP[tagName];\n if (!rules) return [];\n return Object.keys(rules);\n}\n\nfunction formatZodIssue(\n issue: z.core.$ZodIssue,\n tagName: string,\n): string | null {\n const path = issue.path;\n // Skip children-related issues (validated recursively)\n if (path.length > 0 && path[0] === \"children\") return null;\n // Skip \"type\" field issues (set internally)\n if (path.length === 1 && path[0] === \"type\") return null;\n\n const attrName = path.length > 0 ? String(path[0]) : undefined;\n\n const code = issue.code;\n\n if (code === \"invalid_type\") {\n // Missing required attribute\n if (issue.input === undefined) {\n if (attrName) {\n return `<${tagName}>: Missing required attribute \"${attrName}\"`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n // Type mismatch\n if (attrName) {\n return `<${tagName}>: Invalid type for attribute \"${attrName}\". ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n\n if (code === \"invalid_value\") {\n if (attrName) {\n const values = (issue as unknown as { values: string[] }).values;\n if (values) {\n return `<${tagName}>: Invalid value for attribute \"${attrName}\". Expected: ${values.map((v) => `\"${v}\"`).join(\", \")}`;\n }\n return `<${tagName}>: Invalid value for attribute \"${attrName}\". ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n\n if (code === \"too_small\" || code === \"too_big\") {\n if (attrName) {\n return `<${tagName}>: Invalid value for attribute \"${attrName}\". ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n\n // Generic fallback\n if (attrName) {\n return `<${tagName}>: Attribute \"${attrName}\": ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n}\n\n// Properties that may be legitimately absent when using child element notation\n// or when the property is optional in practice (even if required in schema).\nfunction validateLeafNode(\n nodeType: string,\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const def = getNodeMetadata(nodeType as POMNode[\"type\"]);\n if (def.childPolicy.kind === \"pom-children\") return;\n const schema = def.schema;\n const tagName = def.tagName;\n const optionalChildProps = new Set(\n def.childPolicy.kind === \"custom\"\n ? (def.childPolicy.optionalProperties ?? [])\n : [],\n );\n const parseResult = schema.safeParse(result);\n if (!parseResult.success) {\n const seen = new Set<string>();\n for (const issue of parseResult.error.issues) {\n // Skip only top-level missing child-element properties (path.length === 1)\n // Nested issues (e.g., data.children[0].label) must still be reported\n if (\n optionalChildProps.size > 0 &&\n issue.path.length === 1 &&\n optionalChildProps.has(String(issue.path[0])) &&\n issue.code === \"invalid_type\" &&\n issue.input === undefined\n ) {\n continue;\n }\n // Skip issues for universal attributes (x, y)\n if (issue.path.length > 0 && UNIVERSAL_ATTRS.has(String(issue.path[0]))) {\n continue;\n }\n const msg = formatZodIssue(issue, tagName);\n if (msg && !seen.has(msg)) {\n seen.add(msg);\n errors.push(msg);\n }\n }\n }\n}\n\n// ===== Types for XML parser output (preserveOrder mode) =====\ntype XmlNode = XmlElement | XmlTextNode;\ntype XmlTextNode = { \"#text\": string };\ninterface XmlElement {\n [tagName: string]: XmlNode[] | Record<string, string> | undefined;\n \":@\"?: Record<string, string>;\n}\n\n// ===== Coercion rule lookup =====\n\nfunction getCoercionRule(\n nodeType: string,\n propertyName: string,\n): CoercionRule | undefined {\n return NODE_COERCION_MAP[nodeType]?.[propertyName];\n}\n\n// ===== Dot notation helpers =====\n\n// ===== Dot notation expansion =====\nfunction expandDotNotation(attrs: Record<string, string>): {\n regular: Record<string, string>;\n dotGroups: Record<string, Record<string, string>>;\n} {\n const regular: Record<string, string> = {};\n const dotGroups: Record<string, Record<string, string>> = {};\n\n for (const [key, value] of Object.entries(attrs)) {\n const dotIndex = key.indexOf(\".\");\n if (dotIndex > 0) {\n const prefix = key.substring(0, dotIndex);\n const suffix = key.substring(dotIndex + 1);\n if (!dotGroups[prefix]) dotGroups[prefix] = {};\n dotGroups[prefix][suffix] = value;\n } else {\n regular[key] = value;\n }\n }\n\n return { regular, dotGroups };\n}\n\nfunction coerceDotGroup(\n prefix: string,\n subAttrs: Record<string, string>,\n rule: CoercionRule,\n tagName: string,\n errors: string[],\n): Record<string, unknown> {\n const objectShape = getObjectShapeFromRule(rule);\n\n const obj: Record<string, unknown> = {};\n if (objectShape) {\n for (const [subKey, subValue] of Object.entries(subAttrs)) {\n if (objectShape[subKey]) {\n const coerced = coerceWithRule(subValue, objectShape[subKey]);\n if (coerced.error !== null) {\n errors.push(`<${tagName}>: ${prefix}.${subKey}: ${coerced.error}`);\n } else {\n obj[subKey] = coerced.value;\n }\n } else {\n const knownSubKeys = Object.keys(objectShape);\n const suggestion = findClosestMatch(subKey, knownSubKeys);\n errors.push(\n `<${tagName}>: Unknown sub-attribute \"${prefix}.${subKey}\"${suggestion ? `. Did you mean \"${prefix}.${suggestion}\"?` : \"\"}`,\n );\n }\n }\n } else {\n errors.push(\n `<${tagName}>: Attribute \"${prefix}\" does not support dot notation`,\n );\n }\n return obj;\n}\n\n// ===== XML node helpers =====\nfunction isTextNode(node: XmlNode): node is XmlTextNode {\n return \"#text\" in node;\n}\n\nfunction getTagName(node: XmlElement): string {\n for (const key of Object.keys(node)) {\n if (key !== \":@\") return key;\n }\n throw new Error(\"No tag name found in XML element\");\n}\n\nfunction getAttributes(node: XmlElement): Record<string, string> {\n const attrs: Record<string, string> = {};\n const rawAttrs = node[\":@\"];\n if (rawAttrs) {\n for (const [key, value] of Object.entries(rawAttrs)) {\n const attrName = key.startsWith(\"@_\") ? key.slice(2) : key;\n attrs[attrName] = value.trim();\n }\n }\n return attrs;\n}\n\nfunction getChildElements(node: XmlElement): XmlElement[] {\n const tagName = getTagName(node);\n const children = node[tagName] as XmlNode[] | undefined;\n if (!children) return [];\n return children.filter((child): child is XmlElement => !isTextNode(child));\n}\n\nfunction getTextContent(node: XmlElement): string | undefined {\n const tagName = getTagName(node);\n const children = node[tagName] as XmlNode[] | undefined;\n if (!children) return undefined;\n const textParts: string[] = [];\n for (const child of children) {\n if (isTextNode(child)) {\n textParts.push(child[\"#text\"]);\n }\n }\n return textParts.length > 0 ? textParts.join(\"\") : undefined;\n}\n\nfunction getRawChildren(node: XmlElement): XmlNode[] {\n const tagName = getTagName(node);\n return (node[tagName] as XmlNode[] | undefined) ?? [];\n}\n\nfunction hasInlineFormatChildren(childElements: XmlElement[]): boolean {\n return (\n childElements.length > 0 &&\n childElements.every((el) => INLINE_FORMAT_TAGS.has(getTagName(el)))\n );\n}\n\nfunction extractTextRuns(\n children: XmlNode[],\n inherited: Partial<Omit<TextRun, \"text\">> = {},\n): TextRun[] {\n const runs: TextRun[] = [];\n for (const child of children) {\n if (isTextNode(child)) {\n runs.push({ text: child[\"#text\"], ...inherited });\n continue;\n }\n const tag = getTagName(child);\n const innerChildren = getRawChildren(child);\n const booleanFormat = INLINE_BOOLEAN_FORMATS.find(\n (format) => format.tag === tag,\n );\n if (booleanFormat) {\n const next: Partial<Omit<TextRun, \"text\">> = {\n ...inherited,\n [booleanFormat.property]: true,\n };\n // subscript と superscript は OOXML の baseline 値として相互排他\n // (同時 true は描画結果が未定義になる)。後で立てた側を優先して反対側を解除する。\n if (booleanFormat.property === \"subscript\") delete next.superscript;\n if (booleanFormat.property === \"superscript\") delete next.subscript;\n runs.push(...extractTextRuns(innerChildren, next));\n } else if (tag === INLINE_LINK_TAG) {\n // href なしの <A> は外側の href を引き継がない(リンク解除として扱う)\n const next = { ...inherited };\n const href = getAttributes(child).href;\n if (href) {\n next.href = href;\n } else {\n delete next.href;\n }\n runs.push(...extractTextRuns(innerChildren, next));\n } else if (tag === INLINE_MARK_TAG) {\n const rawColor = getAttributes(child).color;\n const highlight =\n rawColor && rawColor.trim() ? rawColor : MARK_DEFAULT_HIGHLIGHT_COLOR;\n runs.push(...extractTextRuns(innerChildren, { ...inherited, highlight }));\n } else if (tag === INLINE_SPAN_TAG) {\n const spanAttrs = getAttributes(child);\n const next = { ...inherited };\n if (spanAttrs.color && spanAttrs.color.trim()) {\n next.color = spanAttrs.color;\n }\n if (spanAttrs.fontFamily && spanAttrs.fontFamily.trim()) {\n next.fontFamily = spanAttrs.fontFamily;\n }\n if (spanAttrs.fontSize && spanAttrs.fontSize.trim()) {\n next.fontSize = Number(spanAttrs.fontSize);\n }\n if (spanAttrs.letterSpacing && spanAttrs.letterSpacing.trim()) {\n next.letterSpacing = Number(spanAttrs.letterSpacing);\n }\n runs.push(...extractTextRuns(innerChildren, next));\n }\n }\n return runs;\n}\n\nfunction buildRunsAndText(\n node: XmlElement,\n): { runs: TextRun[]; text: string } | null {\n const rawChildren = getRawChildren(node);\n const childElements = rawChildren.filter(\n (c): c is XmlElement => !isTextNode(c),\n );\n if (!hasInlineFormatChildren(childElements)) return null;\n const runs = extractTextRuns(rawChildren);\n const text = runs.map((r) => r.text).join(\"\");\n return { runs, text };\n}\n\nfunction coerceChildAttrs(\n parentTagName: string,\n tagName: string,\n attrs: Record<string, string>,\n errors: string[],\n): Record<string, unknown> {\n const rules = CHILD_ELEMENT_COERCION_MAP[tagName];\n const result: Record<string, unknown> = {};\n const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);\n\n // Process dot-notation attributes\n for (const [prefix, subAttrs] of Object.entries(dotGroups)) {\n if (rules && rules[prefix]) {\n result[prefix] = coerceDotGroup(\n prefix,\n subAttrs,\n rules[prefix],\n `${parentTagName}.${tagName}`,\n errors,\n );\n } else if (rules) {\n const knownAttrs = getKnownChildAttributes(tagName);\n const suggestion = findClosestMatch(prefix, knownAttrs);\n errors.push(\n `<${parentTagName}>.<${tagName}>: Unknown attribute \"${prefix}\"${suggestion ? `. Did you mean \"${suggestion}\"?` : \"\"}`,\n );\n } else {\n result[prefix] = {};\n for (const [subKey, subValue] of Object.entries(subAttrs)) {\n (result[prefix] as Record<string, unknown>)[subKey] =\n coerceFallback(subValue);\n }\n }\n }\n\n // Process regular attributes\n for (const [key, value] of Object.entries(regularAttrs)) {\n if (key in dotGroups) {\n if (rules && rules[key]) {\n const resolved = resolveMixedNotationShorthand(value, rules[key]);\n if (resolved.mode === \"ignore\") {\n continue;\n }\n if (resolved.mode === \"merge\") {\n result[key] = {\n ...resolved.value,\n ...(result[key] as Record<string, unknown>),\n };\n continue;\n }\n }\n errors.push(\n `<${parentTagName}>.<${tagName}>: Attribute \"${key}\" conflicts with dot-notation attributes. Use one or the other, not both`,\n );\n continue;\n }\n if (rules && rules[key]) {\n const coerced = coerceWithRule(value, rules[key]);\n if (coerced.error !== null) {\n errors.push(`<${parentTagName}>.<${tagName}>: ${coerced.error}`);\n } else {\n result[key] = coerced.value;\n }\n } else if (rules) {\n // Unknown attribute on child element\n const knownAttrs = getKnownChildAttributes(tagName);\n const suggestion = findClosestMatch(key, knownAttrs);\n errors.push(\n `<${parentTagName}>.<${tagName}>: Unknown attribute \"${key}\"${suggestion ? `. Did you mean \"${suggestion}\"?` : \"\"}`,\n );\n } else {\n result[key] = coerceFallback(value);\n }\n }\n return result;\n}\n\n// ===== Child element converters =====\n\nfunction unknownChildError(\n childTag: string,\n parentTag: string,\n expectedTags: readonly string[],\n): string {\n return `Unknown child element <${childTag}> inside <${parentTag}>. Expected: ${formatExpectedTags(expectedTags)}`;\n}\n\n/** element の text content / インライン装飾を attrs の text / runs へ反映する */\nfunction applyTextAndRuns(\n element: XmlElement,\n attrs: Record<string, unknown>,\n): void {\n const runsResult = buildRunsAndText(element);\n if (runsResult) {\n attrs.runs = runsResult.runs;\n attrs.text = runsResult.text;\n } else {\n const textContent = getTextContent(element);\n if (textContent !== undefined && !(\"text\" in attrs)) {\n attrs.text = textContent;\n }\n }\n}\n\n/** RepeatedChildRule (単一種類の child tag の繰り返し → 配列 property) の汎用 converter */\nfunction convertRepeatedChildren(\n rule: RepeatedChildRule,\n parentTag: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const items: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n if (tag !== rule.childTag) {\n errors.push(unknownChildError(tag, parentTag, [rule.childTag]));\n continue;\n }\n const attrs = coerceChildAttrs(\n parentTag,\n tag,\n getAttributes(child),\n errors,\n );\n if (rule.allowsItemText) {\n applyTextAndRuns(child, attrs);\n }\n items.push(attrs);\n }\n result[rule.property] = items;\n}\n\n/** NodeSpecificChildRule を処理する専用 converter のシグネチャ */\ntype NodeSpecificChildConverter = (\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n) => void;\n\nfunction convertMatrixChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const items: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n switch (tag) {\n case \"MatrixAxes\":\n result.axes = coerceChildAttrs(\n tagName,\n tag,\n getAttributes(child),\n errors,\n );\n break;\n case \"MatrixQuadrants\":\n result.quadrants = coerceChildAttrs(\n tagName,\n tag,\n getAttributes(child),\n errors,\n );\n break;\n case \"MatrixItem\":\n items.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n default:\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n }\n }\n if (items.length > 0) {\n result.items = items;\n }\n}\n\nfunction convertFlowChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const nodes: Record<string, unknown>[] = [];\n const connections: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n switch (tag) {\n case \"FlowNode\":\n nodes.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n case \"FlowConnection\":\n connections.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n default:\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n }\n }\n if (nodes.length > 0) {\n result.nodes = nodes;\n }\n if (connections.length > 0) {\n result.connections = connections;\n }\n}\n\nfunction convertChartChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const data: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n if (tag !== \"ChartSeries\") {\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n continue;\n }\n const attrs = getAttributes(child);\n const series: Record<string, unknown> = {\n labels: [],\n values: [],\n };\n if (attrs.name !== undefined) {\n // chartDataSchema.name は z.string().optional() なのでそのまま文字列として使用\n series.name = attrs.name;\n }\n\n for (const dp of getChildElements(child)) {\n const dpTag = getTagName(dp);\n if (dpTag !== \"ChartDataPoint\") {\n errors.push(\n unknownChildError(dpTag, \"ChartSeries\", [\"ChartDataPoint\"]),\n );\n continue;\n }\n const dpAttrs = getAttributes(dp);\n if (dpAttrs.label === undefined) {\n errors.push('<ChartDataPoint> requires a \"label\" attribute');\n }\n if (dpAttrs.value === undefined) {\n errors.push('<ChartDataPoint> requires a \"value\" attribute');\n }\n if (dpAttrs.label === undefined || dpAttrs.value === undefined) {\n continue;\n }\n const numValue = Number(dpAttrs.value);\n if (isNaN(numValue)) {\n errors.push(\n `Cannot convert \"${dpAttrs.value}\" to number in <ChartDataPoint> \"value\" attribute`,\n );\n continue;\n }\n (series.labels as string[]).push(dpAttrs.label);\n (series.values as number[]).push(numValue);\n }\n data.push(series);\n }\n result.data = data;\n}\n\nfunction convertTableChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const columns: Record<string, unknown>[] = [];\n const rows: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n switch (tag) {\n case \"Col\":\n columns.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n case \"Tr\": {\n const rowAttrs = getAttributes(child);\n const cells: Record<string, unknown>[] = [];\n for (const cellEl of getChildElements(child)) {\n const cellTag = getTagName(cellEl);\n if (cellTag !== \"Td\") {\n errors.push(unknownChildError(cellTag, \"Tr\", [\"Td\"]));\n continue;\n }\n const cellAttrs = coerceChildAttrs(\n \"Tr\",\n cellTag,\n getAttributes(cellEl),\n errors,\n );\n applyTextAndRuns(cellEl, cellAttrs);\n cells.push(cellAttrs);\n }\n const row: Record<string, unknown> = { cells };\n if (rowAttrs.height !== undefined) {\n const h = Number(rowAttrs.height);\n if (isNaN(h)) {\n errors.push(\n `Cannot convert \"${rowAttrs.height}\" to number in <Tr> \"height\" attribute`,\n );\n } else {\n row.height = h;\n }\n }\n rows.push(row);\n break;\n }\n default:\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n }\n }\n if (columns.length > 0) {\n result.columns = columns;\n } else if (rows.length > 0) {\n // Col が未指定の場合、行のセル数(colspan 考慮)からデフォルトの columns を自動生成\n const maxCells = Math.max(\n ...rows.map((row) =>\n (row.cells as Record<string, unknown>[]).reduce(\n (sum, cell) => sum + ((cell.colspan as number) ?? 1),\n 0,\n ),\n ),\n );\n result.columns = Array.from({ length: maxCells }, () => ({}));\n }\n if (rows.length > 0) {\n result.rows = rows;\n }\n}\n\nfunction convertTreeItem(\n element: XmlElement,\n errors: string[],\n): Record<string, unknown> {\n const attrs = getAttributes(element);\n if (attrs.label === undefined) {\n errors.push('<TreeItem> requires a \"label\" attribute');\n }\n const item: Record<string, unknown> = {};\n if (attrs.label !== undefined) {\n item.label = attrs.label;\n }\n if (attrs.color !== undefined) {\n item.color = attrs.color;\n }\n if (attrs.textColor !== undefined) {\n item.textColor = attrs.textColor;\n }\n const children = getChildElements(element);\n if (children.length > 0) {\n item.children = children\n .map((child) => {\n const tag = getTagName(child);\n if (tag !== \"TreeItem\") {\n errors.push(unknownChildError(tag, \"TreeItem\", [\"TreeItem\"]));\n return null;\n }\n return convertTreeItem(child, errors);\n })\n .filter((item): item is Record<string, unknown> => item !== null);\n }\n return item;\n}\n\nfunction convertTreeChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n if (childElements.length !== 1) {\n errors.push(\n `<Tree> must have exactly 1 <TreeItem> child element, but got ${childElements.length}`,\n );\n return;\n }\n const child = childElements[0];\n const tag = getTagName(child);\n if (tag !== \"TreeItem\") {\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n return;\n }\n result.data = convertTreeItem(child, errors);\n}\n\n// SVG 要素を XML 文字列に再構築する\nconst svgBuilder = new XMLBuilder({\n preserveOrder: true,\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n});\n\nfunction serializeSvgElement(svgElement: XmlElement): string {\n return String(svgBuilder.build([svgElement]));\n}\n\nfunction convertSvgChildren(\n _rule: NodeSpecificChildRule,\n _tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n if (childElements.length !== 1) {\n errors.push(\n `<Svg>: Expected exactly one <svg> child element, but found ${childElements.length} child element(s)`,\n );\n return;\n }\n\n const child = childElements[0];\n const tag = getTagName(child);\n if (tag !== \"svg\") {\n errors.push(`<Svg>: Expected <svg> child element, but found <${tag}>`);\n return;\n }\n\n result.svgContent = serializeSvgElement(child);\n}\n\nfunction convertInlineRunsChildren(\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n node?: XmlElement,\n): void {\n // インラインフォーマットタグ以外の子要素がある場合はエラー\n for (const el of childElements) {\n const tag = getTagName(el);\n if (!INLINE_FORMAT_TAGS.has(tag)) {\n const allowedTags = INLINE_FORMAT_TAG_LIST.map((t) => `<${t}>`);\n const allowedList = `${allowedTags.slice(0, -1).join(\", \")}, and ${allowedTags[allowedTags.length - 1]}`;\n errors.push(\n `<${tagName}>: Unexpected child element <${tag}>. Only ${allowedList} are allowed inside <${tagName}>`,\n );\n return;\n }\n }\n if (!node || childElements.length === 0) return;\n const runsResult = buildRunsAndText(node);\n if (runsResult) {\n result.runs = runsResult.runs;\n result.text = runsResult.text;\n }\n}\n\n/** NodeSpecificChildRule を持つノードの専用 converter テーブル */\nconst NODE_SPECIFIC_CHILD_CONVERTERS: Record<\n string,\n NodeSpecificChildConverter\n> = {\n matrix: convertMatrixChildren,\n flow: convertFlowChildren,\n chart: convertChartChildren,\n table: convertTableChildren,\n tree: convertTreeChildren,\n svg: convertSvgChildren,\n};\n\n/** NodeMetadata の xmlChildRule に従って child element を変換する */\nfunction applyXmlChildRule(\n rule: XmlChildRule,\n nodeType: string,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n node?: XmlElement,\n): void {\n if (rule.kind === \"inline-runs\") {\n convertInlineRunsChildren(tagName, childElements, result, errors, node);\n return;\n }\n if (rule.kind === \"repeated\") {\n convertRepeatedChildren(rule, tagName, childElements, result, errors);\n return;\n }\n const converter = NODE_SPECIFIC_CHILD_CONVERTERS[nodeType];\n if (!converter) {\n throw new Error(\n `No node-specific child converter registered for node type: ${nodeType}`,\n );\n }\n converter(rule, tagName, childElements, result, errors);\n}\n\n// ===== Theme tokens =====\nconst THEME_TOKEN_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*$/;\nconst THEME_TOKEN_VALUE_PATTERN = /^[0-9A-Fa-f]{6}$/;\n// 値全体が \"$name\"(\"#\" プレフィックスは任意)のときトークン参照とみなす\nconst TOKEN_REF_PATTERN = /^(#?)\\$([A-Za-z][A-Za-z0-9_-]*)$/;\n// backgroundGradient / textGradient 文字列中に現れる \"$name\" 参照\nconst TOKEN_REF_IN_GRADIENT_PATTERN = /#?\\$([A-Za-z][A-Za-z0-9_-]*)/g;\n\nfunction parseThemeElement(\n element: XmlElement,\n tokens: Record<string, string>,\n errors: string[],\n): void {\n if (getChildElements(element).length > 0) {\n errors.push(\n `<Theme>: Child elements are not supported. Declare tokens as attributes (e.g. <Theme accent=\"1D4ED8\" />)`,\n );\n }\n for (const [name, rawValue] of Object.entries(getAttributes(element))) {\n if (!THEME_TOKEN_NAME_PATTERN.test(name)) {\n errors.push(\n `<Theme>: Invalid token name \"${name}\". Token names must start with a letter and contain only letters, digits, \"_\", and \"-\"`,\n );\n continue;\n }\n const value = rawValue.replace(/^#/, \"\");\n if (!THEME_TOKEN_VALUE_PATTERN.test(value)) {\n errors.push(\n `<Theme>: Invalid color value \"${rawValue}\" for token \"${name}\". Expected 6-digit hex (e.g. \"1D4ED8\")`,\n );\n continue;\n }\n tokens[name] = value;\n }\n}\n\n// トークン参照を解決する対象のキー判定。\n// pom の色属性は \"...Color\" / \"...Colors\" / \"highlight\" に統一されているため、\n// キー名ベースで判定することでテキスト内容(text 等)の \"$...\" を誤置換しない。\nfunction isColorKey(key: string): boolean {\n return /colors?$/i.test(key) || key === \"highlight\";\n}\n\nfunction resolveThemeToken(\n name: string,\n hashPrefix: string,\n tokens: Record<string, string>,\n themeDeclared: boolean,\n errors: string[],\n): string | undefined {\n const value = tokens[name];\n if (value !== undefined) {\n return `${hashPrefix}${value}`;\n }\n if (!themeDeclared) {\n errors.push(\n `Theme token \"$${name}\" is referenced, but no <Theme> is declared. Add a top-level <Theme ${name}=\"RRGGBB\" /> element`,\n );\n } else {\n const suggestion = findClosestMatch(name, Object.keys(tokens));\n errors.push(\n `Unknown theme token \"$${name}\"${suggestion ? `. Did you mean \"$${suggestion}\"?` : \"\"}`,\n );\n }\n return undefined;\n}\n\ninterface ThemeContext {\n tokens: Record<string, string>;\n declared: boolean;\n}\n\nfunction resolveThemeTokensDeep(\n value: unknown,\n key: string | null,\n tokens: Record<string, string>,\n themeDeclared: boolean,\n errors: string[],\n): unknown {\n if (typeof value === \"string\") {\n if (key === \"backgroundGradient\" || key === \"textGradient\") {\n return value.replace(\n TOKEN_REF_IN_GRADIENT_PATTERN,\n (matched, name: string) => {\n const resolved = resolveThemeToken(\n name,\n \"#\",\n tokens,\n themeDeclared,\n errors,\n );\n return resolved ?? matched;\n },\n );\n }\n if (key !== null && isColorKey(key)) {\n const match = TOKEN_REF_PATTERN.exec(value.trim());\n if (match) {\n const resolved = resolveThemeToken(\n match[2],\n match[1],\n tokens,\n themeDeclared,\n errors,\n );\n return resolved ?? value;\n }\n }\n return value;\n }\n if (Array.isArray(value)) {\n // 配列はキー文脈を維持して要素ごとに解決する(chartColors 等の文字列配列に対応)\n return value.map((item) =>\n resolveThemeTokensDeep(item, key, tokens, themeDeclared, errors),\n );\n }\n if (typeof value === \"object\" && value !== null) {\n const result: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n result[childKey] = resolveThemeTokensDeep(\n childValue,\n childKey,\n tokens,\n themeDeclared,\n errors,\n );\n }\n return result;\n }\n return value;\n}\n\n// ===== Node conversion =====\nfunction convertElement(\n node: XmlElement,\n errors: string[],\n theme: ThemeContext,\n): Record<string, unknown> | null {\n const tagName = getTagName(node);\n const def = getNodeMetadataByTag(tagName);\n const attrs = getAttributes(node);\n const childElements = getChildElements(node);\n const textContent = getTextContent(node);\n\n if (def) {\n return convertPomNode(\n def.type,\n tagName,\n attrs,\n childElements,\n textContent,\n errors,\n theme,\n node,\n );\n } else {\n errors.push(`Unknown tag: <${tagName}>`);\n return null;\n }\n}\n\nfunction convertPomNode(\n nodeType: string,\n tagName: string,\n attrs: Record<string, string>,\n childElements: XmlElement[],\n textContent: string | undefined,\n errors: string[],\n theme: ThemeContext,\n xmlNode?: XmlElement,\n): Record<string, unknown> {\n const result: Record<string, unknown> = { type: nodeType };\n const def = getNodeMetadata(nodeType as POMNode[\"type\"]);\n\n // Expand dot-notation attributes (e.g., fill.color=\"hex\" → { fill: { color: \"hex\" } })\n const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);\n\n for (const [prefix, subAttrs] of Object.entries(dotGroups)) {\n if (prefix === \"type\") continue;\n const rule = getCoercionRule(nodeType, prefix);\n if (rule) {\n result[prefix] = coerceDotGroup(prefix, subAttrs, rule, tagName, errors);\n } else {\n const knownAttrs = getKnownAttributes(nodeType);\n const suggestion = findClosestMatch(prefix, knownAttrs);\n if (suggestion) {\n errors.push(\n `<${tagName}>: Unknown attribute \"${prefix}\". Did you mean \"${suggestion}\"?`,\n );\n } else {\n errors.push(`<${tagName}>: Unknown attribute \"${prefix}\"`);\n }\n }\n }\n\n for (const [key, value] of Object.entries(regularAttrs)) {\n if (key === \"type\") continue;\n // Conflict check: dot-notation and regular attribute for the same key\n if (key in dotGroups) {\n const ruleForConflict = getCoercionRule(nodeType, key);\n if (ruleForConflict) {\n const resolved = resolveMixedNotationShorthand(value, ruleForConflict);\n if (resolved.mode === \"ignore\") {\n continue;\n }\n if (resolved.mode === \"merge\") {\n result[key] = {\n ...resolved.value,\n ...(result[key] as Record<string, unknown>),\n };\n continue;\n }\n }\n errors.push(\n `<${tagName}>: Attribute \"${key}\" conflicts with dot-notation attributes (e.g., \"${key}.xxx\"). Use one or the other, not both`,\n );\n continue;\n }\n const rule = getCoercionRule(nodeType, key);\n if (rule) {\n const coerced = coerceWithRule(value, rule);\n if (coerced.error !== null) {\n errors.push(`<${tagName}>: ${coerced.error}`);\n } else {\n result[key] = coerced.value;\n }\n } else if (UNIVERSAL_ATTRS.has(key)) {\n // Allow universal attributes (e.g., x/y for Layer children)\n result[key] = coerceFallback(value);\n } else {\n // Unknown attribute\n const knownAttrs = getKnownAttributes(nodeType);\n const suggestion = findClosestMatch(key, knownAttrs);\n if (suggestion) {\n errors.push(\n `<${tagName}>: Unknown attribute \"${key}\". Did you mean \"${suggestion}\"?`,\n );\n } else {\n errors.push(`<${tagName}>: Unknown attribute \"${key}\"`);\n }\n }\n }\n\n // Text content → text property for nodes that support it\n if (textContent !== undefined && def.textContentProperty) {\n if (!(def.textContentProperty in result)) {\n result[def.textContentProperty] = textContent;\n }\n }\n\n // Child element notation for complex properties\n const childRule = def.xmlChildRule;\n if (childRule && childElements.length > 0) {\n applyXmlChildRule(\n childRule,\n nodeType,\n tagName,\n childElements,\n result,\n errors,\n xmlNode,\n );\n }\n // Children for container nodes\n else if (def.childPolicy.kind === \"pom-children\") {\n const convertedChildren = childElements\n .map((child) => convertElement(child, errors, theme))\n .filter((child): child is Record<string, unknown> => child !== null);\n result.children = convertedChildren;\n }\n // Leaf nodes that shouldn't have child elements\n else if (!childRule && childElements.length > 0) {\n errors.push(\n `<${tagName}>: Unexpected child elements. <${tagName}> does not accept child elements`,\n );\n }\n\n // テーマトークン参照(色属性中の \"$name\")を Zod 検証より前に解決する。\n // children は各子ノードの convertPomNode で解決済みのためスキップする。\n for (const [key, value] of Object.entries(result)) {\n if (key === \"type\" || key === \"children\") continue;\n result[key] = resolveThemeTokensDeep(\n value,\n key,\n theme.tokens,\n theme.declared,\n errors,\n );\n }\n\n // Zod validation for leaf nodes\n if (def.childPolicy.kind !== \"pom-children\") {\n validateLeafNode(nodeType, result, errors);\n }\n\n // Icon: normalize color / bgColor\n if (nodeType === \"icon\") {\n if (typeof result.color === \"string\" && !result.color.startsWith(\"#\")) {\n result.color = `#${result.color}`;\n }\n if (typeof result.bgColor === \"string\" && !result.bgColor.startsWith(\"#\")) {\n result.bgColor = `#${result.bgColor}`;\n }\n }\n\n // Svg: normalize color and validate svgContent\n if (nodeType === \"svg\") {\n if (typeof result.color === \"string\" && !result.color.startsWith(\"#\")) {\n result.color = `#${result.color}`;\n }\n if (result.svgContent === undefined) {\n errors.push(\"<Svg>: A <svg> child element is required\");\n }\n }\n\n return result;\n}\n\n/**\n * XML 文字列を POMNode 配列に変換する。\n *\n * 最上位は `<Slide>` 要素と `<Theme>` 要素のみが許容される。各 `<Slide>` が\n * 1 つのスライドに対応し、その子要素がスライドのルート POMNode となる。\n * 子要素が複数ある場合は暗黙的に VStack でラップされる。\n *\n * `<Theme>` は文書全体に適用されるデザイントークン(配色)の宣言で、最大 1 つ\n * 置ける。属性名がトークン名、属性値が 6 桁 hex の色値となり、各ノードの色属性\n * から `$トークン名` で参照できる。参照は parse 時に解決されるため、返される\n * POMNode には解決済みの hex 値が入る(`<Theme>` 自体はノードにならない)。\n *\n * XML タグは POM ノードタイプにマッピングされ、属性値は Zod スキーマを参照して\n * 適切な型(number, boolean, array, object)に変換される。\n * 未知のタグ名が指定された場合はエラーがスローされる。\n *\n * @example\n * ```typescript\n * import { parseXml, buildPptx } from \"@hirokisakabe/pom\";\n *\n * const xml = `\n * <Slide>\n * <VStack gap=\"16\" padding=\"32\">\n * <Text fontSize=\"32\" bold=\"true\">売上レポート</Text>\n * </VStack>\n * </Slide>\n * `;\n *\n * const nodes = parseXml(xml);\n * const pptx = await buildPptx(nodes, { w: 1280, h: 720 });\n * ```\n */\nexport function parseXml(xmlString: string): POMNode[] {\n if (!xmlString.trim()) return [];\n\n const parser = new XMLParser({\n preserveOrder: true,\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n parseAttributeValue: false,\n parseTagValue: false,\n trimValues: false,\n });\n\n const wrappedXml = `<__root__>${xmlString}</__root__>`;\n const parsed: XmlElement[] = parser.parse(wrappedXml) as XmlElement[];\n\n if (!parsed || parsed.length === 0) return [];\n\n const rootElement = parsed[0];\n const rootChildren = (rootElement[\"__root__\"] ?? []) as XmlNode[];\n\n const errors: string[] = [];\n const topLevelElements = rootChildren.filter(\n (child): child is XmlElement => !isTextNode(child),\n );\n\n // <Theme> はスライドより先に収集する(出現位置によらず文書全体に適用)\n const theme: ThemeContext = { tokens: {}, declared: false };\n for (const element of topLevelElements) {\n if (getTagName(element) !== \"Theme\") continue;\n if (theme.declared) {\n errors.push(\n `Only one <Theme> element is allowed, but multiple were found`,\n );\n continue;\n }\n theme.declared = true;\n parseThemeElement(element, theme.tokens, errors);\n }\n\n const slideElements = topLevelElements.filter(\n (element) => getTagName(element) !== \"Theme\",\n );\n\n const nodes: POMNode[] = [];\n for (const slideEl of slideElements) {\n const tagName = getTagName(slideEl);\n if (tagName !== \"Slide\") {\n errors.push(\n `Top-level element must be <Slide> or <Theme>, but got <${tagName}>. Wrap your slide content in <Slide>...</Slide>.`,\n );\n continue;\n }\n if (Object.keys(getAttributes(slideEl)).length > 0) {\n errors.push(`<Slide>: Attributes are not supported`);\n }\n const slideChildren = getChildElements(slideEl);\n if (slideChildren.length === 0) {\n errors.push(`<Slide> must contain at least one child element`);\n continue;\n }\n const converted = slideChildren\n .map((child) => convertElement(child, errors, theme))\n .filter((c): c is Record<string, unknown> => c !== null);\n if (converted.length === 0) continue;\n if (converted.length === 1) {\n nodes.push(converted[0] as POMNode);\n } else {\n nodes.push({\n type: \"vstack\",\n children: converted,\n } as POMNode);\n }\n }\n\n if (errors.length > 0) {\n throw new ParseXmlError(errors);\n }\n\n return nodes;\n}\n"],"mappings":"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"}
|