@pixerate/editor 0.23.0 → 0.25.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 +167 -2
- package/THIRD_PARTY_NOTICES.md +80 -0
- package/dist/agent/index.cjs +10 -8
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +4 -3
- package/dist/agent/index.d.ts +4 -3
- package/dist/agent/index.js +4 -2
- package/dist/agent/index.js.map +1 -1
- package/dist/canvas/index.cjs +4437 -411
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +934 -4
- package/dist/canvas/index.d.ts +934 -4
- package/dist/canvas/index.js +4309 -283
- package/dist/canvas/index.js.map +1 -1
- package/dist/chunk-4BVP64JJ.cjs +1406 -0
- package/dist/chunk-4BVP64JJ.cjs.map +1 -0
- package/dist/chunk-664LQYFJ.js +115 -0
- package/dist/chunk-664LQYFJ.js.map +1 -0
- package/dist/chunk-7WISYZFO.cjs +740 -0
- package/dist/chunk-7WISYZFO.cjs.map +1 -0
- package/dist/chunk-AL6JMGWW.cjs +783 -0
- package/dist/chunk-AL6JMGWW.cjs.map +1 -0
- package/dist/chunk-BVP3TSLH.cjs +69 -0
- package/dist/chunk-BVP3TSLH.cjs.map +1 -0
- package/dist/{chunk-RIKBJLS2.cjs → chunk-C7P22VIP.cjs} +2001 -279
- package/dist/chunk-C7P22VIP.cjs.map +1 -0
- package/dist/chunk-D6FH2YAX.cjs +131 -0
- package/dist/chunk-D6FH2YAX.cjs.map +1 -0
- package/dist/chunk-ECCCYKGL.js +740 -0
- package/dist/chunk-ECCCYKGL.js.map +1 -0
- package/dist/{chunk-4SUNJZWB.cjs → chunk-FD4LPFAE.cjs} +48 -200
- package/dist/chunk-FD4LPFAE.cjs.map +1 -0
- package/dist/{chunk-QBJ22YZR.js → chunk-FH6F67DN.js} +1999 -277
- package/dist/chunk-FH6F67DN.js.map +1 -0
- package/dist/{chunk-OYXSKQFR.js → chunk-FPENXAEJ.js} +35 -187
- package/dist/chunk-FPENXAEJ.js.map +1 -0
- package/dist/chunk-HLIMTC6N.js +1 -0
- package/dist/chunk-HLIMTC6N.js.map +1 -0
- package/dist/chunk-HRMEDT2L.js +1406 -0
- package/dist/chunk-HRMEDT2L.js.map +1 -0
- package/dist/{chunk-QGHGJ56O.js → chunk-IXHSYOVY.js} +2518 -122
- package/dist/chunk-IXHSYOVY.js.map +1 -0
- package/dist/chunk-MKA3AHLV.cjs +256 -0
- package/dist/chunk-MKA3AHLV.cjs.map +1 -0
- package/dist/chunk-NAXVVS5I.js +783 -0
- package/dist/chunk-NAXVVS5I.js.map +1 -0
- package/dist/chunk-O5RYH2PG.js +69 -0
- package/dist/chunk-O5RYH2PG.js.map +1 -0
- package/dist/chunk-OXSV64JX.js +689 -0
- package/dist/chunk-OXSV64JX.js.map +1 -0
- package/dist/chunk-P3RQ5UJE.cjs +689 -0
- package/dist/chunk-P3RQ5UJE.cjs.map +1 -0
- package/dist/chunk-P6ODPZ4W.js +256 -0
- package/dist/chunk-P6ODPZ4W.js.map +1 -0
- package/dist/chunk-PL4JB3BF.cjs +1 -0
- package/dist/chunk-PL4JB3BF.cjs.map +1 -0
- package/dist/{chunk-GVSMRPHB.cjs → chunk-PO6A6QQH.cjs} +2607 -211
- package/dist/chunk-PO6A6QQH.cjs.map +1 -0
- package/dist/{chunk-JJDLPEWL.js → chunk-QGYDWPRM.js} +2 -2
- package/dist/chunk-RR7F5GUM.js +5726 -0
- package/dist/chunk-RR7F5GUM.js.map +1 -0
- package/dist/chunk-TNNJXF46.cjs +115 -0
- package/dist/chunk-TNNJXF46.cjs.map +1 -0
- package/dist/chunk-U5HZSFCS.js +131 -0
- package/dist/chunk-U5HZSFCS.js.map +1 -0
- package/dist/{chunk-MJZBNWG7.js → chunk-UAKDG62Z.js} +309 -581
- package/dist/chunk-UAKDG62Z.js.map +1 -0
- package/dist/{chunk-CL37JGFW.cjs → chunk-V3CHHWOE.cjs} +4 -4
- package/dist/{chunk-CL37JGFW.cjs.map → chunk-V3CHHWOE.cjs.map} +1 -1
- package/dist/chunk-WSQKHXW7.cjs +5726 -0
- package/dist/chunk-WSQKHXW7.cjs.map +1 -0
- package/dist/{chunk-AA4ZEVCC.cjs → chunk-X4N4WUKB.cjs} +336 -608
- package/dist/chunk-X4N4WUKB.cjs.map +1 -0
- package/dist/commands/index.cjs +74 -1
- package/dist/commands/index.cjs.map +1 -1
- package/dist/commands/index.d.cts +38 -353
- package/dist/commands/index.d.ts +38 -353
- package/dist/commands/index.js +73 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/comment-store-BEMgVlAA.d.cts +135 -0
- package/dist/comment-store-BEMgVlAA.d.ts +135 -0
- package/dist/compare/index.cjs +15 -0
- package/dist/compare/index.cjs.map +1 -0
- package/dist/compare/index.d.cts +58 -0
- package/dist/compare/index.d.ts +58 -0
- package/dist/compare/index.js +15 -0
- package/dist/compare/index.js.map +1 -0
- package/dist/controller-BIJiNoVs.d.cts +1842 -0
- package/dist/controller-BIJiNoVs.d.ts +1842 -0
- package/dist/documents-CHT1U5Vs.d.ts +86 -0
- package/dist/documents-Gp7wb0Me.d.cts +86 -0
- package/dist/extensions/index.cjs +100 -5
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +16 -4
- package/dist/extensions/index.d.ts +16 -4
- package/dist/extensions/index.js +100 -5
- package/dist/generation/index.cjs +2317 -0
- package/dist/generation/index.cjs.map +1 -0
- package/dist/generation/index.d.cts +1015 -0
- package/dist/generation/index.d.ts +1015 -0
- package/dist/generation/index.js +2317 -0
- package/dist/generation/index.js.map +1 -0
- package/dist/grammar/index.cjs +48 -3
- package/dist/grammar/index.cjs.map +1 -1
- package/dist/grammar/index.d.cts +322 -100
- package/dist/grammar/index.d.ts +322 -100
- package/dist/grammar/index.js +54 -9
- package/dist/image-editor/index.cjs +4392 -481
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +1249 -97
- package/dist/image-editor/index.d.ts +1249 -97
- package/dist/image-editor/index.js +4281 -370
- package/dist/image-editor/index.js.map +1 -1
- package/dist/index-7a6bHTLy.d.ts +1754 -0
- package/dist/index-Csd5qI8u.d.cts +1754 -0
- package/dist/index.cjs +1682 -99
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +118 -21
- package/dist/index.d.ts +118 -21
- package/dist/index.js +1630 -47
- package/dist/index.js.map +1 -1
- package/dist/mention-text-CDnCFd3c.d.cts +53 -0
- package/dist/mention-text-CDnCFd3c.d.ts +53 -0
- package/dist/migrate-iTlm3a8h.d.cts +112 -0
- package/dist/migrate-iTlm3a8h.d.ts +112 -0
- package/dist/model-C1zApQM8.d.cts +219 -0
- package/dist/model-C1zApQM8.d.ts +219 -0
- package/dist/persistence/index.cjs +676 -0
- package/dist/persistence/index.cjs.map +1 -0
- package/dist/persistence/index.d.cts +230 -0
- package/dist/persistence/index.d.ts +230 -0
- package/dist/persistence/index.js +676 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/{registry-D5-R90p0.d.cts → registry-BDe-vlv3.d.ts} +2 -40
- package/dist/{registry-GJI4gToU.d.ts → registry-CEgwXED1.d.cts} +12 -1
- package/dist/{registry-GJI4gToU.d.cts → registry-CEgwXED1.d.ts} +12 -1
- package/dist/registry-D32LpIc4.d.cts +354 -0
- package/dist/{registry-D5-R90p0.d.ts → registry-DnzpgY27.d.cts} +2 -40
- package/dist/registry-evKTP4ls.d.ts +354 -0
- package/dist/schema-DYDGdYL9.d.cts +41 -0
- package/dist/schema-DYDGdYL9.d.ts +41 -0
- package/dist/serializers/index.cjs +12 -3
- package/dist/serializers/index.cjs.map +1 -1
- package/dist/serializers/index.d.cts +40 -12
- package/dist/serializers/index.d.ts +40 -12
- package/dist/serializers/index.js +12 -3
- package/dist/sourcemap-C8AH3MBQ.d.cts +91 -0
- package/dist/sourcemap-DA1Evhrv.d.ts +91 -0
- package/dist/spreadsheet/index.cjs +161 -3
- package/dist/spreadsheet/index.cjs.map +1 -1
- package/dist/spreadsheet/index.d.cts +611 -20
- package/dist/spreadsheet/index.d.ts +611 -20
- package/dist/spreadsheet/index.js +168 -10
- package/dist/storage-BpFfspHm.d.cts +120 -0
- package/dist/storage-BpFfspHm.d.ts +120 -0
- package/dist/tokens/index.cjs +115 -0
- package/dist/tokens/index.cjs.map +1 -0
- package/dist/tokens/index.d.cts +212 -0
- package/dist/tokens/index.d.ts +212 -0
- package/dist/tokens/index.js +115 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/{tokens-CyLZmIei.d.cts → tokens-D7yXvUU6.d.cts} +15 -2
- package/dist/{tokens-CyLZmIei.d.ts → tokens-D7yXvUU6.d.ts} +15 -2
- package/dist/{track-changes-BSF58RK0.d.cts → track-changes-D_VAPELi.d.cts} +110 -144
- package/dist/{track-changes-BSF58RK0.d.ts → track-changes-Db_fGEvx.d.ts} +110 -144
- package/package.json +21 -1
- package/dist/chunk-4SUNJZWB.cjs.map +0 -1
- package/dist/chunk-AA4ZEVCC.cjs.map +0 -1
- package/dist/chunk-AXV2ZW34.cjs +0 -118
- package/dist/chunk-AXV2ZW34.cjs.map +0 -1
- package/dist/chunk-B2ZRLN4S.js +0 -118
- package/dist/chunk-B2ZRLN4S.js.map +0 -1
- package/dist/chunk-GVSMRPHB.cjs.map +0 -1
- package/dist/chunk-K3R5NG2D.js +0 -3100
- package/dist/chunk-K3R5NG2D.js.map +0 -1
- package/dist/chunk-MJZBNWG7.js.map +0 -1
- package/dist/chunk-OYXSKQFR.js.map +0 -1
- package/dist/chunk-QBJ22YZR.js.map +0 -1
- package/dist/chunk-QGHGJ56O.js.map +0 -1
- package/dist/chunk-RIKBJLS2.cjs.map +0 -1
- package/dist/chunk-XDMXXC4Z.cjs +0 -3100
- package/dist/chunk-XDMXXC4Z.cjs.map +0 -1
- package/dist/controller-pePCJLT1.d.cts +0 -959
- package/dist/controller-pePCJLT1.d.ts +0 -959
- package/dist/index-CCr_z9kF.d.cts +0 -899
- package/dist/index-Ck6ajwXh.d.ts +0 -899
- /package/dist/{chunk-JJDLPEWL.js.map → chunk-QGYDWPRM.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/grammar/resolver.ts","../src/grammar/sourcemap.ts","../src/grammar/fields.ts","../src/grammar/data-source.ts","../src/grammar/merge.ts"],"sourcesContent":["import {\n TEMPLATE_REGEX,\n VARIABLE_REGEX,\n INSTRUCTION_REGEX,\n Template,\n PromptValues,\n} from \"./tokens\";\nimport { resolvePrompt } from \"./engine\";\nimport { conditionSubject, parseVariableBody } from \"./variables\";\nimport { tokenizePrompt } from \"./tokenizer\";\n\nexport interface ResolveTemplatesOptions {\n bindings?: Record<string, string>;\n maxDepth?: number;\n /**\n * Values for `{variable}` slots and `{?variable}` sections. When omitted,\n * variables, defaults and section tags are left exactly as written.\n */\n values?: PromptValues;\n}\n\n/**\n * Recursively resolves template tags `{{template_name}}` in a given text.\n * A tag that would recurse into itself is replaced with `TEMPLATE_LOOP_ERROR`,\n * and a tag nested deeper than `maxDepth` with `TEMPLATE_DEPTH_ERROR`; the rest\n * of the text still resolves normally.\n *\n * Pass `options.values` to also fill variables (falling back to their\n * `{name|default}`) and evaluate `{?name}…{/name}` / `{!name}…{/name}`\n * sections, including those inside template bodies. See `resolvePrompt` for\n * the source map and diagnostics.\n */\nexport function resolveTemplates(\n text: string,\n templates: Template[] = [],\n options?: ResolveTemplatesOptions,\n): string {\n return resolvePrompt(text, templates, options).text;\n}\n\n/**\n * Replaces `{variableName}` with values from a dictionary, falling back to a\n * `{variableName|default}` when no value is supplied, and evaluates\n * `{?name}…{/name}` / `{!name}…{/name}` sections. Variables with neither a\n * value nor a default are left as written. Templates are not expanded.\n */\nexport function resolveVariables(\n text: string,\n values: PromptValues,\n): string {\n if (!text) return \"\";\n return resolvePrompt(text, [], { values }).text;\n}\n\n/**\n * Extracts unique template names referenced in text.\n */\nexport function extractTemplateNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n\n/**\n * Extracts unique variable names referenced in text, including names used by\n * conditional section tags (`amount` for `{?amount>100}…{/amount}`).\n * Defaults and descriptions are stripped.\n */\nexport function extractVariableNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags);\n let comparisonStarts: Set<number> | undefined;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n const parsed = parseVariableBody(match[1]);\n let name = parsed.name;\n if (parsed.kind === \"conditional\" && parsed.conditional !== \"end\") {\n const subject = conditionSubject(name);\n if (subject) {\n // Only a tag closed by `{/subject}` is a comparison on `subject`.\n comparisonStarts ??= new Set(\n tokenizePrompt(text)\n .filter((token) => token.comparison)\n .map((token) => token.start),\n );\n if (comparisonStarts.has(match.index)) name = subject;\n }\n }\n set.add(name);\n }\n return Array.from(set);\n}\n\n/**\n * Extracts unique instruction names referenced in text.\n */\nexport function extractInstructionNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(INSTRUCTION_REGEX.source, INSTRUCTION_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n","import type { PromptDiagnostic, Template } from \"./tokens\";\nimport type { ResolveTemplatesOptions } from \"./resolver\";\nimport { resolvePrompt } from \"./engine\";\nimport { getPromptDiagnostics } from \"./tokenizer\";\n\n/**\n * One contiguous piece of resolved output and the raw range it came from.\n *\n * - `raw`: copied verbatim; offsets map character by character.\n * - `template`: the expansion of a `{{template}}` tag.\n * - `variable`: a substituted value or `|default` for a `{variable}` tag.\n * - `conditional`: a section tag, or a whole removed section. These segments\n * are empty in the resolved text (`resolvedStart === resolvedEnd`).\n *\n * Offsets inside non-raw segments map to the start of their raw range.\n */\nexport interface SourceMapSegment {\n resolvedStart: number;\n resolvedEnd: number;\n source: \"raw\" | \"template\" | \"variable\" | \"conditional\";\n rawStart: number;\n rawEnd: number;\n templateName?: string;\n /** Variable substituted (`variable`) or tested (`conditional`). */\n variableName?: string;\n /** For `variable` segments: whether a supplied value or the default was used. */\n valueSource?: \"value\" | \"default\";\n}\n\n/**\n * Resolves templates in text while tracking character offset mapping\n * between the raw input and the fully resolved output.\n *\n * Pass `options.values` to also substitute variables and evaluate conditional\n * sections (see `resolvePrompt`); without it the output is unchanged from the\n * template-only behavior.\n */\nexport function resolveTemplatesWithMapping(\n text: string,\n templates: Template[] = [],\n templateBindings?: Record<string, string>,\n options?: Pick<ResolveTemplatesOptions, \"maxDepth\" | \"values\">,\n): { text: string; map: SourceMapSegment[]; diagnostics: PromptDiagnostic[] } {\n if (\n options?.values === undefined &&\n (!templates || templates.length === 0 || !text.includes(\"{{\"))\n ) {\n return {\n diagnostics: getPromptDiagnostics(text),\n text,\n map: [\n {\n resolvedStart: 0,\n resolvedEnd: text.length,\n source: \"raw\",\n rawStart: 0,\n rawEnd: text.length,\n },\n ],\n };\n }\n\n return resolvePrompt(text, templates, {\n bindings: templateBindings,\n maxDepth: options?.maxDepth,\n values: options?.values,\n });\n}\n\n/**\n * Maps an offset in resolved text back to the corresponding offset in raw text.\n */\nexport function mapResolvedOffsetToRaw(\n resolvedOffset: number,\n map: SourceMapSegment[],\n): number {\n for (let i = 0; i < map.length; i++) {\n const seg = map[i];\n const isLast = i === map.length - 1;\n const inRange = isLast\n ? resolvedOffset >= seg.resolvedStart && resolvedOffset <= seg.resolvedEnd\n : resolvedOffset >= seg.resolvedStart && resolvedOffset < seg.resolvedEnd;\n\n if (inRange) {\n if (seg.source === \"raw\") {\n return seg.rawStart + (resolvedOffset - seg.resolvedStart);\n }\n // The end of the text maps to the end of the tag; anywhere inside a\n // resolved template maps to the start of its tag.\n if (resolvedOffset === seg.resolvedEnd) {\n return seg.rawEnd;\n }\n return seg.rawStart;\n }\n }\n return resolvedOffset;\n}\n\n/**\n * Maps an offset in raw text to the corresponding offset in resolved text.\n */\nexport function mapRawOffsetToResolved(\n rawOffset: number,\n map: SourceMapSegment[],\n): number {\n for (let i = 0; i < map.length; i++) {\n const seg = map[i];\n const isLast = i === map.length - 1;\n const inRange = isLast\n ? rawOffset >= seg.rawStart && rawOffset <= seg.rawEnd\n : rawOffset >= seg.rawStart && rawOffset < seg.rawEnd;\n\n if (inRange) {\n if (seg.source === \"raw\") {\n return seg.resolvedStart + (rawOffset - seg.rawStart);\n }\n if (rawOffset === seg.rawEnd) {\n return seg.resolvedEnd;\n }\n return seg.resolvedStart;\n }\n }\n return rawOffset;\n}\n","import type { PromptValues, Template } from \"./tokens\";\nimport { tokenizePrompt } from \"./tokenizer\";\nimport { getTemplateBody } from \"./engine\";\n\n/** Everything a prompt (and, optionally, its templates) says about one variable. */\nexport interface VariableDescriptor {\n name: string;\n /** First `{name|default}` found. */\n defaultValue?: string;\n /** First `{name|default|description}` found. */\n description?: string;\n /** Appears as a `{name}` slot. */\n usedAsValue: boolean;\n /** Appears in a `{?name}` / `{!name}` condition (including comparisons). */\n usedInCondition: boolean;\n /**\n * Present (and `true`) when the variable is compared in a condition such as\n * `{?amount>100}`, so a form should ask for its text, not a checkbox.\n */\n usedInComparison?: true;\n /** Number of `{name…}` slots and condition tags (closing tags excluded). */\n occurrences: number;\n /** Templates whose bodies mention the variable, in discovery order. */\n templates: string[];\n}\n\nexport interface ExtractVariablesOptions {\n /** Templates to search recursively for further variables. */\n templates?: Template[];\n bindings?: Record<string, string>;\n /** Maximum template nesting depth to search (default 10). */\n maxDepth?: number;\n}\n\n/**\n * Lists every variable a prompt uses, in order of first appearance, with its\n * default and description. Templates referenced by the prompt are searched\n * recursively when `options.templates` is given (loops are skipped). All\n * sections are searched, whatever their condition would evaluate to.\n */\nexport function extractVariables(\n text: string,\n options: ExtractVariablesOptions = {},\n): VariableDescriptor[] {\n const descriptors = new Map<string, VariableDescriptor>();\n const templateMap = new Map(\n (options.templates ?? []).map((t) => [t.name, t] as const),\n );\n const maxDepth = options.maxDepth ?? 10;\n\n const describe = (name: string, templateName?: string) => {\n let descriptor = descriptors.get(name);\n if (!descriptor) {\n descriptor = {\n name,\n usedAsValue: false,\n usedInCondition: false,\n occurrences: 0,\n templates: [],\n };\n descriptors.set(name, descriptor);\n }\n descriptor.occurrences++;\n if (templateName && !descriptor.templates.includes(templateName)) {\n descriptor.templates.push(templateName);\n }\n return descriptor;\n };\n\n const visit = (\n source: string,\n visited: Set<string>,\n depth: number,\n templateName?: string,\n ) => {\n for (const token of tokenizePrompt(source)) {\n if (token.type === \"variable\") {\n const descriptor = describe(token.value, templateName);\n descriptor.usedAsValue = true;\n if (descriptor.defaultValue === undefined && token.defaultValue !== undefined) {\n descriptor.defaultValue = token.defaultValue;\n }\n if (descriptor.description === undefined && token.description !== undefined) {\n descriptor.description = token.description;\n }\n } else if (token.type === \"conditional\" && token.conditional !== \"end\") {\n const descriptor = describe(token.value, templateName);\n descriptor.usedInCondition = true;\n if (token.comparison) descriptor.usedInComparison = true;\n } else if (token.type === \"template\") {\n const template = templateMap.get(token.value);\n if (!template || visited.has(token.value) || depth + 1 > maxDepth) {\n continue;\n }\n const body = getTemplateBody(template, options.bindings);\n if (body === undefined) continue;\n visit(body, new Set(visited).add(token.value), depth + 1, token.value);\n }\n }\n };\n\n if (text) visit(text, new Set(), 0);\n return Array.from(descriptors.values());\n}\n\n/** A headless description of one input in a variable fill-in form. */\nexport interface VariableFormField {\n name: string;\n /** The variable's description, or its name. */\n label: string;\n /** The variable's default, or an empty string. */\n placeholder: string;\n defaultValue?: string;\n description?: string;\n /**\n * The variable is used as a slot and has no default, so leaving it blank\n * leaves the `{name}` placeholder in the resolved prompt.\n */\n required: boolean;\n /**\n * Only used by `{?name}` / `{!name}` presence conditions, never substituted\n * or compared (a form can show a checkbox).\n */\n conditionOnly: boolean;\n}\n\n/**\n * Builds field descriptors for a fill-in form (Word's FILLIN analogue): one\n * per variable, labelled with its description and using its default as the\n * placeholder. Feed the entered text through `compactVariableValues` before\n * resolving so blank inputs fall back to defaults.\n */\nexport function getVariableFormFields(\n text: string,\n options: ExtractVariablesOptions = {},\n): VariableFormField[] {\n return extractVariables(text, options).map((variable) => ({\n name: variable.name,\n label: variable.description || variable.name,\n placeholder: variable.defaultValue ?? \"\",\n ...(variable.defaultValue !== undefined\n ? { defaultValue: variable.defaultValue }\n : {}),\n ...(variable.description !== undefined\n ? { description: variable.description }\n : {}),\n required: variable.usedAsValue && variable.defaultValue === undefined,\n conditionOnly: !variable.usedAsValue && !variable.usedInComparison,\n }));\n}\n\n/**\n * Drops blank entries from form input so the resolver falls back to each\n * variable's default (an explicit `\"\"` value would otherwise render as empty).\n */\nexport function compactVariableValues(\n input: Record<string, string | null | undefined>,\n): PromptValues {\n const values: PromptValues = {};\n for (const [name, value] of Object.entries(input)) {\n if (value !== null && value !== undefined && value.trim() !== \"\") {\n values[name] = value;\n }\n }\n return values;\n}\n","// Portions ported from wordcraft/crates/engine/src/cmd/mailings.rs and\n// wordcraft/crates/formats/src/sheet.rs (MIT OR Apache-2.0, © ArtCraft Team\n// and contributors). See THIRD_PARTY_NOTICES.md.\n\n/**\n * Mail-merge data sources: CSV / TSV text, JSON, rows or objects normalised\n * into named fields and string records, plus fuzzy matching of prompt\n * variables to those fields.\n *\n * Imports only the self-contained CSV module, never the spreadsheet entry, so\n * the grammar entry stays light.\n */\nimport { parseCsv } from \"../spreadsheet/csv\";\nimport type { PromptValues } from \"./tokens\";\n\n/** Most records a data source keeps by default. */\nexport const MAX_DATA_SOURCE_RECORDS = 100_000;\n/** Most fields a data source keeps by default. */\nexport const MAX_DATA_SOURCE_FIELDS = 1_000;\n\n/** One record: field name → cell text. */\nexport type MergeRecord = Record<string, string>;\n\n/** Anything `parseDataSource` accepts. */\nexport type DataSourceInput =\n | string\n | ReadonlyArray<ReadonlyArray<unknown>>\n | ReadonlyArray<Readonly<Record<string, unknown>>>;\n\nexport interface ParseDataSourceOptions {\n /**\n * Field separator for delimited text. `\"auto\"` (the default) picks whichever\n * of `,` `;` and tab occurs most often in the first line (outside quotes),\n * preferring `,` on a tie.\n */\n delimiter?: \"auto\" | string;\n /**\n * Whether the first row names the fields (default `true`). Without a header\n * the fields are `Column 1`…`Column N`. Ignored for arrays of objects.\n */\n hasHeader?: boolean;\n /**\n * How to read a string: `\"auto\"` (default) parses text starting with `[` as\n * JSON and falls back to delimited text when that fails.\n */\n format?: \"auto\" | \"csv\" | \"json\";\n /** Record cap (default `MAX_DATA_SOURCE_RECORDS`). */\n maxRecords?: number;\n /** Field cap (default `MAX_DATA_SOURCE_FIELDS`). */\n maxFields?: number;\n}\n\nexport type DataSourceWarningCode =\n | \"empty\"\n | \"invalid-json\"\n | \"unsupported-json\"\n | \"blank-header\"\n | \"duplicate-header\"\n | \"ragged-rows\"\n | \"records-truncated\"\n | \"fields-truncated\";\n\nexport interface DataSourceWarning {\n code: DataSourceWarningCode;\n message: string;\n /** For `ragged-rows`: how many records were padded or cut. */\n count?: number;\n}\n\nexport interface MergeDataSource {\n /** Field names: trimmed, unique (case-insensitively), never blank. */\n fields: string[];\n /** One entry per record, with every field present. */\n records: MergeRecord[];\n warnings: DataSourceWarning[];\n /** How the input was read. */\n format: \"csv\" | \"json\" | \"rows\" | \"objects\";\n /** The delimiter used for delimited text. */\n delimiter?: string;\n}\n\nconst AUTO_DELIMITERS = [\",\", \";\", \"\\t\"];\n\n/** Counts the auto-detect candidates in the first line, ignoring quoted text. */\nexport function detectDelimiter(text: string): string {\n const counts = new Map<string, number>(AUTO_DELIMITERS.map((d) => [d, 0]));\n let quoted = false;\n for (let i = 0; i < text.length; i++) {\n const ch = text[i];\n if (ch === '\"') {\n quoted = !quoted;\n continue;\n }\n if (quoted) continue;\n if (ch === \"\\n\" || ch === \"\\r\") break;\n if (counts.has(ch)) counts.set(ch, counts.get(ch)! + 1);\n }\n let best = \",\";\n for (const d of AUTO_DELIMITERS) {\n if (counts.get(d)! > counts.get(best)!) best = d;\n }\n return best;\n}\n\n/**\n * Field names from a header row: names are trimmed, a blank name becomes\n * `Column N` (its 1-based position), and repeats (compared case-insensitively)\n * are numbered `Name 2`, `Name 3`, ….\n */\nexport function normalizeFieldNames(row: ReadonlyArray<unknown>): string[] {\n const out: string[] = [];\n const taken = new Set<string>();\n row.forEach((cell, i) => {\n const trimmed = cellText(cell).trim();\n const base = trimmed === \"\" ? `Column ${i + 1}` : trimmed;\n let name = base;\n for (let k = 2; taken.has(name.toLowerCase()); k++) name = `${base} ${k}`;\n taken.add(name.toLowerCase());\n out.push(name);\n });\n return out;\n}\n\nfunction cellText(value: unknown): string {\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"string\") return value;\n if (typeof value === \"object\") {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n}\n\n/** Sets an own property, even for names such as `__proto__`. */\nfunction setField(record: MergeRecord, name: string, value: string): void {\n Object.defineProperty(record, name, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n}\n\nfunction isBlankRow(row: ReadonlyArray<unknown>): boolean {\n return row.every((cell) => cellText(cell).trim() === \"\");\n}\n\n/**\n * Reads a mail-merge data source.\n *\n * - **Text**: CSV / TSV (RFC 4180 quoting, doubled quotes, CRLF / LF / CR,\n * a leading BOM ignored) with the delimiter auto-detected, or JSON (an\n * array of objects or of arrays).\n * - **Rows** (`unknown[][]`): the first row is the header unless\n * `hasHeader: false`.\n * - **Objects**: the fields are the union of keys in first-seen order.\n *\n * Blank rows are skipped, header names are normalised (`normalizeFieldNames`),\n * records are padded or cut to the header width, and records and fields are\n * capped. Cells become strings (`null` → `\"\"`, nested values → JSON). Problems\n * are reported in `warnings`; this never throws.\n */\nexport function parseDataSource(\n input: DataSourceInput,\n options: ParseDataSourceOptions = {},\n): MergeDataSource {\n const warnings: DataSourceWarning[] = [];\n if (typeof input === \"string\") {\n const format = options.format ?? \"auto\";\n const trimmed = input.trim();\n if (format === \"json\" || (format === \"auto\" && /^\\[/.test(trimmed))) {\n let parsed: unknown;\n let ok = true;\n try {\n parsed = JSON.parse(trimmed);\n } catch (error) {\n ok = false;\n if (format === \"json\") {\n warnings.push({\n code: \"invalid-json\",\n message: `Invalid JSON: ${(error as Error).message}`,\n });\n return { fields: [], records: [], warnings, format: \"json\" };\n }\n }\n if (ok) {\n if (!Array.isArray(parsed)) {\n warnings.push({\n code: \"unsupported-json\",\n message: \"JSON data must be an array of objects or of arrays\",\n });\n return { fields: [], records: [], warnings, format: \"json\" };\n }\n const result = fromArray(parsed, options, warnings);\n return { ...result, format: \"json\" };\n }\n }\n const delimiter =\n !options.delimiter || options.delimiter === \"auto\"\n ? detectDelimiter(input)\n : options.delimiter;\n let rows: string[][];\n try {\n rows = parseCsv(input, { delimiter });\n } catch (error) {\n warnings.push({ code: \"empty\", message: (error as Error).message });\n return { fields: [], records: [], warnings, format: \"csv\", delimiter };\n }\n return {\n ...fromRows(rows, options, warnings),\n format: \"csv\",\n delimiter,\n };\n }\n const result = fromArray(input as ReadonlyArray<unknown>, options, warnings);\n return {\n ...result,\n format: result.objects ? \"objects\" : \"rows\",\n };\n}\n\nfunction fromArray(\n items: ReadonlyArray<unknown>,\n options: ParseDataSourceOptions,\n warnings: DataSourceWarning[],\n): { fields: string[]; records: MergeRecord[]; warnings: DataSourceWarning[]; objects: boolean } {\n const objects = items.some(\n (item) => item !== null && typeof item === \"object\" && !Array.isArray(item),\n );\n if (!objects) {\n const rows = items.filter((item): item is unknown[] => Array.isArray(item));\n return { ...fromRows(rows, options, warnings), objects: false };\n }\n const maxFields = options.maxFields ?? MAX_DATA_SOURCE_FIELDS;\n const maxRecords = options.maxRecords ?? MAX_DATA_SOURCE_RECORDS;\n const fields: string[] = [];\n const seen = new Set<string>();\n let fieldsTruncated = false;\n const rows = items.filter(\n (item): item is Record<string, unknown> =>\n item !== null && typeof item === \"object\" && !Array.isArray(item),\n );\n for (const row of rows) {\n for (const key of Object.keys(row)) {\n if (seen.has(key)) continue;\n if (fields.length >= maxFields) {\n fieldsTruncated = true;\n continue;\n }\n seen.add(key);\n fields.push(key);\n }\n }\n if (fieldsTruncated) {\n warnings.push({\n code: \"fields-truncated\",\n message: `Only the first ${maxFields} fields were kept`,\n });\n }\n const records: MergeRecord[] = [];\n for (const row of rows) {\n if (fields.every((field) => cellText(row[field]).trim() === \"\")) continue;\n if (records.length >= maxRecords) {\n warnings.push({\n code: \"records-truncated\",\n message: `Only the first ${maxRecords} records were kept`,\n });\n break;\n }\n const record: MergeRecord = {};\n for (const field of fields) {\n const value = Object.prototype.hasOwnProperty.call(row, field)\n ? row[field]\n : undefined;\n setField(record, field, cellText(value));\n }\n records.push(record);\n }\n if (records.length === 0) {\n warnings.push({ code: \"empty\", message: \"The data source has no records\" });\n }\n return { fields, records, warnings, objects: true };\n}\n\nfunction fromRows(\n allRows: ReadonlyArray<ReadonlyArray<unknown>>,\n options: ParseDataSourceOptions,\n warnings: DataSourceWarning[],\n): { fields: string[]; records: MergeRecord[]; warnings: DataSourceWarning[] } {\n const maxFields = options.maxFields ?? MAX_DATA_SOURCE_FIELDS;\n const maxRecords = options.maxRecords ?? MAX_DATA_SOURCE_RECORDS;\n const rows = allRows.filter((row) => !isBlankRow(row));\n if (rows.length === 0) {\n warnings.push({ code: \"empty\", message: \"The data source has no records\" });\n return { fields: [], records: [], warnings };\n }\n const hasHeader = options.hasHeader ?? true;\n let fields: string[];\n let body: ReadonlyArray<ReadonlyArray<unknown>>;\n let widest: number;\n if (hasHeader) {\n const header = rows[0];\n widest = header.length;\n if (header.some((cell) => cellText(cell).trim() === \"\")) {\n warnings.push({\n code: \"blank-header\",\n message: \"Blank column headers were named \\\"Column N\\\"\",\n });\n }\n fields = normalizeFieldNames(header.slice(0, maxFields));\n const lower = header.map((cell) => cellText(cell).trim().toLowerCase());\n if (lower.some((name, i) => name !== \"\" && lower.indexOf(name) !== i)) {\n warnings.push({\n code: \"duplicate-header\",\n message: \"Repeated column headers were numbered\",\n });\n }\n body = rows.slice(1);\n } else {\n widest = Math.max(...rows.map((row) => row.length));\n fields = Array.from(\n { length: Math.min(widest, maxFields) },\n (_, i) => `Column ${i + 1}`,\n );\n body = rows;\n }\n if (widest > maxFields) {\n warnings.push({\n code: \"fields-truncated\",\n message: `Only the first ${maxFields} fields were kept`,\n });\n }\n if (body.length > maxRecords) {\n warnings.push({\n code: \"records-truncated\",\n message: `Only the first ${maxRecords} of ${body.length} records were kept`,\n });\n body = body.slice(0, maxRecords);\n }\n let ragged = 0;\n const records = body.map((row) => {\n if (hasHeader && row.length !== widest) ragged++;\n const record: MergeRecord = {};\n fields.forEach((field, i) => setField(record, field, cellText(row[i])));\n return record;\n });\n if (ragged > 0) {\n warnings.push({\n code: \"ragged-rows\",\n message: `${ragged} record${ragged === 1 ? \" was\" : \"s were\"} padded or cut to ${widest} fields`,\n count: ragged,\n });\n }\n if (records.length === 0) {\n warnings.push({ code: \"empty\", message: \"The data source has no records\" });\n }\n return { fields, records, warnings };\n}\n\n/** Lower-cases and drops spaces, `_`, `-` and `.` so `First Name` matches `first_name`. */\nexport function normalizeFieldKey(name: string): string {\n return name.toLowerCase().replace(/[\\s_.\\-]+/g, \"\");\n}\n\n/**\n * Built-in alias groups for `matchFields`: any name in a group matches any\n * other (after `normalizeFieldKey`). Extended from Word's address-block\n * field detection.\n */\nexport const FIELD_ALIASES: ReadonlyArray<ReadonlyArray<string>> = [\n [\"FirstName\", \"First\", \"GivenName\", \"Forename\", \"FName\"],\n [\"LastName\", \"Last\", \"Surname\", \"FamilyName\", \"LName\"],\n [\"Name\", \"FullName\", \"DisplayName\"],\n [\"Company\", \"CompanyName\", \"Organization\", \"Organisation\", \"Employer\", \"Business\"],\n [\"Address\", \"AddressLine1\", \"Address1\", \"Street\", \"StreetAddress\"],\n [\"City\", \"Town\"],\n [\"State\", \"Province\", \"Region\", \"County\"],\n [\"PostalCode\", \"ZIP\", \"ZipCode\", \"Postcode\"],\n [\"Country\", \"CountryName\", \"Nation\"],\n [\"Title\", \"CourtesyTitle\", \"Salutation\", \"Honorific\"],\n [\"Email\", \"EmailAddress\", \"Mail\", \"EMail\"],\n [\"Phone\", \"PhoneNumber\", \"Telephone\", \"Tel\", \"Mobile\"],\n];\n\nexport type FieldMatchKind = \"exact\" | \"normalized\" | \"alias\";\n\nexport interface FieldMatch {\n variable: string;\n /** The matched field, or `null`. */\n field: string | null;\n kind: FieldMatchKind | null;\n}\n\nexport interface FieldMapping {\n /** Variable → field (or `null` when unmatched), in variable order. */\n mapping: Record<string, string | null>;\n matches: FieldMatch[];\n unmatchedVariables: string[];\n /** Fields no variable maps to. */\n unusedFields: string[];\n}\n\nexport interface MatchFieldsOptions {\n /** Extra alias groups, checked after the built-in ones. */\n aliases?: ReadonlyArray<ReadonlyArray<string>>;\n}\n\n/**\n * Maps prompt variables to data source fields: an exact name first, then a\n * case-, space- and punctuation-insensitive match (`first_name` ↔\n * `First Name`), then an alias (`FirstName` ↔ `First` / `GivenName`, see\n * `FIELD_ALIASES`). Several variables may map to the same field.\n */\nexport function matchFields(\n variables: ReadonlyArray<string | { name: string }>,\n fields: ReadonlyArray<string>,\n options: MatchFieldsOptions = {},\n): FieldMapping {\n const names = Array.from(\n new Set(variables.map((v) => (typeof v === \"string\" ? v : v.name))),\n );\n const byKey = new Map<string, string>();\n for (const field of fields) {\n const key = normalizeFieldKey(field);\n if (!byKey.has(key)) byKey.set(key, field);\n }\n const groups = [...FIELD_ALIASES, ...(options.aliases ?? [])].map((group) =>\n group.map(normalizeFieldKey),\n );\n\n const matches: FieldMatch[] = names.map((variable) => {\n if (fields.includes(variable)) {\n return { variable, field: variable, kind: \"exact\" };\n }\n const key = normalizeFieldKey(variable);\n const normalized = byKey.get(key);\n if (normalized !== undefined) {\n return { variable, field: normalized, kind: \"normalized\" };\n }\n for (const group of groups) {\n if (!group.includes(key)) continue;\n for (const alias of group) {\n const field = byKey.get(alias);\n if (field !== undefined) return { variable, field, kind: \"alias\" };\n }\n }\n return { variable, field: null, kind: null };\n });\n\n const mapping: Record<string, string | null> = {};\n for (const match of matches) {\n Object.defineProperty(mapping, match.variable, {\n value: match.field,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n const used = new Set(matches.map((m) => m.field));\n return {\n mapping,\n matches,\n unmatchedVariables: matches.filter((m) => !m.field).map((m) => m.variable),\n unusedFields: fields.filter((field) => !used.has(field)),\n };\n}\n\nexport interface RecordToValuesOptions {\n /**\n * Treat blank cells as missing so `{name|default}` falls back to its\n * default (default `true`). With `false`, a blank cell renders as empty.\n */\n blankAsMissing?: boolean;\n}\n\n/**\n * The prompt values for one record: every field under its own name, then\n * each mapped variable set from its field (a `null` mapping leaves the\n * variable unset even if a field shares its name).\n */\nexport function recordToValues(\n record: MergeRecord,\n mapping: Readonly<Record<string, string | null | undefined>> = {},\n options: RecordToValuesOptions = {},\n): PromptValues {\n const blankAsMissing = options.blankAsMissing ?? true;\n const values: PromptValues = {};\n const assign = (name: string, value: string | undefined) => {\n if (value === undefined || (blankAsMissing && value.trim() === \"\")) {\n delete values[name];\n return;\n }\n Object.defineProperty(values, name, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n };\n const own = (name: string) =>\n Object.prototype.hasOwnProperty.call(record, name) ? record[name] : undefined;\n for (const field of Object.keys(record)) assign(field, record[field]);\n for (const variable of Object.keys(mapping)) {\n const field = mapping[variable];\n if (field === undefined) continue;\n assign(variable, field === null ? undefined : own(field));\n }\n return values;\n}\n","// Portions ported from wordcraft/crates/engine/src/cmd/mailings.rs\n// (MIT OR Apache-2.0, © ArtCraft Team and contributors). See\n// THIRD_PARTY_NOTICES.md.\n\n/**\n * Multi-record merge: resolves one prompt per data source record with\n * `resolvePrompt`, like Word's Finish & Merge.\n */\nimport type { PromptDiagnostic, PromptValues, Template } from \"./tokens\";\nimport type { SourceMapSegment } from \"./sourcemap\";\nimport { resolvePrompt } from \"./engine\";\nimport { extractVariables } from \"./fields\";\nimport {\n evaluateConditionExpression,\n parseConditionExpression,\n} from \"./variables\";\nimport {\n matchFields,\n parseDataSource,\n recordToValues,\n type DataSourceInput,\n type MergeDataSource,\n type MergeRecord,\n type ParseDataSourceOptions,\n} from \"./data-source\";\n\n/** Default cap on merged outputs. */\nexport const MAX_MERGE_OUTPUTS = 10_000;\n/** Default cap on the total length of merged text (characters). */\nexport const MAX_MERGE_LENGTH = 20_000_000;\n\nexport interface MergeRecordsOptions {\n /** Templates for `{{name}}` tags. */\n templates?: Template[];\n /** Template version bindings. */\n bindings?: Record<string, string>;\n /** Maximum template nesting depth (default 10). */\n maxDepth?: number;\n /**\n * Variable → field. Variables left out are matched automatically with\n * `matchFields`; a `null` entry leaves the variable unset.\n */\n mapping?: Record<string, string | null>;\n /**\n * Text placed between outputs in the joined `text`: default `\"\\n\\n\"`.\n * `\"none\"` joins them with nothing in between.\n */\n separator?: string;\n /**\n * Drops a record's output when this holds. Either a function of the record\n * (and its prompt values), or a condition written like the inside of a\n * section tag: `void`, `!email`, `status=cancelled`, `amount<10`. The\n * condition is evaluated against the record's prompt values (mapped\n * variables and raw field names); a name that is neither is matched to a\n * field like a variable (`status` → `Status`).\n */\n skipIf?:\n | string\n | ((record: MergeRecord, values: PromptValues, index: number) => boolean);\n /** Stop after this many outputs (default `MAX_MERGE_OUTPUTS`). */\n maxOutputs?: number;\n /** Stop once the outputs reach this many characters (default `MAX_MERGE_LENGTH`). */\n maxLength?: number;\n /** First record to merge, 1-based (default 1). */\n from?: number;\n /** Last record to merge, 1-based and inclusive (default: the last). */\n to?: number;\n /** See `recordToValues` (default `true`: blank cells use defaults). */\n blankAsMissing?: boolean;\n /** Options for parsing `source` when it is not already parsed. */\n parse?: ParseDataSourceOptions;\n}\n\nexport interface MergeOutput {\n /** 0-based index of the record in the data source. */\n index: number;\n record: MergeRecord;\n /** The values the prompt was resolved with. */\n values: PromptValues;\n text: string;\n map: SourceMapSegment[];\n}\n\nexport interface MergeSkip {\n index: number;\n record: MergeRecord;\n reason: \"skip-if\";\n}\n\nexport type MergeDiagnosticCode =\n | PromptDiagnostic[\"code\"]\n | \"unmapped-variable\"\n | \"invalid-skip-condition\"\n | \"max-outputs\"\n | \"max-length\"\n | \"data-source\";\n\n/** A grammar diagnostic from the template, or a merge-level problem. */\nexport interface MergeDiagnostic {\n code: MergeDiagnosticCode;\n message: string;\n /** Variable, for grammar and `unmapped-variable` diagnostics. */\n name?: string;\n start?: number;\n end?: number;\n templateName?: string;\n}\n\nexport interface MergeRecordsResult {\n outputs: MergeOutput[];\n skipped: MergeSkip[];\n diagnostics: MergeDiagnostic[];\n /** Every output's text joined with the separator. */\n text: string;\n /** The variable → field mapping used. */\n mapping: Record<string, string | null>;\n /** The merge stopped early at `maxOutputs` or `maxLength`. */\n truncated: boolean;\n}\n\nfunction isParsedSource(source: unknown): source is MergeDataSource {\n return (\n !!source &&\n typeof source === \"object\" &&\n !Array.isArray(source) &&\n Array.isArray((source as MergeDataSource).fields) &&\n Array.isArray((source as MergeDataSource).records)\n );\n}\n\n/**\n * Merges a prompt with every record of a data source: one resolved output per\n * record, in order. Fields are matched to the prompt's variables\n * automatically (override with `mapping`), blank cells fall back to the\n * variable's default, `{?field}` / `{?field>3}` sections are evaluated per\n * record, and `skipIf` drops records. Grammar diagnostics in the prompt are\n * reported once. Never throws.\n */\nexport function mergeRecords(\n template: string,\n source: MergeDataSource | DataSourceInput,\n options: MergeRecordsOptions = {},\n): MergeRecordsResult {\n const data = isParsedSource(source)\n ? source\n : parseDataSource(source, options.parse);\n const diagnostics: MergeDiagnostic[] = [];\n if (!isParsedSource(source)) {\n for (const warning of data.warnings) {\n if (warning.code === \"empty\") continue;\n diagnostics.push({ code: \"data-source\", message: warning.message });\n }\n }\n\n const variables = extractVariables(template, {\n templates: options.templates,\n bindings: options.bindings,\n maxDepth: options.maxDepth,\n });\n const auto = matchFields(variables, data.fields).mapping;\n const mapping: Record<string, string | null> = { ...auto };\n for (const [variable, field] of Object.entries(options.mapping ?? {})) {\n Object.defineProperty(mapping, variable, {\n value: field,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n for (const variable of variables) {\n const field = mapping[variable.name];\n if (\n (field === null || field === undefined) &&\n variable.defaultValue === undefined &&\n variable.usedAsValue\n ) {\n diagnostics.push({\n code: \"unmapped-variable\",\n message: `No field is mapped to \"${variable.name}\", so it stays as a placeholder`,\n name: variable.name,\n });\n }\n }\n\n let skip: ((record: MergeRecord, values: PromptValues, index: number) => boolean) | undefined;\n if (typeof options.skipIf === \"function\") {\n skip = options.skipIf;\n } else if (typeof options.skipIf === \"string\" && options.skipIf.trim()) {\n const parsed = parseConditionExpression(options.skipIf);\n if (\"error\" in parsed) {\n diagnostics.push({\n code: \"invalid-skip-condition\",\n message: `Invalid skipIf condition \"${options.skipIf}\": ${parsed.error}`,\n });\n } else {\n // The condition may name a field the template never uses: match it to\n // a field the same way variables are (`status` → `Status`).\n const field =\n mapping[parsed.name] ??\n matchFields([parsed.name], data.fields).mapping[parsed.name];\n skip = (record, values) => {\n if (\n field &&\n !Object.prototype.hasOwnProperty.call(values, parsed.name) &&\n Object.prototype.hasOwnProperty.call(record, field)\n ) {\n return evaluateConditionExpression(parsed, {\n ...values,\n [parsed.name]: record[field],\n });\n }\n return evaluateConditionExpression(parsed, values);\n };\n }\n }\n\n const separator =\n options.separator === undefined\n ? \"\\n\\n\"\n : options.separator === \"none\"\n ? \"\"\n : options.separator;\n const maxOutputs = Math.max(0, options.maxOutputs ?? MAX_MERGE_OUTPUTS);\n const maxLength = Math.max(0, options.maxLength ?? MAX_MERGE_LENGTH);\n const first = Math.max(1, Math.floor(options.from ?? 1)) - 1;\n const last = Math.min(\n data.records.length,\n Math.floor(options.to ?? data.records.length),\n );\n\n const outputs: MergeOutput[] = [];\n const skipped: MergeSkip[] = [];\n let length = 0;\n let truncated = false;\n let reportedGrammar = false;\n\n for (let index = first; index < last; index++) {\n const record = data.records[index];\n const values = recordToValues(record, mapping, {\n blankAsMissing: options.blankAsMissing,\n });\n if (skip?.(record, values, index)) {\n skipped.push({ index, record, reason: \"skip-if\" });\n continue;\n }\n if (outputs.length >= maxOutputs) {\n truncated = true;\n diagnostics.push({\n code: \"max-outputs\",\n message: `Stopped after ${maxOutputs} outputs`,\n });\n break;\n }\n const resolved = resolvePrompt(template, options.templates, {\n bindings: options.bindings,\n maxDepth: options.maxDepth,\n values,\n });\n if (!reportedGrammar) {\n // The template's grammar diagnostics are the same for every record.\n reportedGrammar = true;\n diagnostics.push(...resolved.diagnostics);\n }\n const added = resolved.text.length + (outputs.length > 0 ? separator.length : 0);\n if (length + added > maxLength) {\n truncated = true;\n diagnostics.push({\n code: \"max-length\",\n message: `Stopped at ${outputs.length} outputs: the merged text would exceed ${maxLength} characters`,\n });\n break;\n }\n length += added;\n outputs.push({ index, record, values, text: resolved.text, map: resolved.map });\n }\n\n return {\n outputs,\n skipped,\n diagnostics,\n text: outputs.map((output) => output.text).join(separator),\n mapping,\n truncated,\n };\n}\n\n/**\n * Serializes merge outputs for copying or download: `\"text\"` joins them with\n * `separator` (default `\"\\n\\n\"`), `\"json\"` writes an array of\n * `{ record, text }` objects (`record` is 1-based).\n */\nexport function serializeMergeOutputs(\n outputs: ReadonlyArray<Pick<MergeOutput, \"index\" | \"text\" | \"values\">>,\n format: \"text\" | \"json\" = \"text\",\n separator = \"\\n\\n\",\n): string {\n if (format === \"json\") {\n return JSON.stringify(\n outputs.map((output) => ({ record: output.index + 1, text: output.text })),\n null,\n 2,\n );\n }\n return outputs.map((output) => output.text).join(separator === \"none\" ? \"\" : separator);\n}\n"],"mappings":"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","names":["result","rows"]}
|