@pixerate/editor 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +96 -1
  2. package/THIRD_PARTY_NOTICES.md +51 -0
  3. package/dist/agent/index.cjs +9 -8
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +4 -3
  6. package/dist/agent/index.d.ts +4 -3
  7. package/dist/agent/index.js +3 -2
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/canvas/index.cjs +1210 -17
  10. package/dist/canvas/index.cjs.map +1 -1
  11. package/dist/canvas/index.d.cts +318 -1
  12. package/dist/canvas/index.d.ts +318 -1
  13. package/dist/canvas/index.js +1199 -6
  14. package/dist/canvas/index.js.map +1 -1
  15. package/dist/{chunk-QBJ22YZR.js → chunk-3CN2WD3X.js} +1354 -206
  16. package/dist/chunk-3CN2WD3X.js.map +1 -0
  17. package/dist/{chunk-JJDLPEWL.js → chunk-3LV6RRPH.js} +2 -2
  18. package/dist/{chunk-MJZBNWG7.js → chunk-5S3Z4PPF.js} +78 -557
  19. package/dist/chunk-5S3Z4PPF.js.map +1 -0
  20. package/dist/chunk-664LQYFJ.js +115 -0
  21. package/dist/chunk-664LQYFJ.js.map +1 -0
  22. package/dist/{chunk-AA4ZEVCC.cjs → chunk-D27YFC46.cjs} +101 -580
  23. package/dist/chunk-D27YFC46.cjs.map +1 -0
  24. package/dist/chunk-D6FH2YAX.cjs +131 -0
  25. package/dist/chunk-D6FH2YAX.cjs.map +1 -0
  26. package/dist/{chunk-4SUNJZWB.cjs → chunk-FD4LPFAE.cjs} +48 -200
  27. package/dist/chunk-FD4LPFAE.cjs.map +1 -0
  28. package/dist/chunk-FODNLX5N.js +749 -0
  29. package/dist/chunk-FODNLX5N.js.map +1 -0
  30. package/dist/{chunk-OYXSKQFR.js → chunk-FPENXAEJ.js} +35 -187
  31. package/dist/chunk-FPENXAEJ.js.map +1 -0
  32. package/dist/chunk-HLIMTC6N.js +1 -0
  33. package/dist/chunk-HLIMTC6N.js.map +1 -0
  34. package/dist/{chunk-QGHGJ56O.js → chunk-ITBSKI26.js} +1483 -19
  35. package/dist/chunk-ITBSKI26.js.map +1 -0
  36. package/dist/{chunk-XDMXXC4Z.cjs → chunk-MA2F5KHF.cjs} +350 -227
  37. package/dist/chunk-MA2F5KHF.cjs.map +1 -0
  38. package/dist/{chunk-RIKBJLS2.cjs → chunk-MCSJFWAO.cjs} +1356 -208
  39. package/dist/chunk-MCSJFWAO.cjs.map +1 -0
  40. package/dist/chunk-MKA3AHLV.cjs +256 -0
  41. package/dist/chunk-MKA3AHLV.cjs.map +1 -0
  42. package/dist/chunk-OLZJXL4R.cjs +749 -0
  43. package/dist/chunk-OLZJXL4R.cjs.map +1 -0
  44. package/dist/chunk-OXSV64JX.js +689 -0
  45. package/dist/chunk-OXSV64JX.js.map +1 -0
  46. package/dist/chunk-P3RQ5UJE.cjs +689 -0
  47. package/dist/chunk-P3RQ5UJE.cjs.map +1 -0
  48. package/dist/chunk-P6ODPZ4W.js +256 -0
  49. package/dist/chunk-P6ODPZ4W.js.map +1 -0
  50. package/dist/chunk-PGNZKFQS.js +685 -0
  51. package/dist/chunk-PGNZKFQS.js.map +1 -0
  52. package/dist/chunk-PL4JB3BF.cjs +1 -0
  53. package/dist/chunk-PL4JB3BF.cjs.map +1 -0
  54. package/dist/{chunk-GVSMRPHB.cjs → chunk-SBCZ6RN5.cjs} +1568 -104
  55. package/dist/chunk-SBCZ6RN5.cjs.map +1 -0
  56. package/dist/{chunk-CL37JGFW.cjs → chunk-SML64VJG.cjs} +4 -4
  57. package/dist/{chunk-CL37JGFW.cjs.map → chunk-SML64VJG.cjs.map} +1 -1
  58. package/dist/chunk-TNNJXF46.cjs +115 -0
  59. package/dist/chunk-TNNJXF46.cjs.map +1 -0
  60. package/dist/chunk-U5HZSFCS.js +131 -0
  61. package/dist/chunk-U5HZSFCS.js.map +1 -0
  62. package/dist/{chunk-K3R5NG2D.js → chunk-U5KWZU4X.js} +251 -128
  63. package/dist/chunk-U5KWZU4X.js.map +1 -0
  64. package/dist/chunk-XNORY7M6.cjs +685 -0
  65. package/dist/chunk-XNORY7M6.cjs.map +1 -0
  66. package/dist/commands/index.d.cts +5 -353
  67. package/dist/commands/index.d.ts +5 -353
  68. package/dist/comment-store-BEMgVlAA.d.cts +135 -0
  69. package/dist/comment-store-BEMgVlAA.d.ts +135 -0
  70. package/dist/compare/index.cjs +15 -0
  71. package/dist/compare/index.cjs.map +1 -0
  72. package/dist/compare/index.d.cts +58 -0
  73. package/dist/compare/index.d.ts +58 -0
  74. package/dist/compare/index.js +15 -0
  75. package/dist/compare/index.js.map +1 -0
  76. package/dist/{controller-pePCJLT1.d.cts → controller-BhLLAoi8.d.cts} +45 -4
  77. package/dist/{controller-pePCJLT1.d.ts → controller-BhLLAoi8.d.ts} +45 -4
  78. package/dist/documents-BQjzJNe2.d.ts +76 -0
  79. package/dist/documents-KRTPhvst.d.cts +76 -0
  80. package/dist/extensions/index.cjs +53 -5
  81. package/dist/extensions/index.cjs.map +1 -1
  82. package/dist/extensions/index.d.cts +7 -3
  83. package/dist/extensions/index.d.ts +7 -3
  84. package/dist/extensions/index.js +52 -4
  85. package/dist/generation/index.cjs +1373 -0
  86. package/dist/generation/index.cjs.map +1 -0
  87. package/dist/generation/index.d.cts +554 -0
  88. package/dist/generation/index.d.ts +554 -0
  89. package/dist/generation/index.js +1373 -0
  90. package/dist/generation/index.js.map +1 -0
  91. package/dist/grammar/index.cjs +48 -3
  92. package/dist/grammar/index.cjs.map +1 -1
  93. package/dist/grammar/index.d.cts +322 -100
  94. package/dist/grammar/index.d.ts +322 -100
  95. package/dist/grammar/index.js +54 -9
  96. package/dist/image-editor/index.cjs +1831 -30
  97. package/dist/image-editor/index.cjs.map +1 -1
  98. package/dist/image-editor/index.d.cts +590 -3
  99. package/dist/image-editor/index.d.ts +590 -3
  100. package/dist/image-editor/index.js +1807 -6
  101. package/dist/image-editor/index.js.map +1 -1
  102. package/dist/{index-CCr_z9kF.d.cts → index-BhJBSm2d.d.cts} +370 -4
  103. package/dist/{index-Ck6ajwXh.d.ts → index-fJrlkJCd.d.ts} +370 -4
  104. package/dist/index.cjs +162 -25
  105. package/dist/index.cjs.map +1 -1
  106. package/dist/index.d.cts +14 -8
  107. package/dist/index.d.ts +14 -8
  108. package/dist/index.js +174 -37
  109. package/dist/index.js.map +1 -1
  110. package/dist/migrate-iTlm3a8h.d.cts +112 -0
  111. package/dist/migrate-iTlm3a8h.d.ts +112 -0
  112. package/dist/persistence/index.cjs +676 -0
  113. package/dist/persistence/index.cjs.map +1 -0
  114. package/dist/persistence/index.d.cts +347 -0
  115. package/dist/persistence/index.d.ts +347 -0
  116. package/dist/persistence/index.js +676 -0
  117. package/dist/persistence/index.js.map +1 -0
  118. package/dist/{registry-D5-R90p0.d.cts → registry-BDe-vlv3.d.ts} +2 -40
  119. package/dist/registry-D32LpIc4.d.cts +354 -0
  120. package/dist/{registry-D5-R90p0.d.ts → registry-DnzpgY27.d.cts} +2 -40
  121. package/dist/registry-evKTP4ls.d.ts +354 -0
  122. package/dist/schema-DYDGdYL9.d.cts +41 -0
  123. package/dist/schema-DYDGdYL9.d.ts +41 -0
  124. package/dist/serializers/index.cjs +4 -3
  125. package/dist/serializers/index.cjs.map +1 -1
  126. package/dist/serializers/index.d.cts +2 -1
  127. package/dist/serializers/index.d.ts +2 -1
  128. package/dist/serializers/index.js +3 -2
  129. package/dist/sourcemap-C8AH3MBQ.d.cts +91 -0
  130. package/dist/sourcemap-DA1Evhrv.d.ts +91 -0
  131. package/dist/spreadsheet/index.cjs +37 -3
  132. package/dist/spreadsheet/index.cjs.map +1 -1
  133. package/dist/spreadsheet/index.d.cts +188 -17
  134. package/dist/spreadsheet/index.d.ts +188 -17
  135. package/dist/spreadsheet/index.js +43 -9
  136. package/dist/{tokens-CyLZmIei.d.cts → tokens-D7yXvUU6.d.cts} +15 -2
  137. package/dist/{tokens-CyLZmIei.d.ts → tokens-D7yXvUU6.d.ts} +15 -2
  138. package/dist/{track-changes-BSF58RK0.d.ts → track-changes-BK5sVf4_.d.cts} +18 -136
  139. package/dist/{track-changes-BSF58RK0.d.cts → track-changes-CDjCrwKe.d.ts} +18 -136
  140. package/package.json +16 -1
  141. package/dist/chunk-4SUNJZWB.cjs.map +0 -1
  142. package/dist/chunk-AA4ZEVCC.cjs.map +0 -1
  143. package/dist/chunk-AXV2ZW34.cjs +0 -118
  144. package/dist/chunk-AXV2ZW34.cjs.map +0 -1
  145. package/dist/chunk-B2ZRLN4S.js +0 -118
  146. package/dist/chunk-B2ZRLN4S.js.map +0 -1
  147. package/dist/chunk-GVSMRPHB.cjs.map +0 -1
  148. package/dist/chunk-K3R5NG2D.js.map +0 -1
  149. package/dist/chunk-MJZBNWG7.js.map +0 -1
  150. package/dist/chunk-OYXSKQFR.js.map +0 -1
  151. package/dist/chunk-QBJ22YZR.js.map +0 -1
  152. package/dist/chunk-QGHGJ56O.js.map +0 -1
  153. package/dist/chunk-RIKBJLS2.cjs.map +0 -1
  154. package/dist/chunk-XDMXXC4Z.cjs.map +0 -1
  155. /package/dist/{chunk-JJDLPEWL.js.map → chunk-3LV6RRPH.js.map} +0 -0
@@ -0,0 +1,689 @@
1
+ import {
2
+ getPromptDiagnostics,
3
+ getTemplateBody,
4
+ resolvePrompt,
5
+ tokenizePrompt
6
+ } from "./chunk-FPENXAEJ.js";
7
+ import {
8
+ INSTRUCTION_REGEX,
9
+ TEMPLATE_REGEX,
10
+ VARIABLE_REGEX,
11
+ conditionSubject,
12
+ evaluateConditionExpression,
13
+ parseConditionExpression,
14
+ parseVariableBody
15
+ } from "./chunk-P6ODPZ4W.js";
16
+ import {
17
+ parseCsv
18
+ } from "./chunk-664LQYFJ.js";
19
+
20
+ // src/grammar/resolver.ts
21
+ function resolveTemplates(text, templates = [], options) {
22
+ return resolvePrompt(text, templates, options).text;
23
+ }
24
+ function resolveVariables(text, values) {
25
+ if (!text) return "";
26
+ return resolvePrompt(text, [], { values }).text;
27
+ }
28
+ function extractTemplateNames(text) {
29
+ if (!text) return [];
30
+ const set = /* @__PURE__ */ new Set();
31
+ const regex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);
32
+ let match;
33
+ while ((match = regex.exec(text)) !== null) {
34
+ set.add(match[1].trim());
35
+ }
36
+ return Array.from(set);
37
+ }
38
+ function extractVariableNames(text) {
39
+ if (!text) return [];
40
+ const set = /* @__PURE__ */ new Set();
41
+ const regex = new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags);
42
+ let comparisonStarts;
43
+ let match;
44
+ while ((match = regex.exec(text)) !== null) {
45
+ const parsed = parseVariableBody(match[1]);
46
+ let name = parsed.name;
47
+ if (parsed.kind === "conditional" && parsed.conditional !== "end") {
48
+ const subject = conditionSubject(name);
49
+ if (subject) {
50
+ comparisonStarts ??= new Set(
51
+ tokenizePrompt(text).filter((token) => token.comparison).map((token) => token.start)
52
+ );
53
+ if (comparisonStarts.has(match.index)) name = subject;
54
+ }
55
+ }
56
+ set.add(name);
57
+ }
58
+ return Array.from(set);
59
+ }
60
+ function extractInstructionNames(text) {
61
+ if (!text) return [];
62
+ const set = /* @__PURE__ */ new Set();
63
+ const regex = new RegExp(INSTRUCTION_REGEX.source, INSTRUCTION_REGEX.flags);
64
+ let match;
65
+ while ((match = regex.exec(text)) !== null) {
66
+ set.add(match[1].trim());
67
+ }
68
+ return Array.from(set);
69
+ }
70
+
71
+ // src/grammar/sourcemap.ts
72
+ function resolveTemplatesWithMapping(text, templates = [], templateBindings, options) {
73
+ if (options?.values === void 0 && (!templates || templates.length === 0 || !text.includes("{{"))) {
74
+ return {
75
+ diagnostics: getPromptDiagnostics(text),
76
+ text,
77
+ map: [
78
+ {
79
+ resolvedStart: 0,
80
+ resolvedEnd: text.length,
81
+ source: "raw",
82
+ rawStart: 0,
83
+ rawEnd: text.length
84
+ }
85
+ ]
86
+ };
87
+ }
88
+ return resolvePrompt(text, templates, {
89
+ bindings: templateBindings,
90
+ maxDepth: options?.maxDepth,
91
+ values: options?.values
92
+ });
93
+ }
94
+ function mapResolvedOffsetToRaw(resolvedOffset, map) {
95
+ for (let i = 0; i < map.length; i++) {
96
+ const seg = map[i];
97
+ const isLast = i === map.length - 1;
98
+ const inRange = isLast ? resolvedOffset >= seg.resolvedStart && resolvedOffset <= seg.resolvedEnd : resolvedOffset >= seg.resolvedStart && resolvedOffset < seg.resolvedEnd;
99
+ if (inRange) {
100
+ if (seg.source === "raw") {
101
+ return seg.rawStart + (resolvedOffset - seg.resolvedStart);
102
+ }
103
+ if (resolvedOffset === seg.resolvedEnd) {
104
+ return seg.rawEnd;
105
+ }
106
+ return seg.rawStart;
107
+ }
108
+ }
109
+ return resolvedOffset;
110
+ }
111
+ function mapRawOffsetToResolved(rawOffset, map) {
112
+ for (let i = 0; i < map.length; i++) {
113
+ const seg = map[i];
114
+ const isLast = i === map.length - 1;
115
+ const inRange = isLast ? rawOffset >= seg.rawStart && rawOffset <= seg.rawEnd : rawOffset >= seg.rawStart && rawOffset < seg.rawEnd;
116
+ if (inRange) {
117
+ if (seg.source === "raw") {
118
+ return seg.resolvedStart + (rawOffset - seg.rawStart);
119
+ }
120
+ if (rawOffset === seg.rawEnd) {
121
+ return seg.resolvedEnd;
122
+ }
123
+ return seg.resolvedStart;
124
+ }
125
+ }
126
+ return rawOffset;
127
+ }
128
+
129
+ // src/grammar/fields.ts
130
+ function extractVariables(text, options = {}) {
131
+ const descriptors = /* @__PURE__ */ new Map();
132
+ const templateMap = new Map(
133
+ (options.templates ?? []).map((t) => [t.name, t])
134
+ );
135
+ const maxDepth = options.maxDepth ?? 10;
136
+ const describe = (name, templateName) => {
137
+ let descriptor = descriptors.get(name);
138
+ if (!descriptor) {
139
+ descriptor = {
140
+ name,
141
+ usedAsValue: false,
142
+ usedInCondition: false,
143
+ occurrences: 0,
144
+ templates: []
145
+ };
146
+ descriptors.set(name, descriptor);
147
+ }
148
+ descriptor.occurrences++;
149
+ if (templateName && !descriptor.templates.includes(templateName)) {
150
+ descriptor.templates.push(templateName);
151
+ }
152
+ return descriptor;
153
+ };
154
+ const visit = (source, visited, depth, templateName) => {
155
+ for (const token of tokenizePrompt(source)) {
156
+ if (token.type === "variable") {
157
+ const descriptor = describe(token.value, templateName);
158
+ descriptor.usedAsValue = true;
159
+ if (descriptor.defaultValue === void 0 && token.defaultValue !== void 0) {
160
+ descriptor.defaultValue = token.defaultValue;
161
+ }
162
+ if (descriptor.description === void 0 && token.description !== void 0) {
163
+ descriptor.description = token.description;
164
+ }
165
+ } else if (token.type === "conditional" && token.conditional !== "end") {
166
+ const descriptor = describe(token.value, templateName);
167
+ descriptor.usedInCondition = true;
168
+ if (token.comparison) descriptor.usedInComparison = true;
169
+ } else if (token.type === "template") {
170
+ const template = templateMap.get(token.value);
171
+ if (!template || visited.has(token.value) || depth + 1 > maxDepth) {
172
+ continue;
173
+ }
174
+ const body = getTemplateBody(template, options.bindings);
175
+ if (body === void 0) continue;
176
+ visit(body, new Set(visited).add(token.value), depth + 1, token.value);
177
+ }
178
+ }
179
+ };
180
+ if (text) visit(text, /* @__PURE__ */ new Set(), 0);
181
+ return Array.from(descriptors.values());
182
+ }
183
+ function getVariableFormFields(text, options = {}) {
184
+ return extractVariables(text, options).map((variable) => ({
185
+ name: variable.name,
186
+ label: variable.description || variable.name,
187
+ placeholder: variable.defaultValue ?? "",
188
+ ...variable.defaultValue !== void 0 ? { defaultValue: variable.defaultValue } : {},
189
+ ...variable.description !== void 0 ? { description: variable.description } : {},
190
+ required: variable.usedAsValue && variable.defaultValue === void 0,
191
+ conditionOnly: !variable.usedAsValue && !variable.usedInComparison
192
+ }));
193
+ }
194
+ function compactVariableValues(input) {
195
+ const values = {};
196
+ for (const [name, value] of Object.entries(input)) {
197
+ if (value !== null && value !== void 0 && value.trim() !== "") {
198
+ values[name] = value;
199
+ }
200
+ }
201
+ return values;
202
+ }
203
+
204
+ // src/grammar/data-source.ts
205
+ var MAX_DATA_SOURCE_RECORDS = 1e5;
206
+ var MAX_DATA_SOURCE_FIELDS = 1e3;
207
+ var AUTO_DELIMITERS = [",", ";", " "];
208
+ function detectDelimiter(text) {
209
+ const counts = new Map(AUTO_DELIMITERS.map((d) => [d, 0]));
210
+ let quoted = false;
211
+ for (let i = 0; i < text.length; i++) {
212
+ const ch = text[i];
213
+ if (ch === '"') {
214
+ quoted = !quoted;
215
+ continue;
216
+ }
217
+ if (quoted) continue;
218
+ if (ch === "\n" || ch === "\r") break;
219
+ if (counts.has(ch)) counts.set(ch, counts.get(ch) + 1);
220
+ }
221
+ let best = ",";
222
+ for (const d of AUTO_DELIMITERS) {
223
+ if (counts.get(d) > counts.get(best)) best = d;
224
+ }
225
+ return best;
226
+ }
227
+ function normalizeFieldNames(row) {
228
+ const out = [];
229
+ const taken = /* @__PURE__ */ new Set();
230
+ row.forEach((cell, i) => {
231
+ const trimmed = cellText(cell).trim();
232
+ const base = trimmed === "" ? `Column ${i + 1}` : trimmed;
233
+ let name = base;
234
+ for (let k = 2; taken.has(name.toLowerCase()); k++) name = `${base} ${k}`;
235
+ taken.add(name.toLowerCase());
236
+ out.push(name);
237
+ });
238
+ return out;
239
+ }
240
+ function cellText(value) {
241
+ if (value === null || value === void 0) return "";
242
+ if (typeof value === "string") return value;
243
+ if (typeof value === "object") {
244
+ try {
245
+ return JSON.stringify(value);
246
+ } catch {
247
+ return String(value);
248
+ }
249
+ }
250
+ return String(value);
251
+ }
252
+ function setField(record, name, value) {
253
+ Object.defineProperty(record, name, {
254
+ value,
255
+ enumerable: true,
256
+ writable: true,
257
+ configurable: true
258
+ });
259
+ }
260
+ function isBlankRow(row) {
261
+ return row.every((cell) => cellText(cell).trim() === "");
262
+ }
263
+ function parseDataSource(input, options = {}) {
264
+ const warnings = [];
265
+ if (typeof input === "string") {
266
+ const format = options.format ?? "auto";
267
+ const trimmed = input.trim();
268
+ if (format === "json" || format === "auto" && /^\[/.test(trimmed)) {
269
+ let parsed;
270
+ let ok = true;
271
+ try {
272
+ parsed = JSON.parse(trimmed);
273
+ } catch (error) {
274
+ ok = false;
275
+ if (format === "json") {
276
+ warnings.push({
277
+ code: "invalid-json",
278
+ message: `Invalid JSON: ${error.message}`
279
+ });
280
+ return { fields: [], records: [], warnings, format: "json" };
281
+ }
282
+ }
283
+ if (ok) {
284
+ if (!Array.isArray(parsed)) {
285
+ warnings.push({
286
+ code: "unsupported-json",
287
+ message: "JSON data must be an array of objects or of arrays"
288
+ });
289
+ return { fields: [], records: [], warnings, format: "json" };
290
+ }
291
+ const result2 = fromArray(parsed, options, warnings);
292
+ return { ...result2, format: "json" };
293
+ }
294
+ }
295
+ const delimiter = !options.delimiter || options.delimiter === "auto" ? detectDelimiter(input) : options.delimiter;
296
+ let rows;
297
+ try {
298
+ rows = parseCsv(input, { delimiter });
299
+ } catch (error) {
300
+ warnings.push({ code: "empty", message: error.message });
301
+ return { fields: [], records: [], warnings, format: "csv", delimiter };
302
+ }
303
+ return {
304
+ ...fromRows(rows, options, warnings),
305
+ format: "csv",
306
+ delimiter
307
+ };
308
+ }
309
+ const result = fromArray(input, options, warnings);
310
+ return {
311
+ ...result,
312
+ format: result.objects ? "objects" : "rows"
313
+ };
314
+ }
315
+ function fromArray(items, options, warnings) {
316
+ const objects = items.some(
317
+ (item) => item !== null && typeof item === "object" && !Array.isArray(item)
318
+ );
319
+ if (!objects) {
320
+ const rows2 = items.filter((item) => Array.isArray(item));
321
+ return { ...fromRows(rows2, options, warnings), objects: false };
322
+ }
323
+ const maxFields = options.maxFields ?? MAX_DATA_SOURCE_FIELDS;
324
+ const maxRecords = options.maxRecords ?? MAX_DATA_SOURCE_RECORDS;
325
+ const fields = [];
326
+ const seen = /* @__PURE__ */ new Set();
327
+ let fieldsTruncated = false;
328
+ const rows = items.filter(
329
+ (item) => item !== null && typeof item === "object" && !Array.isArray(item)
330
+ );
331
+ for (const row of rows) {
332
+ for (const key of Object.keys(row)) {
333
+ if (seen.has(key)) continue;
334
+ if (fields.length >= maxFields) {
335
+ fieldsTruncated = true;
336
+ continue;
337
+ }
338
+ seen.add(key);
339
+ fields.push(key);
340
+ }
341
+ }
342
+ if (fieldsTruncated) {
343
+ warnings.push({
344
+ code: "fields-truncated",
345
+ message: `Only the first ${maxFields} fields were kept`
346
+ });
347
+ }
348
+ const records = [];
349
+ for (const row of rows) {
350
+ if (fields.every((field) => cellText(row[field]).trim() === "")) continue;
351
+ if (records.length >= maxRecords) {
352
+ warnings.push({
353
+ code: "records-truncated",
354
+ message: `Only the first ${maxRecords} records were kept`
355
+ });
356
+ break;
357
+ }
358
+ const record = {};
359
+ for (const field of fields) {
360
+ const value = Object.prototype.hasOwnProperty.call(row, field) ? row[field] : void 0;
361
+ setField(record, field, cellText(value));
362
+ }
363
+ records.push(record);
364
+ }
365
+ if (records.length === 0) {
366
+ warnings.push({ code: "empty", message: "The data source has no records" });
367
+ }
368
+ return { fields, records, warnings, objects: true };
369
+ }
370
+ function fromRows(allRows, options, warnings) {
371
+ const maxFields = options.maxFields ?? MAX_DATA_SOURCE_FIELDS;
372
+ const maxRecords = options.maxRecords ?? MAX_DATA_SOURCE_RECORDS;
373
+ const rows = allRows.filter((row) => !isBlankRow(row));
374
+ if (rows.length === 0) {
375
+ warnings.push({ code: "empty", message: "The data source has no records" });
376
+ return { fields: [], records: [], warnings };
377
+ }
378
+ const hasHeader = options.hasHeader ?? true;
379
+ let fields;
380
+ let body;
381
+ let widest;
382
+ if (hasHeader) {
383
+ const header = rows[0];
384
+ widest = header.length;
385
+ if (header.some((cell) => cellText(cell).trim() === "")) {
386
+ warnings.push({
387
+ code: "blank-header",
388
+ message: 'Blank column headers were named "Column N"'
389
+ });
390
+ }
391
+ fields = normalizeFieldNames(header.slice(0, maxFields));
392
+ const lower = header.map((cell) => cellText(cell).trim().toLowerCase());
393
+ if (lower.some((name, i) => name !== "" && lower.indexOf(name) !== i)) {
394
+ warnings.push({
395
+ code: "duplicate-header",
396
+ message: "Repeated column headers were numbered"
397
+ });
398
+ }
399
+ body = rows.slice(1);
400
+ } else {
401
+ widest = Math.max(...rows.map((row) => row.length));
402
+ fields = Array.from(
403
+ { length: Math.min(widest, maxFields) },
404
+ (_, i) => `Column ${i + 1}`
405
+ );
406
+ body = rows;
407
+ }
408
+ if (widest > maxFields) {
409
+ warnings.push({
410
+ code: "fields-truncated",
411
+ message: `Only the first ${maxFields} fields were kept`
412
+ });
413
+ }
414
+ if (body.length > maxRecords) {
415
+ warnings.push({
416
+ code: "records-truncated",
417
+ message: `Only the first ${maxRecords} of ${body.length} records were kept`
418
+ });
419
+ body = body.slice(0, maxRecords);
420
+ }
421
+ let ragged = 0;
422
+ const records = body.map((row) => {
423
+ if (hasHeader && row.length !== widest) ragged++;
424
+ const record = {};
425
+ fields.forEach((field, i) => setField(record, field, cellText(row[i])));
426
+ return record;
427
+ });
428
+ if (ragged > 0) {
429
+ warnings.push({
430
+ code: "ragged-rows",
431
+ message: `${ragged} record${ragged === 1 ? " was" : "s were"} padded or cut to ${widest} fields`,
432
+ count: ragged
433
+ });
434
+ }
435
+ if (records.length === 0) {
436
+ warnings.push({ code: "empty", message: "The data source has no records" });
437
+ }
438
+ return { fields, records, warnings };
439
+ }
440
+ function normalizeFieldKey(name) {
441
+ return name.toLowerCase().replace(/[\s_.\-]+/g, "");
442
+ }
443
+ var FIELD_ALIASES = [
444
+ ["FirstName", "First", "GivenName", "Forename", "FName"],
445
+ ["LastName", "Last", "Surname", "FamilyName", "LName"],
446
+ ["Name", "FullName", "DisplayName"],
447
+ ["Company", "CompanyName", "Organization", "Organisation", "Employer", "Business"],
448
+ ["Address", "AddressLine1", "Address1", "Street", "StreetAddress"],
449
+ ["City", "Town"],
450
+ ["State", "Province", "Region", "County"],
451
+ ["PostalCode", "ZIP", "ZipCode", "Postcode"],
452
+ ["Country", "CountryName", "Nation"],
453
+ ["Title", "CourtesyTitle", "Salutation", "Honorific"],
454
+ ["Email", "EmailAddress", "Mail", "EMail"],
455
+ ["Phone", "PhoneNumber", "Telephone", "Tel", "Mobile"]
456
+ ];
457
+ function matchFields(variables, fields, options = {}) {
458
+ const names = Array.from(
459
+ new Set(variables.map((v) => typeof v === "string" ? v : v.name))
460
+ );
461
+ const byKey = /* @__PURE__ */ new Map();
462
+ for (const field of fields) {
463
+ const key = normalizeFieldKey(field);
464
+ if (!byKey.has(key)) byKey.set(key, field);
465
+ }
466
+ const groups = [...FIELD_ALIASES, ...options.aliases ?? []].map(
467
+ (group) => group.map(normalizeFieldKey)
468
+ );
469
+ const matches = names.map((variable) => {
470
+ if (fields.includes(variable)) {
471
+ return { variable, field: variable, kind: "exact" };
472
+ }
473
+ const key = normalizeFieldKey(variable);
474
+ const normalized = byKey.get(key);
475
+ if (normalized !== void 0) {
476
+ return { variable, field: normalized, kind: "normalized" };
477
+ }
478
+ for (const group of groups) {
479
+ if (!group.includes(key)) continue;
480
+ for (const alias of group) {
481
+ const field = byKey.get(alias);
482
+ if (field !== void 0) return { variable, field, kind: "alias" };
483
+ }
484
+ }
485
+ return { variable, field: null, kind: null };
486
+ });
487
+ const mapping = {};
488
+ for (const match of matches) {
489
+ Object.defineProperty(mapping, match.variable, {
490
+ value: match.field,
491
+ enumerable: true,
492
+ writable: true,
493
+ configurable: true
494
+ });
495
+ }
496
+ const used = new Set(matches.map((m) => m.field));
497
+ return {
498
+ mapping,
499
+ matches,
500
+ unmatchedVariables: matches.filter((m) => !m.field).map((m) => m.variable),
501
+ unusedFields: fields.filter((field) => !used.has(field))
502
+ };
503
+ }
504
+ function recordToValues(record, mapping = {}, options = {}) {
505
+ const blankAsMissing = options.blankAsMissing ?? true;
506
+ const values = {};
507
+ const assign = (name, value) => {
508
+ if (value === void 0 || blankAsMissing && value.trim() === "") {
509
+ delete values[name];
510
+ return;
511
+ }
512
+ Object.defineProperty(values, name, {
513
+ value,
514
+ enumerable: true,
515
+ writable: true,
516
+ configurable: true
517
+ });
518
+ };
519
+ const own = (name) => Object.prototype.hasOwnProperty.call(record, name) ? record[name] : void 0;
520
+ for (const field of Object.keys(record)) assign(field, record[field]);
521
+ for (const variable of Object.keys(mapping)) {
522
+ const field = mapping[variable];
523
+ if (field === void 0) continue;
524
+ assign(variable, field === null ? void 0 : own(field));
525
+ }
526
+ return values;
527
+ }
528
+
529
+ // src/grammar/merge.ts
530
+ var MAX_MERGE_OUTPUTS = 1e4;
531
+ var MAX_MERGE_LENGTH = 2e7;
532
+ function isParsedSource(source) {
533
+ return !!source && typeof source === "object" && !Array.isArray(source) && Array.isArray(source.fields) && Array.isArray(source.records);
534
+ }
535
+ function mergeRecords(template, source, options = {}) {
536
+ const data = isParsedSource(source) ? source : parseDataSource(source, options.parse);
537
+ const diagnostics = [];
538
+ if (!isParsedSource(source)) {
539
+ for (const warning of data.warnings) {
540
+ if (warning.code === "empty") continue;
541
+ diagnostics.push({ code: "data-source", message: warning.message });
542
+ }
543
+ }
544
+ const variables = extractVariables(template, {
545
+ templates: options.templates,
546
+ bindings: options.bindings,
547
+ maxDepth: options.maxDepth
548
+ });
549
+ const auto = matchFields(variables, data.fields).mapping;
550
+ const mapping = { ...auto };
551
+ for (const [variable, field] of Object.entries(options.mapping ?? {})) {
552
+ Object.defineProperty(mapping, variable, {
553
+ value: field,
554
+ enumerable: true,
555
+ writable: true,
556
+ configurable: true
557
+ });
558
+ }
559
+ for (const variable of variables) {
560
+ const field = mapping[variable.name];
561
+ if ((field === null || field === void 0) && variable.defaultValue === void 0 && variable.usedAsValue) {
562
+ diagnostics.push({
563
+ code: "unmapped-variable",
564
+ message: `No field is mapped to "${variable.name}", so it stays as a placeholder`,
565
+ name: variable.name
566
+ });
567
+ }
568
+ }
569
+ let skip;
570
+ if (typeof options.skipIf === "function") {
571
+ skip = options.skipIf;
572
+ } else if (typeof options.skipIf === "string" && options.skipIf.trim()) {
573
+ const parsed = parseConditionExpression(options.skipIf);
574
+ if ("error" in parsed) {
575
+ diagnostics.push({
576
+ code: "invalid-skip-condition",
577
+ message: `Invalid skipIf condition "${options.skipIf}": ${parsed.error}`
578
+ });
579
+ } else {
580
+ const field = mapping[parsed.name] ?? matchFields([parsed.name], data.fields).mapping[parsed.name];
581
+ skip = (record, values) => {
582
+ if (field && !Object.prototype.hasOwnProperty.call(values, parsed.name) && Object.prototype.hasOwnProperty.call(record, field)) {
583
+ return evaluateConditionExpression(parsed, {
584
+ ...values,
585
+ [parsed.name]: record[field]
586
+ });
587
+ }
588
+ return evaluateConditionExpression(parsed, values);
589
+ };
590
+ }
591
+ }
592
+ const separator = options.separator === void 0 ? "\n\n" : options.separator === "none" ? "" : options.separator;
593
+ const maxOutputs = Math.max(0, options.maxOutputs ?? MAX_MERGE_OUTPUTS);
594
+ const maxLength = Math.max(0, options.maxLength ?? MAX_MERGE_LENGTH);
595
+ const first = Math.max(1, Math.floor(options.from ?? 1)) - 1;
596
+ const last = Math.min(
597
+ data.records.length,
598
+ Math.floor(options.to ?? data.records.length)
599
+ );
600
+ const outputs = [];
601
+ const skipped = [];
602
+ let length = 0;
603
+ let truncated = false;
604
+ let reportedGrammar = false;
605
+ for (let index = first; index < last; index++) {
606
+ const record = data.records[index];
607
+ const values = recordToValues(record, mapping, {
608
+ blankAsMissing: options.blankAsMissing
609
+ });
610
+ if (skip?.(record, values, index)) {
611
+ skipped.push({ index, record, reason: "skip-if" });
612
+ continue;
613
+ }
614
+ if (outputs.length >= maxOutputs) {
615
+ truncated = true;
616
+ diagnostics.push({
617
+ code: "max-outputs",
618
+ message: `Stopped after ${maxOutputs} outputs`
619
+ });
620
+ break;
621
+ }
622
+ const resolved = resolvePrompt(template, options.templates, {
623
+ bindings: options.bindings,
624
+ maxDepth: options.maxDepth,
625
+ values
626
+ });
627
+ if (!reportedGrammar) {
628
+ reportedGrammar = true;
629
+ diagnostics.push(...resolved.diagnostics);
630
+ }
631
+ const added = resolved.text.length + (outputs.length > 0 ? separator.length : 0);
632
+ if (length + added > maxLength) {
633
+ truncated = true;
634
+ diagnostics.push({
635
+ code: "max-length",
636
+ message: `Stopped at ${outputs.length} outputs: the merged text would exceed ${maxLength} characters`
637
+ });
638
+ break;
639
+ }
640
+ length += added;
641
+ outputs.push({ index, record, values, text: resolved.text, map: resolved.map });
642
+ }
643
+ return {
644
+ outputs,
645
+ skipped,
646
+ diagnostics,
647
+ text: outputs.map((output) => output.text).join(separator),
648
+ mapping,
649
+ truncated
650
+ };
651
+ }
652
+ function serializeMergeOutputs(outputs, format = "text", separator = "\n\n") {
653
+ if (format === "json") {
654
+ return JSON.stringify(
655
+ outputs.map((output) => ({ record: output.index + 1, text: output.text })),
656
+ null,
657
+ 2
658
+ );
659
+ }
660
+ return outputs.map((output) => output.text).join(separator === "none" ? "" : separator);
661
+ }
662
+
663
+ export {
664
+ resolveTemplates,
665
+ resolveVariables,
666
+ extractTemplateNames,
667
+ extractVariableNames,
668
+ extractInstructionNames,
669
+ resolveTemplatesWithMapping,
670
+ mapResolvedOffsetToRaw,
671
+ mapRawOffsetToResolved,
672
+ extractVariables,
673
+ getVariableFormFields,
674
+ compactVariableValues,
675
+ MAX_DATA_SOURCE_RECORDS,
676
+ MAX_DATA_SOURCE_FIELDS,
677
+ detectDelimiter,
678
+ normalizeFieldNames,
679
+ parseDataSource,
680
+ normalizeFieldKey,
681
+ FIELD_ALIASES,
682
+ matchFields,
683
+ recordToValues,
684
+ MAX_MERGE_OUTPUTS,
685
+ MAX_MERGE_LENGTH,
686
+ mergeRecords,
687
+ serializeMergeOutputs
688
+ };
689
+ //# sourceMappingURL=chunk-OXSV64JX.js.map