@mono-lit/helper 0.0.9 → 0.0.10

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 (161) hide show
  1. package/dist/accordion-core-DaNyPWRr.js +277 -0
  2. package/dist/alert-core-DWtHbX_-.js +134 -0
  3. package/dist/breadcrumb-list-core-Dh68T8Cf.js +747 -0
  4. package/dist/{mono-button-CLkHg3WW.js → button-core-DerXg84Q.js} +3 -276
  5. package/dist/button-dropdown-core-DKYEOyjy.js +654 -0
  6. package/dist/button-utils-D5-66M02.js +63 -0
  7. package/dist/card-utils-l80qAmrN.js +312 -0
  8. package/dist/chart-core-DV7hD3ZY.js +801 -0
  9. package/dist/checkbox-utils-DKdrhAzF.js +337 -0
  10. package/dist/chip-utils-DpRrd7Zj.js +403 -0
  11. package/dist/{data-source-controller-C6C4ej_M.js → data-source-controller-DS_JLrmS.js} +1 -1
  12. package/dist/{data-source-options-fxT5QIX4.js → data-source-options-DJUNU26C.js} +6 -6
  13. package/dist/{data-source-read-BL266IW0.js → data-source-read-uKJpRAzx.js} +2 -2
  14. package/dist/date-core-CyuSyvvG.js +734 -0
  15. package/dist/drawer-core-DbFWvNln.js +759 -0
  16. package/dist/dropdown-core-BCH1pK14.js +511 -0
  17. package/dist/dropdown-table-core-SfHUJVFq.js +1342 -0
  18. package/dist/export.js +1 -1
  19. package/dist/{field-path-BabiMrrA.js → field-path-DK2VBWHl.js} +1 -1
  20. package/dist/field-tooltip.css_raw-DVblekCl.js +5 -0
  21. package/dist/{field-validation.css_raw-Cx6SGrfP.js → field-validation.css_raw-BU7C6173.js} +1 -170
  22. package/dist/file-upload-core-Cz_dBQMx.js +624 -0
  23. package/dist/filter-builder-core-DyWjbBP7.js +381 -0
  24. package/dist/{filter-builder-B6Y2mmbM.js → filter-builder-vbqIuPhX.js} +1 -1
  25. package/dist/{filter-eval-ChDSaAUH.js → filter-eval-CqeBnMYh.js} +1 -1
  26. package/dist/{filter-odata-Bi27XUpQ.js → filter-odata-GsczYKNC.js} +1 -1
  27. package/dist/{hydration-flush-BaE9gN3C.js → hydration-flush-Volt9X7Q.js} +2 -1071
  28. package/dist/index.js +11 -11
  29. package/dist/{index.node-DTqDBca7.js → index.node-Csy9zrr1.js} +4 -4
  30. package/dist/index.node.js +11 -11
  31. package/dist/input-utils-BglY-k0H.js +1145 -0
  32. package/dist/menu-core-DkAYuCZ2.js +831 -0
  33. package/dist/modal-core-CSBSPN_m.js +844 -0
  34. package/dist/mono-button-DVvZ03P-.js +280 -0
  35. package/dist/{mono-button.shadow-DqZMpcqY.js → mono-button.shadow-BANxMGln.js} +6 -594
  36. package/dist/{mono-data-chart-NKPdAgVq.js → mono-data-chart-ChF4J9RT.js} +6 -6
  37. package/dist/{mono-data-dropdown-B2iRpJuI.js → mono-data-dropdown-Bgj2PDfm.js} +1 -1
  38. package/dist/{mono-data-grid-llJCX9MC.js → mono-data-grid-DJkp96N-.js} +144 -46
  39. package/dist/{mono-event-BPku9HpS.js → mono-event-CAZf0F_k.js} +14 -9
  40. package/dist/{mono-form-controller-BrA10erm.js → mono-form-controller-DxZLvyg6.js} +2 -1
  41. package/dist/mono-table-checkbox-core-BKOMx8R5.js +5288 -0
  42. package/dist/nav-core-B5qU2dzn.js +225 -0
  43. package/dist/{normalize-error-D93O4q8g.js → normalize-error-BEcd1tmS.js} +2 -2
  44. package/dist/otp-core-DXg3vFLh.js +758 -0
  45. package/dist/radio-utils-Dk9Tl1jz.js +319 -0
  46. package/dist/rich-text-editor-core-Ddd_QaLn.js +1280 -0
  47. package/dist/select-utils-BgArYHk8.js +2140 -0
  48. package/dist/sidebar-core-CD6txDo3.js +583 -0
  49. package/dist/slider-core-vcWr321-.js +1014 -0
  50. package/dist/src/components/dropdown-table/dropdown-table-core.d.ts +2 -2
  51. package/dist/src/components/dropdown-table/dropdown-table-types.d.ts +1 -1
  52. package/dist/src/components/dropdown-table/index.d.ts +1 -1
  53. package/dist/src/components/dropdown-table/index.shadow.d.ts +1 -1
  54. package/dist/src/components/dropdown-table/mono-data-dropdown.d.ts +1 -1
  55. package/dist/src/components/form/form-types.d.ts +9 -3
  56. package/dist/src/components/input/input-core.d.ts +1 -1
  57. package/dist/src/components/input/input-types.d.ts +1 -1
  58. package/dist/src/components/otp/otp-core.d.ts +1 -1
  59. package/dist/src/components/select/select-core.d.ts +1 -1
  60. package/dist/src/components/select/select-types.d.ts +1 -1
  61. package/dist/src/components/slider/slider-core.d.ts +1 -1
  62. package/dist/src/components/slider/slider-types.d.ts +1 -1
  63. package/dist/src/components/table/filter-suggestion.d.ts +171 -0
  64. package/dist/src/components/table/index.d.ts +5 -4
  65. package/dist/src/components/table/index.shadow.d.ts +5 -4
  66. package/dist/src/components/table/mono-data-grid.d.ts +22 -3
  67. package/dist/src/components/table/mono-table-empty-core.d.ts +37 -0
  68. package/dist/src/components/table/mono-table-search-core.d.ts +22 -3
  69. package/dist/src/components/table/table-types.d.ts +74 -4
  70. package/dist/src/components/tag-input/tag-input-core.d.ts +1 -1
  71. package/dist/src/components/tag-input/tag-input-types.d.ts +1 -1
  72. package/dist/src/components/textarea/textarea-core.d.ts +1 -1
  73. package/dist/src/composables/mono-event.d.ts +7 -1
  74. package/dist/src/entries/index.d.ts +8 -6
  75. package/dist/src/entries/index.node.d.ts +8 -6
  76. package/dist/src/search/index.d.ts +1 -1
  77. package/dist/src/utils/group-count.d.ts +36 -0
  78. package/dist/switch-utils-CTZ4id2V.js +338 -0
  79. package/dist/tabs-core-r5-B8k_N.js +317 -0
  80. package/dist/tag-input-utils-D2JA90DQ.js +3060 -0
  81. package/dist/textarea-utils-VU1KeXm8.js +821 -0
  82. package/dist/ui/accordion.js +2 -274
  83. package/dist/ui/alert.js +2 -131
  84. package/dist/ui/breadcrumb.js +4 -745
  85. package/dist/ui/button-dropdown.js +4 -652
  86. package/dist/ui/button.js +2 -63
  87. package/dist/ui/card.js +2 -310
  88. package/dist/ui/chart.js +4 -800
  89. package/dist/ui/checkbox.js +4 -335
  90. package/dist/ui/chip.js +4 -402
  91. package/dist/ui/date.js +3 -732
  92. package/dist/ui/drawer.js +3 -757
  93. package/dist/ui/dropdown-table.js +5 -1341
  94. package/dist/ui/dropdown.js +4 -509
  95. package/dist/ui/file-upload.js +3 -622
  96. package/dist/ui/filter.js +5 -380
  97. package/dist/ui/form.js +1 -1
  98. package/dist/ui/index.css +118 -1
  99. package/dist/ui/input.js +3 -1141
  100. package/dist/ui/menu.js +4 -828
  101. package/dist/ui/modal.js +4 -843
  102. package/dist/ui/nav.js +4 -223
  103. package/dist/ui/otp.js +4 -756
  104. package/dist/ui/radio.js +4 -317
  105. package/dist/ui/rich-text-editor.js +4 -1278
  106. package/dist/ui/select.js +5 -2138
  107. package/dist/ui/shadow/accordion.js +4 -273
  108. package/dist/ui/shadow/alert.js +4 -130
  109. package/dist/ui/shadow/breadcrumb.js +5 -744
  110. package/dist/ui/shadow/button-dropdown.js +6 -652
  111. package/dist/ui/shadow/button.js +3 -63
  112. package/dist/ui/shadow/card.js +4 -309
  113. package/dist/ui/shadow/chart.js +6 -1576
  114. package/dist/ui/shadow/checkbox.js +4 -334
  115. package/dist/ui/shadow/chip.js +4 -396
  116. package/dist/ui/shadow/date.js +7 -731
  117. package/dist/ui/shadow/drawer.js +4 -756
  118. package/dist/ui/shadow/dropdown-table.js +8 -1762
  119. package/dist/ui/shadow/dropdown.js +4 -508
  120. package/dist/ui/shadow/file-upload.js +4 -620
  121. package/dist/ui/shadow/filter.js +7 -379
  122. package/dist/ui/shadow/input.js +6 -1140
  123. package/dist/ui/shadow/menu.js +5 -828
  124. package/dist/ui/shadow/modal.js +6 -1063
  125. package/dist/ui/shadow/nav.js +5 -223
  126. package/dist/ui/shadow/otp.js +6 -754
  127. package/dist/ui/shadow/radio.js +4 -316
  128. package/dist/ui/shadow/rich-text-editor.js +4 -1276
  129. package/dist/ui/shadow/select.js +6 -2136
  130. package/dist/ui/shadow/sidebar.js +5 -581
  131. package/dist/ui/shadow/slider.js +5 -1010
  132. package/dist/ui/shadow/switch.js +4 -335
  133. package/dist/ui/shadow/table.js +10 -4501
  134. package/dist/ui/shadow/tabs.js +6 -315
  135. package/dist/ui/shadow/tag-input.js +7 -3057
  136. package/dist/ui/shadow/textarea.js +6 -817
  137. package/dist/ui/sidebar.js +3 -581
  138. package/dist/ui/slider.js +4 -1012
  139. package/dist/ui/switch.js +4 -336
  140. package/dist/ui/table.js +9 -4502
  141. package/dist/ui/tabs.js +4 -315
  142. package/dist/ui/tag-input.js +5 -3058
  143. package/dist/ui/textarea.js +4 -819
  144. package/dist/vue.d.ts +3 -2
  145. package/package.json +3 -3
  146. package/dist/chip-strip-bNfLn52Z.js +0 -215
  147. package/dist/data-source-controller-Dx6IQ2CN.js +0 -243
  148. package/dist/data-source-options-BM4r4PRw.js +0 -558
  149. package/dist/data-source-read-HyBCRg1t.js +0 -242
  150. package/dist/excel-BXzr3uI1.js +0 -784
  151. package/dist/export-ixRdCS2y.js +0 -2388
  152. package/dist/field-tooltip-addon-CWCp19mJ.js +0 -702
  153. package/dist/field-tooltip.css_raw-U5UeTa2d.js +0 -269
  154. package/dist/filter-builder-C0T3pMx2.js +0 -208
  155. package/dist/form-control-core-BbiACMtL.js +0 -226
  156. package/dist/icon-ClxnYhBG.js +0 -19
  157. package/dist/import-Dc4eXC02.js +0 -612
  158. package/dist/light-slots-_no0r2Z-.js +0 -246
  159. package/dist/markdown-uGlE_OfJ.js +0 -20191
  160. package/dist/mono-data-grid-e9ZVBlNN.js +0 -4240
  161. package/dist/normalize-error-BmLbgANw.js +0 -1048
@@ -1,2388 +0,0 @@
1
- import { a as stripDirectives, i as escapeCellText, n as parseMarkdown, o as __commonJSMin, r as encodeDirective, s as __toESM } from "./markdown-uGlE_OfJ.js";
2
- import { n as isReadableSource, r as readAllRows } from "./data-source-read-HyBCRg1t.js";
3
- import { n as unwrapReactive } from "./reactive-Dtd-esHO.js";
4
- import { t as DEFAULT_STYLES } from "./excel-BXzr3uI1.js";
5
-
6
- //#region src/export/download.ts
7
- /**
8
- * Browser download helper. Kept separate (and DOM-guarded) so the report engine
9
- * can still render on a server — where `download()` is simply a no-op warning
10
- * rather than a crash.
11
- */
12
- /** MIME type per output format. */
13
- const MIME = {
14
- md: "text/markdown;charset=utf-8",
15
- xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
16
- };
17
- /** Save a Blob to disk via a transient `<a download>`. Browser only. */
18
- function downloadBlob(blob, fileName) {
19
- if (typeof document === "undefined" || typeof URL?.createObjectURL !== "function") {
20
- console.warn("[mono-export] download() needs a browser environment — skipped.");
21
- return;
22
- }
23
- const url = URL.createObjectURL(blob);
24
- const anchor = document.createElement("a");
25
- anchor.href = url;
26
- anchor.download = fileName;
27
- anchor.style.display = "none";
28
- document.body.appendChild(anchor);
29
- anchor.click();
30
- document.body.removeChild(anchor);
31
- setTimeout(() => URL.revokeObjectURL(url), 0);
32
- }
33
-
34
- //#endregion
35
- //#region src/export/detail.ts
36
- function readPath(row, path) {
37
- if (path in row) return row[path];
38
- return path.split(".").reduce((acc, part) => acc == null ? acc : acc[part], row);
39
- }
40
- /**
41
- * Run `task` over `items` with at most `limit` in flight.
42
- *
43
- * Deliberately NOT `Promise.all` over the whole list. The implementation this
44
- * replaces fires every batch at once and wraps the lot in a single `.catch`, so
45
- * one flaky request loses a multi-minute export and discards the error with it.
46
- * Here a rejection is captured per item, and the rest of the workbook is still
47
- * produced.
48
- *
49
- * The items are CHUNKS of master rows, not single documents — see the note at
50
- * the top of this file.
51
- */
52
- async function pool(items, limit, task) {
53
- const out = new Array(items.length);
54
- let cursor = 0;
55
- const worker = async () => {
56
- for (;;) {
57
- const index = cursor;
58
- cursor += 1;
59
- if (index >= items.length) return;
60
- try {
61
- out[index] = {
62
- status: "fulfilled",
63
- value: await task(items[index])
64
- };
65
- } catch (error) {
66
- out[index] = {
67
- status: "rejected",
68
- reason: error
69
- };
70
- }
71
- }
72
- };
73
- const size = Math.max(1, Math.min(limit, items.length));
74
- await Promise.all(Array.from({ length: size }, worker));
75
- return out;
76
- }
77
- /**
78
- * Turn master rows into per-document detail rows.
79
- *
80
- * A document with no rows is reported in `skipped` rather than given an empty
81
- * sheet — an empty worksheet behind a link is worse than no link, and the
82
- * caller gets told which documents those were instead of having to diff the
83
- * tab list.
84
- */
85
- async function resolveDetails(masterRows, detail) {
86
- const rows = masterRows.filter((row) => !!row && typeof row === "object");
87
- const keyOf = (row) => String(readPath(row, detail.key) ?? "");
88
- const details = [];
89
- const skipped = [];
90
- const collect = (row, value) => {
91
- const key = keyOf(row);
92
- const list = Array.isArray(value) ? value : [];
93
- if (!key || !list.length) {
94
- skipped.push({
95
- key: key || "(no key)",
96
- reason: "empty"
97
- });
98
- return;
99
- }
100
- details.push({
101
- row,
102
- key,
103
- rows: list
104
- });
105
- };
106
- if (typeof detail.load === "function") {
107
- const size = Math.max(1, Math.floor(detail.loadChunk ?? 100));
108
- const chunks = [];
109
- for (let i = 0; i < rows.length; i += size) chunks.push(rows.slice(i, i + size));
110
- const groupBy = detail.groupBy ?? detail.key;
111
- const groupOf = typeof groupBy === "function" ? groupBy : (row) => readPath(row, groupBy);
112
- (await pool(chunks, detail.concurrency ?? 4, (chunk) => Promise.resolve(detail.load({
113
- data: chunk,
114
- keys: [...new Set(chunk.map((row) => readPath(row, detail.key)))],
115
- key: detail.key
116
- })))).forEach((result, index) => {
117
- const chunk = chunks[index];
118
- if (result.status === "rejected") {
119
- for (const row of chunk) skipped.push({
120
- key: keyOf(row) || "(no key)",
121
- reason: "failed",
122
- error: result.reason
123
- });
124
- return;
125
- }
126
- const byKey = /* @__PURE__ */ new Map();
127
- for (const row of Array.isArray(result.value) ? result.value : []) {
128
- if (!row || typeof row !== "object") continue;
129
- const key = String(groupOf(row) ?? "");
130
- if (!key) continue;
131
- const bucket = byKey.get(key);
132
- if (bucket) bucket.push(row);
133
- else byKey.set(key, [row]);
134
- }
135
- for (const row of chunk) collect(row, byKey.get(keyOf(row)) ?? []);
136
- });
137
- return {
138
- details,
139
- skipped
140
- };
141
- }
142
- if (detail.field) {
143
- for (const row of rows) collect(row, readPath(row, detail.field));
144
- return {
145
- details,
146
- skipped
147
- };
148
- }
149
- throw new Error("[mono-export] `detail` needs either `field` or `load`.");
150
- }
151
-
152
- //#endregion
153
- //#region src/export/resolve-data.ts
154
- /**
155
- * Turning live data sources in `options.data` into plain arrays.
156
- *
157
- * A template can only loop over an array, but the thing a consumer *has* is
158
- * usually a devextreme DataSource. Rather than making everyone drain it by hand
159
- * before every export, any DataSource-shaped value in `data` is drained here
160
- * first — in chunks, honouring whatever filter / search / sort the source
161
- * already carries — so the template just sees rows:
162
- *
163
- * ```ts
164
- * data: { program: dataSourceProgramTransfer.value }
165
- * ```
166
- * ```hbs
167
- * {{#each program}}| {{NoDokumen}} | {{currency TotalBudget}} |
168
- * {{/each}}
169
- * ```
170
- */
171
- /**
172
- * Replace every DataSource / store in `data`'s **top level** with its rows.
173
- *
174
- * Top-level only, deliberately: it's predictable, and a deep walk would mean
175
- * inspecting every record of every array already in `data` — a real cost for a
176
- * 10k-row export, to support a nesting nobody has asked for. A source nested
177
- * deeper stays the caller's job (`await table.getData()` and pass the array).
178
- *
179
- * Sources are drained concurrently — several are independent queries, and a
180
- * report with three of them shouldn't take three times as long.
181
- */
182
- async function resolveExportData(data, options = {}) {
183
- if (!data) return {};
184
- const entries = Object.entries(data);
185
- const pending = [];
186
- const out = {};
187
- for (const [key, raw] of entries) {
188
- const value = unwrapReactive(raw);
189
- if (isReadableSource(value)) pending.push(readAllRows(value, { chunkSize: options.chunkSize }).then((rows) => {
190
- out[key] = rows;
191
- }));
192
- else out[key] = value;
193
- }
194
- if (pending.length) await Promise.all(pending);
195
- return out;
196
- }
197
-
198
- //#endregion
199
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/interopRequireDefault.js
200
- var require_interopRequireDefault = /* @__PURE__ */ __commonJSMin(((exports, module) => {
201
- function _interopRequireDefault(e) {
202
- return e && e.__esModule ? e : { "default": e };
203
- }
204
- module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports;
205
- }));
206
-
207
- //#endregion
208
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/typeof.js
209
- var require_typeof = /* @__PURE__ */ __commonJSMin(((exports, module) => {
210
- function _typeof(o) {
211
- "@babel/helpers - typeof";
212
- return module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
213
- return typeof o;
214
- } : function(o) {
215
- return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
216
- }, module.exports.__esModule = true, module.exports["default"] = module.exports, _typeof(o);
217
- }
218
- module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports;
219
- }));
220
-
221
- //#endregion
222
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/toPrimitive.js
223
- var require_toPrimitive = /* @__PURE__ */ __commonJSMin(((exports, module) => {
224
- var _typeof = require_typeof()["default"];
225
- function toPrimitive(t, r) {
226
- if ("object" != _typeof(t) || !t) return t;
227
- var e = t[Symbol.toPrimitive];
228
- if (void 0 !== e) {
229
- var i = e.call(t, r || "default");
230
- if ("object" != _typeof(i)) return i;
231
- throw new TypeError("@@toPrimitive must return a primitive value.");
232
- }
233
- return ("string" === r ? String : Number)(t);
234
- }
235
- module.exports = toPrimitive, module.exports.__esModule = true, module.exports["default"] = module.exports;
236
- }));
237
-
238
- //#endregion
239
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/toPropertyKey.js
240
- var require_toPropertyKey = /* @__PURE__ */ __commonJSMin(((exports, module) => {
241
- var _typeof = require_typeof()["default"];
242
- var toPrimitive = require_toPrimitive();
243
- function toPropertyKey(t) {
244
- var i = toPrimitive(t, "string");
245
- return "symbol" == _typeof(i) ? i : i + "";
246
- }
247
- module.exports = toPropertyKey, module.exports.__esModule = true, module.exports["default"] = module.exports;
248
- }));
249
-
250
- //#endregion
251
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/defineProperty.js
252
- var require_defineProperty = /* @__PURE__ */ __commonJSMin(((exports, module) => {
253
- var toPropertyKey = require_toPropertyKey();
254
- function _defineProperty(e, r, t) {
255
- return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
256
- value: t,
257
- enumerable: !0,
258
- configurable: !0,
259
- writable: !0
260
- }) : e[r] = t, e;
261
- }
262
- module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports;
263
- }));
264
-
265
- //#endregion
266
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/classCallCheck.js
267
- var require_classCallCheck = /* @__PURE__ */ __commonJSMin(((exports, module) => {
268
- function _classCallCheck(a, n) {
269
- if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
270
- }
271
- module.exports = _classCallCheck, module.exports.__esModule = true, module.exports["default"] = module.exports;
272
- }));
273
-
274
- //#endregion
275
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/createClass.js
276
- var require_createClass = /* @__PURE__ */ __commonJSMin(((exports, module) => {
277
- var toPropertyKey = require_toPropertyKey();
278
- function _defineProperties(e, r) {
279
- for (var t = 0; t < r.length; t++) {
280
- var o = r[t];
281
- o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, toPropertyKey(o.key), o);
282
- }
283
- }
284
- function _createClass(e, r, t) {
285
- return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e;
286
- }
287
- module.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports;
288
- }));
289
-
290
- //#endregion
291
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/arrayLikeToArray.js
292
- var require_arrayLikeToArray = /* @__PURE__ */ __commonJSMin(((exports, module) => {
293
- function _arrayLikeToArray(r, a) {
294
- (null == a || a > r.length) && (a = r.length);
295
- for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
296
- return n;
297
- }
298
- module.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
299
- }));
300
-
301
- //#endregion
302
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/arrayWithoutHoles.js
303
- var require_arrayWithoutHoles = /* @__PURE__ */ __commonJSMin(((exports, module) => {
304
- var arrayLikeToArray = require_arrayLikeToArray();
305
- function _arrayWithoutHoles(r) {
306
- if (Array.isArray(r)) return arrayLikeToArray(r);
307
- }
308
- module.exports = _arrayWithoutHoles, module.exports.__esModule = true, module.exports["default"] = module.exports;
309
- }));
310
-
311
- //#endregion
312
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/iterableToArray.js
313
- var require_iterableToArray = /* @__PURE__ */ __commonJSMin(((exports, module) => {
314
- function _iterableToArray(r) {
315
- if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
316
- }
317
- module.exports = _iterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
318
- }));
319
-
320
- //#endregion
321
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js
322
- var require_unsupportedIterableToArray = /* @__PURE__ */ __commonJSMin(((exports, module) => {
323
- var arrayLikeToArray = require_arrayLikeToArray();
324
- function _unsupportedIterableToArray(r, a) {
325
- if (r) {
326
- if ("string" == typeof r) return arrayLikeToArray(r, a);
327
- var t = {}.toString.call(r).slice(8, -1);
328
- return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? arrayLikeToArray(r, a) : void 0;
329
- }
330
- }
331
- module.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
332
- }));
333
-
334
- //#endregion
335
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/nonIterableSpread.js
336
- var require_nonIterableSpread = /* @__PURE__ */ __commonJSMin(((exports, module) => {
337
- function _nonIterableSpread() {
338
- throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
339
- }
340
- module.exports = _nonIterableSpread, module.exports.__esModule = true, module.exports["default"] = module.exports;
341
- }));
342
-
343
- //#endregion
344
- //#region ../../node_modules/.pnpm/@babel+runtime@7.26.10/node_modules/@babel/runtime/helpers/toConsumableArray.js
345
- var require_toConsumableArray = /* @__PURE__ */ __commonJSMin(((exports, module) => {
346
- var arrayWithoutHoles = require_arrayWithoutHoles();
347
- var iterableToArray = require_iterableToArray();
348
- var unsupportedIterableToArray = require_unsupportedIterableToArray();
349
- var nonIterableSpread = require_nonIterableSpread();
350
- function _toConsumableArray(r) {
351
- return arrayWithoutHoles(r) || iterableToArray(r) || unsupportedIterableToArray(r) || nonIterableSpread();
352
- }
353
- module.exports = _toConsumableArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
354
- }));
355
-
356
- //#endregion
357
- //#region ../../node_modules/.pnpm/jexl@2.3.0/node_modules/jexl/dist/evaluator/handlers.js
358
- var require_handlers$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
359
- var _toConsumableArray2 = require_interopRequireDefault()(require_toConsumableArray());
360
- var poolNames = {
361
- functions: "Jexl Function",
362
- transforms: "Transform"
363
- };
364
- /**
365
- * Evaluates an ArrayLiteral by returning its value, with each element
366
- * independently run through the evaluator.
367
- * @param {{type: 'ObjectLiteral', value: <{}>}} ast An expression tree with an
368
- * ObjectLiteral as the top node
369
- * @returns {Promise.<[]>} resolves to a map contained evaluated values.
370
- * @private
371
- */
372
- exports.ArrayLiteral = function(ast) {
373
- return this.evalArray(ast.value);
374
- };
375
- /**
376
- * Evaluates a BinaryExpression node by running the Grammar's evaluator for
377
- * the given operator. Note that binary expressions support two types of
378
- * evaluators: `eval` is called with the left and right operands pre-evaluated.
379
- * `evalOnDemand`, if it exists, will be called with the left and right operands
380
- * each individually wrapped in an object with an "eval" function that returns
381
- * a promise with the resulting value. This allows the binary expression to
382
- * evaluate the operands conditionally.
383
- * @param {{type: 'BinaryExpression', operator: <string>, left: {},
384
- * right: {}}} ast An expression tree with a BinaryExpression as the top
385
- * node
386
- * @returns {Promise<*>} resolves with the value of the BinaryExpression.
387
- * @private
388
- */
389
- exports.BinaryExpression = function(ast) {
390
- var _this = this;
391
- var grammarOp = this._grammar.elements[ast.operator];
392
- if (grammarOp.evalOnDemand) {
393
- var wrap = function wrap(subAst) {
394
- return { eval: function _eval() {
395
- return _this.eval(subAst);
396
- } };
397
- };
398
- return grammarOp.evalOnDemand(wrap(ast.left), wrap(ast.right));
399
- }
400
- return this.Promise.all([this.eval(ast.left), this.eval(ast.right)]).then(function(arr) {
401
- return grammarOp.eval(arr[0], arr[1]);
402
- });
403
- };
404
- /**
405
- * Evaluates a ConditionalExpression node by first evaluating its test branch,
406
- * and resolving with the consequent branch if the test is truthy, or the
407
- * alternate branch if it is not. If there is no consequent branch, the test
408
- * result will be used instead.
409
- * @param {{type: 'ConditionalExpression', test: {}, consequent: {},
410
- * alternate: {}}} ast An expression tree with a ConditionalExpression as
411
- * the top node
412
- * @private
413
- */
414
- exports.ConditionalExpression = function(ast) {
415
- var _this2 = this;
416
- return this.eval(ast.test).then(function(res) {
417
- if (res) {
418
- if (ast.consequent) return _this2.eval(ast.consequent);
419
- return res;
420
- }
421
- return _this2.eval(ast.alternate);
422
- });
423
- };
424
- /**
425
- * Evaluates a FilterExpression by applying it to the subject value.
426
- * @param {{type: 'FilterExpression', relative: <boolean>, expr: {},
427
- * subject: {}}} ast An expression tree with a FilterExpression as the top
428
- * node
429
- * @returns {Promise<*>} resolves with the value of the FilterExpression.
430
- * @private
431
- */
432
- exports.FilterExpression = function(ast) {
433
- var _this3 = this;
434
- return this.eval(ast.subject).then(function(subject) {
435
- if (ast.relative) return _this3._filterRelative(subject, ast.expr);
436
- return _this3._filterStatic(subject, ast.expr);
437
- });
438
- };
439
- /**
440
- * Evaluates an Identifier by either stemming from the evaluated 'from'
441
- * expression tree or accessing the context provided when this Evaluator was
442
- * constructed.
443
- * @param {{type: 'Identifier', value: <string>, [from]: {}}} ast An expression
444
- * tree with an Identifier as the top node
445
- * @returns {Promise<*>|*} either the identifier's value, or a Promise that
446
- * will resolve with the identifier's value.
447
- * @private
448
- */
449
- exports.Identifier = function(ast) {
450
- if (!ast.from) return ast.relative ? this._relContext[ast.value] : this._context[ast.value];
451
- return this.eval(ast.from).then(function(context) {
452
- if (context === void 0 || context === null) return;
453
- if (Array.isArray(context)) context = context[0];
454
- return context[ast.value];
455
- });
456
- };
457
- /**
458
- * Evaluates a Literal by returning its value property.
459
- * @param {{type: 'Literal', value: <string|number|boolean>}} ast An expression
460
- * tree with a Literal as its only node
461
- * @returns {string|number|boolean} The value of the Literal node
462
- * @private
463
- */
464
- exports.Literal = function(ast) {
465
- return ast.value;
466
- };
467
- /**
468
- * Evaluates an ObjectLiteral by returning its value, with each key
469
- * independently run through the evaluator.
470
- * @param {{type: 'ObjectLiteral', value: <{}>}} ast An expression tree with an
471
- * ObjectLiteral as the top node
472
- * @returns {Promise<{}>} resolves to a map contained evaluated values.
473
- * @private
474
- */
475
- exports.ObjectLiteral = function(ast) {
476
- return this.evalMap(ast.value);
477
- };
478
- /**
479
- * Evaluates a FunctionCall node by applying the supplied arguments to a
480
- * function defined in one of the grammar's function pools.
481
- * @param {{type: 'FunctionCall', name: <string>}} ast An
482
- * expression tree with a FunctionCall as the top node
483
- * @returns {Promise<*>|*} the value of the function call, or a Promise that
484
- * will resolve with the resulting value.
485
- * @private
486
- */
487
- exports.FunctionCall = function(ast) {
488
- var poolName = poolNames[ast.pool];
489
- if (!poolName) throw new Error("Corrupt AST: Pool '".concat(ast.pool, "' not found"));
490
- var func = this._grammar[ast.pool][ast.name];
491
- if (!func) throw new Error("".concat(poolName, " ").concat(ast.name, " is not defined."));
492
- return this.evalArray(ast.args || []).then(function(args) {
493
- return func.apply(void 0, (0, _toConsumableArray2.default)(args));
494
- });
495
- };
496
- /**
497
- * Evaluates a Unary expression by passing the right side through the
498
- * operator's eval function.
499
- * @param {{type: 'UnaryExpression', operator: <string>, right: {}}} ast An
500
- * expression tree with a UnaryExpression as the top node
501
- * @returns {Promise<*>} resolves with the value of the UnaryExpression.
502
- * @constructor
503
- */
504
- exports.UnaryExpression = function(ast) {
505
- var _this4 = this;
506
- return this.eval(ast.right).then(function(right) {
507
- return _this4._grammar.elements[ast.operator].eval(right);
508
- });
509
- };
510
- }));
511
-
512
- //#endregion
513
- //#region ../../node_modules/.pnpm/jexl@2.3.0/node_modules/jexl/dist/evaluator/Evaluator.js
514
- var require_Evaluator = /* @__PURE__ */ __commonJSMin(((exports, module) => {
515
- var _interopRequireDefault = require_interopRequireDefault();
516
- var _classCallCheck2 = _interopRequireDefault(require_classCallCheck());
517
- var _createClass2 = _interopRequireDefault(require_createClass());
518
- var handlers = require_handlers$1();
519
- /**
520
- * The Evaluator takes a Jexl expression tree as generated by the
521
- * {@link Parser} and calculates its value within a given context. The
522
- * collection of transforms, context, and a relative context to be used as the
523
- * root for relative identifiers, are all specific to an Evaluator instance.
524
- * When any of these things change, a new instance is required. However, a
525
- * single instance can be used to simultaneously evaluate many different
526
- * expressions, and does not have to be reinstantiated for each.
527
- * @param {{}} grammar A grammar object against which to evaluate the expression
528
- * tree
529
- * @param {{}} [context] A map of variable keys to their values. This will be
530
- * accessed to resolve the value of each non-relative identifier. Any
531
- * Promise values will be passed to the expression as their resolved
532
- * value.
533
- * @param {{}|Array<{}|Array>} [relativeContext] A map or array to be accessed
534
- * to resolve the value of a relative identifier.
535
- * @param {function} promise A constructor for the Promise class to be used;
536
- * probably either Promise or PromiseSync.
537
- */
538
- var Evaluator = /*#__PURE__*/ function() {
539
- function Evaluator(grammar, context, relativeContext) {
540
- var promise = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : Promise;
541
- (0, _classCallCheck2.default)(this, Evaluator);
542
- this._grammar = grammar;
543
- this._context = context || {};
544
- this._relContext = relativeContext || this._context;
545
- this.Promise = promise;
546
- }
547
- /**
548
- * Evaluates an expression tree within the configured context.
549
- * @param {{}} ast An expression tree object
550
- * @returns {Promise<*>} resolves with the resulting value of the expression.
551
- */
552
- (0, _createClass2.default)(Evaluator, [
553
- {
554
- key: "eval",
555
- value: function _eval(ast) {
556
- var _this = this;
557
- return this.Promise.resolve().then(function() {
558
- return handlers[ast.type].call(_this, ast);
559
- });
560
- }
561
- },
562
- {
563
- key: "evalArray",
564
- value: function evalArray(arr) {
565
- var _this2 = this;
566
- return this.Promise.all(arr.map(function(elem) {
567
- return _this2.eval(elem);
568
- }));
569
- }
570
- },
571
- {
572
- key: "evalMap",
573
- value: function evalMap(map) {
574
- var _this3 = this;
575
- var keys = Object.keys(map);
576
- var result = {};
577
- var asts = keys.map(function(key) {
578
- return _this3.eval(map[key]);
579
- });
580
- return this.Promise.all(asts).then(function(vals) {
581
- vals.forEach(function(val, idx) {
582
- result[keys[idx]] = val;
583
- });
584
- return result;
585
- });
586
- }
587
- },
588
- {
589
- key: "_filterRelative",
590
- value: function _filterRelative(subject, expr) {
591
- var _this4 = this;
592
- var promises = [];
593
- if (!Array.isArray(subject)) subject = subject === void 0 ? [] : [subject];
594
- subject.forEach(function(elem) {
595
- var evalInst = new Evaluator(_this4._grammar, _this4._context, elem, _this4.Promise);
596
- promises.push(evalInst.eval(expr));
597
- });
598
- return this.Promise.all(promises).then(function(values) {
599
- var results = [];
600
- values.forEach(function(value, idx) {
601
- if (value) results.push(subject[idx]);
602
- });
603
- return results;
604
- });
605
- }
606
- },
607
- {
608
- key: "_filterStatic",
609
- value: function _filterStatic(subject, expr) {
610
- return this.eval(expr).then(function(res) {
611
- if (typeof res === "boolean") return res ? subject : void 0;
612
- return subject[res];
613
- });
614
- }
615
- }
616
- ]);
617
- return Evaluator;
618
- }();
619
- module.exports = Evaluator;
620
- }));
621
-
622
- //#endregion
623
- //#region ../../node_modules/.pnpm/jexl@2.3.0/node_modules/jexl/dist/Lexer.js
624
- var require_Lexer = /* @__PURE__ */ __commonJSMin(((exports, module) => {
625
- var _interopRequireDefault = require_interopRequireDefault();
626
- var _classCallCheck2 = _interopRequireDefault(require_classCallCheck());
627
- var _createClass2 = _interopRequireDefault(require_createClass());
628
- var numericRegex = /^-?(?:(?:[0-9]*\.[0-9]+)|[0-9]+)$/;
629
- var identRegex = /^[a-zA-Zа-яА-Я_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF$][a-zA-Zа-яА-Я0-9_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF$]*$/;
630
- var escEscRegex = /\\\\/;
631
- var whitespaceRegex = /^\s*$/;
632
- var preOpRegexElems = [
633
- "'(?:(?:\\\\')|[^'])*'",
634
- "\"(?:(?:\\\\\")|[^\"])*\"",
635
- "\\s+",
636
- "\\btrue\\b",
637
- "\\bfalse\\b"
638
- ];
639
- var postOpRegexElems = ["[a-zA-Zа-яА-Я_À-ÖØ-öø-ÿ\\$][a-zA-Z0-9а-яА-Я_À-ÖØ-öø-ÿ\\$]*", "(?:(?:[0-9]*\\.[0-9]+)|[0-9]+)"];
640
- var minusNegatesAfter = [
641
- "binaryOp",
642
- "unaryOp",
643
- "openParen",
644
- "openBracket",
645
- "question",
646
- "colon"
647
- ];
648
- /**
649
- * Lexer is a collection of stateless, statically-accessed functions for the
650
- * lexical parsing of a Jexl string. Its responsibility is to identify the
651
- * "parts of speech" of a Jexl expression, and tokenize and label each, but
652
- * to do only the most minimal syntax checking; the only errors the Lexer
653
- * should be concerned with are if it's unable to identify the utility of
654
- * any of its tokens. Errors stemming from these tokens not being in a
655
- * sensible configuration should be left for the Parser to handle.
656
- * @type {{}}
657
- */
658
- var Lexer = /*#__PURE__*/ function() {
659
- function Lexer(grammar) {
660
- (0, _classCallCheck2.default)(this, Lexer);
661
- this._grammar = grammar;
662
- }
663
- /**
664
- * Splits a Jexl expression string into an array of expression elements.
665
- * @param {string} str A Jexl expression string
666
- * @returns {Array<string>} An array of substrings defining the functional
667
- * elements of the expression.
668
- */
669
- (0, _createClass2.default)(Lexer, [
670
- {
671
- key: "getElements",
672
- value: function getElements(str) {
673
- var regex = this._getSplitRegex();
674
- return str.split(regex).filter(function(elem) {
675
- return elem;
676
- });
677
- }
678
- },
679
- {
680
- key: "getTokens",
681
- value: function getTokens(elements) {
682
- var tokens = [];
683
- var negate = false;
684
- for (var i = 0; i < elements.length; i++) if (this._isWhitespace(elements[i])) {
685
- if (tokens.length) tokens[tokens.length - 1].raw += elements[i];
686
- } else if (elements[i] === "-" && this._isNegative(tokens)) negate = true;
687
- else {
688
- if (negate) {
689
- elements[i] = "-" + elements[i];
690
- negate = false;
691
- }
692
- tokens.push(this._createToken(elements[i]));
693
- }
694
- if (negate) tokens.push(this._createToken("-"));
695
- return tokens;
696
- }
697
- },
698
- {
699
- key: "tokenize",
700
- value: function tokenize(str) {
701
- var elements = this.getElements(str);
702
- return this.getTokens(elements);
703
- }
704
- },
705
- {
706
- key: "_createToken",
707
- value: function _createToken(element) {
708
- var token = {
709
- type: "literal",
710
- value: element,
711
- raw: element
712
- };
713
- if (element[0] === "\"" || element[0] === "'") token.value = this._unquote(element);
714
- else if (element.match(numericRegex)) token.value = parseFloat(element);
715
- else if (element === "true" || element === "false") token.value = element === "true";
716
- else if (this._grammar.elements[element]) token.type = this._grammar.elements[element].type;
717
- else if (element.match(identRegex)) token.type = "identifier";
718
- else throw new Error("Invalid expression token: ".concat(element));
719
- return token;
720
- }
721
- },
722
- {
723
- key: "_escapeRegExp",
724
- value: function _escapeRegExp(str) {
725
- str = str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
726
- if (str.match(identRegex)) str = "\\b" + str + "\\b";
727
- return str;
728
- }
729
- },
730
- {
731
- key: "_getSplitRegex",
732
- value: function _getSplitRegex() {
733
- var _this = this;
734
- if (!this._splitRegex) {
735
- var elemArray = Object.keys(this._grammar.elements).sort(function(a, b) {
736
- return b.length - a.length;
737
- }).map(function(elem) {
738
- return _this._escapeRegExp(elem);
739
- }, this);
740
- this._splitRegex = new RegExp("(" + [
741
- preOpRegexElems.join("|"),
742
- elemArray.join("|"),
743
- postOpRegexElems.join("|")
744
- ].join("|") + ")");
745
- }
746
- return this._splitRegex;
747
- }
748
- },
749
- {
750
- key: "_isNegative",
751
- value: function _isNegative(tokens) {
752
- if (!tokens.length) return true;
753
- return minusNegatesAfter.some(function(type) {
754
- return type === tokens[tokens.length - 1].type;
755
- });
756
- }
757
- },
758
- {
759
- key: "_isWhitespace",
760
- value: function _isWhitespace(str) {
761
- return !!str.match(whitespaceRegex);
762
- }
763
- },
764
- {
765
- key: "_unquote",
766
- value: function _unquote(str) {
767
- var quote = str[0];
768
- var escQuoteRegex = new RegExp("\\\\" + quote, "g");
769
- return str.substr(1, str.length - 2).replace(escQuoteRegex, quote).replace(escEscRegex, "\\");
770
- }
771
- }
772
- ]);
773
- return Lexer;
774
- }();
775
- module.exports = Lexer;
776
- }));
777
-
778
- //#endregion
779
- //#region ../../node_modules/.pnpm/jexl@2.3.0/node_modules/jexl/dist/parser/handlers.js
780
- var require_handlers = /* @__PURE__ */ __commonJSMin(((exports) => {
781
- /**
782
- * Handles a subexpression that's used to define a transform argument's value.
783
- * @param {{type: <string>}} ast The subexpression tree
784
- */
785
- exports.argVal = function(ast) {
786
- if (ast) this._cursor.args.push(ast);
787
- };
788
- /**
789
- * Handles new array literals by adding them as a new node in the AST,
790
- * initialized with an empty array.
791
- */
792
- exports.arrayStart = function() {
793
- this._placeAtCursor({
794
- type: "ArrayLiteral",
795
- value: []
796
- });
797
- };
798
- /**
799
- * Handles a subexpression representing an element of an array literal.
800
- * @param {{type: <string>}} ast The subexpression tree
801
- */
802
- exports.arrayVal = function(ast) {
803
- if (ast) this._cursor.value.push(ast);
804
- };
805
- /**
806
- * Handles tokens of type 'binaryOp', indicating an operation that has two
807
- * inputs: a left side and a right side.
808
- * @param {{type: <string>}} token A token object
809
- */
810
- exports.binaryOp = function(token) {
811
- var precedence = this._grammar.elements[token.value].precedence || 0;
812
- var parent = this._cursor._parent;
813
- while (parent && parent.operator && this._grammar.elements[parent.operator].precedence >= precedence) {
814
- this._cursor = parent;
815
- parent = parent._parent;
816
- }
817
- var node = {
818
- type: "BinaryExpression",
819
- operator: token.value,
820
- left: this._cursor
821
- };
822
- this._setParent(this._cursor, node);
823
- this._cursor = parent;
824
- this._placeAtCursor(node);
825
- };
826
- /**
827
- * Handles successive nodes in an identifier chain. More specifically, it
828
- * sets values that determine how the following identifier gets placed in the
829
- * AST.
830
- */
831
- exports.dot = function() {
832
- this._nextIdentEncapsulate = this._cursor && this._cursor.type !== "UnaryExpression" && (this._cursor.type !== "BinaryExpression" || this._cursor.type === "BinaryExpression" && this._cursor.right);
833
- this._nextIdentRelative = !this._cursor || this._cursor && !this._nextIdentEncapsulate;
834
- if (this._nextIdentRelative) this._relative = true;
835
- };
836
- /**
837
- * Handles a subexpression used for filtering an array returned by an
838
- * identifier chain.
839
- * @param {{type: <string>}} ast The subexpression tree
840
- */
841
- exports.filter = function(ast) {
842
- this._placeBeforeCursor({
843
- type: "FilterExpression",
844
- expr: ast,
845
- relative: this._subParser.isRelative(),
846
- subject: this._cursor
847
- });
848
- };
849
- /**
850
- * Handles identifier tokens when used to indicate the name of a function to
851
- * be called.
852
- * @param {{type: <string>}} token A token object
853
- */
854
- exports.functionCall = function() {
855
- this._placeBeforeCursor({
856
- type: "FunctionCall",
857
- name: this._cursor.value,
858
- args: [],
859
- pool: "functions"
860
- });
861
- };
862
- /**
863
- * Handles identifier tokens by adding them as a new node in the AST.
864
- * @param {{type: <string>}} token A token object
865
- */
866
- exports.identifier = function(token) {
867
- var node = {
868
- type: "Identifier",
869
- value: token.value
870
- };
871
- if (this._nextIdentEncapsulate) {
872
- node.from = this._cursor;
873
- this._placeBeforeCursor(node);
874
- this._nextIdentEncapsulate = false;
875
- } else {
876
- if (this._nextIdentRelative) {
877
- node.relative = true;
878
- this._nextIdentRelative = false;
879
- }
880
- this._placeAtCursor(node);
881
- }
882
- };
883
- /**
884
- * Handles literal values, such as strings, booleans, and numerics, by adding
885
- * them as a new node in the AST.
886
- * @param {{type: <string>}} token A token object
887
- */
888
- exports.literal = function(token) {
889
- this._placeAtCursor({
890
- type: "Literal",
891
- value: token.value
892
- });
893
- };
894
- /**
895
- * Queues a new object literal key to be written once a value is collected.
896
- * @param {{type: <string>}} token A token object
897
- */
898
- exports.objKey = function(token) {
899
- this._curObjKey = token.value;
900
- };
901
- /**
902
- * Handles new object literals by adding them as a new node in the AST,
903
- * initialized with an empty object.
904
- */
905
- exports.objStart = function() {
906
- this._placeAtCursor({
907
- type: "ObjectLiteral",
908
- value: {}
909
- });
910
- };
911
- /**
912
- * Handles an object value by adding its AST to the queued key on the object
913
- * literal node currently at the cursor.
914
- * @param {{type: <string>}} ast The subexpression tree
915
- */
916
- exports.objVal = function(ast) {
917
- this._cursor.value[this._curObjKey] = ast;
918
- };
919
- /**
920
- * Handles traditional subexpressions, delineated with the groupStart and
921
- * groupEnd elements.
922
- * @param {{type: <string>}} ast The subexpression tree
923
- */
924
- exports.subExpression = function(ast) {
925
- this._placeAtCursor(ast);
926
- };
927
- /**
928
- * Handles a completed alternate subexpression of a ternary operator.
929
- * @param {{type: <string>}} ast The subexpression tree
930
- */
931
- exports.ternaryEnd = function(ast) {
932
- this._cursor.alternate = ast;
933
- };
934
- /**
935
- * Handles a completed consequent subexpression of a ternary operator.
936
- * @param {{type: <string>}} ast The subexpression tree
937
- */
938
- exports.ternaryMid = function(ast) {
939
- this._cursor.consequent = ast;
940
- };
941
- /**
942
- * Handles the start of a new ternary expression by encapsulating the entire
943
- * AST in a ConditionalExpression node, and using the existing tree as the
944
- * test element.
945
- */
946
- exports.ternaryStart = function() {
947
- this._tree = {
948
- type: "ConditionalExpression",
949
- test: this._tree
950
- };
951
- this._cursor = this._tree;
952
- };
953
- /**
954
- * Handles identifier tokens when used to indicate the name of a transform to
955
- * be applied.
956
- * @param {{type: <string>}} token A token object
957
- */
958
- exports.transform = function(token) {
959
- this._placeBeforeCursor({
960
- type: "FunctionCall",
961
- name: token.value,
962
- args: [this._cursor],
963
- pool: "transforms"
964
- });
965
- };
966
- /**
967
- * Handles token of type 'unaryOp', indicating that the operation has only
968
- * one input: a right side.
969
- * @param {{type: <string>}} token A token object
970
- */
971
- exports.unaryOp = function(token) {
972
- this._placeAtCursor({
973
- type: "UnaryExpression",
974
- operator: token.value
975
- });
976
- };
977
- }));
978
-
979
- //#endregion
980
- //#region ../../node_modules/.pnpm/jexl@2.3.0/node_modules/jexl/dist/parser/states.js
981
- var require_states = /* @__PURE__ */ __commonJSMin(((exports) => {
982
- var h = require_handlers();
983
- /**
984
- * A mapping of all states in the finite state machine to a set of instructions
985
- * for handling or transitioning into other states. Each state can be handled
986
- * in one of two schemes: a tokenType map, or a subHandler.
987
- *
988
- * Standard expression elements are handled through the tokenType object. This
989
- * is an object map of all legal token types to encounter in this state (and
990
- * any unexpected token types will generate a thrown error) to an options
991
- * object that defines how they're handled. The available options are:
992
- *
993
- * {string} toState: The name of the state to which to transition
994
- * immediately after handling this token
995
- * {string} handler: The handler function to call when this token type is
996
- * encountered in this state. If omitted, the default handler
997
- * matching the token's "type" property will be called. If the handler
998
- * function does not exist, no call will be made and no error will be
999
- * generated. This is useful for tokens whose sole purpose is to
1000
- * transition to other states.
1001
- *
1002
- * States that consume a subexpression should define a subHandler, the
1003
- * function to be called with an expression tree argument when the
1004
- * subexpression is complete. Completeness is determined through the
1005
- * endStates object, which maps tokens on which an expression should end to the
1006
- * state to which to transition once the subHandler function has been called.
1007
- *
1008
- * Additionally, any state in which it is legal to mark the AST as completed
1009
- * should have a 'completable' property set to boolean true. Attempting to
1010
- * call {@link Parser#complete} in any state without this property will result
1011
- * in a thrown Error.
1012
- *
1013
- * @type {{}}
1014
- */
1015
- exports.states = {
1016
- expectOperand: { tokenTypes: {
1017
- literal: { toState: "expectBinOp" },
1018
- identifier: { toState: "identifier" },
1019
- unaryOp: {},
1020
- openParen: { toState: "subExpression" },
1021
- openCurl: {
1022
- toState: "expectObjKey",
1023
- handler: h.objStart
1024
- },
1025
- dot: { toState: "traverse" },
1026
- openBracket: {
1027
- toState: "arrayVal",
1028
- handler: h.arrayStart
1029
- }
1030
- } },
1031
- expectBinOp: {
1032
- tokenTypes: {
1033
- binaryOp: { toState: "expectOperand" },
1034
- pipe: { toState: "expectTransform" },
1035
- dot: { toState: "traverse" },
1036
- question: {
1037
- toState: "ternaryMid",
1038
- handler: h.ternaryStart
1039
- }
1040
- },
1041
- completable: true
1042
- },
1043
- expectTransform: { tokenTypes: { identifier: {
1044
- toState: "postTransform",
1045
- handler: h.transform
1046
- } } },
1047
- expectObjKey: { tokenTypes: {
1048
- identifier: {
1049
- toState: "expectKeyValSep",
1050
- handler: h.objKey
1051
- },
1052
- closeCurl: { toState: "expectBinOp" }
1053
- } },
1054
- expectKeyValSep: { tokenTypes: { colon: { toState: "objVal" } } },
1055
- postTransform: {
1056
- tokenTypes: {
1057
- openParen: { toState: "argVal" },
1058
- binaryOp: { toState: "expectOperand" },
1059
- dot: { toState: "traverse" },
1060
- openBracket: { toState: "filter" },
1061
- pipe: { toState: "expectTransform" }
1062
- },
1063
- completable: true
1064
- },
1065
- postArgs: {
1066
- tokenTypes: {
1067
- binaryOp: { toState: "expectOperand" },
1068
- dot: { toState: "traverse" },
1069
- openBracket: { toState: "filter" },
1070
- pipe: { toState: "expectTransform" }
1071
- },
1072
- completable: true
1073
- },
1074
- identifier: {
1075
- tokenTypes: {
1076
- binaryOp: { toState: "expectOperand" },
1077
- dot: { toState: "traverse" },
1078
- openBracket: { toState: "filter" },
1079
- openParen: {
1080
- toState: "argVal",
1081
- handler: h.functionCall
1082
- },
1083
- pipe: { toState: "expectTransform" },
1084
- question: {
1085
- toState: "ternaryMid",
1086
- handler: h.ternaryStart
1087
- }
1088
- },
1089
- completable: true
1090
- },
1091
- traverse: { tokenTypes: { identifier: { toState: "identifier" } } },
1092
- filter: {
1093
- subHandler: h.filter,
1094
- endStates: { closeBracket: "identifier" }
1095
- },
1096
- subExpression: {
1097
- subHandler: h.subExpression,
1098
- endStates: { closeParen: "expectBinOp" }
1099
- },
1100
- argVal: {
1101
- subHandler: h.argVal,
1102
- endStates: {
1103
- comma: "argVal",
1104
- closeParen: "postArgs"
1105
- }
1106
- },
1107
- objVal: {
1108
- subHandler: h.objVal,
1109
- endStates: {
1110
- comma: "expectObjKey",
1111
- closeCurl: "expectBinOp"
1112
- }
1113
- },
1114
- arrayVal: {
1115
- subHandler: h.arrayVal,
1116
- endStates: {
1117
- comma: "arrayVal",
1118
- closeBracket: "expectBinOp"
1119
- }
1120
- },
1121
- ternaryMid: {
1122
- subHandler: h.ternaryMid,
1123
- endStates: { colon: "ternaryEnd" }
1124
- },
1125
- ternaryEnd: {
1126
- subHandler: h.ternaryEnd,
1127
- completable: true
1128
- }
1129
- };
1130
- }));
1131
-
1132
- //#endregion
1133
- //#region ../../node_modules/.pnpm/jexl@2.3.0/node_modules/jexl/dist/parser/Parser.js
1134
- var require_Parser = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1135
- var _interopRequireDefault = require_interopRequireDefault();
1136
- var _classCallCheck2 = _interopRequireDefault(require_classCallCheck());
1137
- var _createClass2 = _interopRequireDefault(require_createClass());
1138
- var handlers = require_handlers();
1139
- var states = require_states().states;
1140
- /**
1141
- * The Parser is a state machine that converts tokens from the {@link Lexer}
1142
- * into an Abstract Syntax Tree (AST), capable of being evaluated in any
1143
- * context by the {@link Evaluator}. The Parser expects that all tokens
1144
- * provided to it are legal and typed properly according to the grammar, but
1145
- * accepts that the tokens may still be in an invalid order or in some other
1146
- * unparsable configuration that requires it to throw an Error.
1147
- * @param {{}} grammar The grammar object to use to parse Jexl strings
1148
- * @param {string} [prefix] A string prefix to prepend to the expression string
1149
- * for error messaging purposes. This is useful for when a new Parser is
1150
- * instantiated to parse an subexpression, as the parent Parser's
1151
- * expression string thus far can be passed for a more user-friendly
1152
- * error message.
1153
- * @param {{}} [stopMap] A mapping of token types to any truthy value. When the
1154
- * token type is encountered, the parser will return the mapped value
1155
- * instead of boolean false.
1156
- */
1157
- var Parser = /*#__PURE__*/ function() {
1158
- function Parser(grammar, prefix, stopMap) {
1159
- (0, _classCallCheck2.default)(this, Parser);
1160
- this._grammar = grammar;
1161
- this._state = "expectOperand";
1162
- this._tree = null;
1163
- this._exprStr = prefix || "";
1164
- this._relative = false;
1165
- this._stopMap = stopMap || {};
1166
- }
1167
- /**
1168
- * Processes a new token into the AST and manages the transitions of the state
1169
- * machine.
1170
- * @param {{type: <string>}} token A token object, as provided by the
1171
- * {@link Lexer#tokenize} function.
1172
- * @throws {Error} if a token is added when the Parser has been marked as
1173
- * complete by {@link #complete}, or if an unexpected token type is added.
1174
- * @returns {boolean|*} the stopState value if this parser encountered a token
1175
- * in the stopState mapb false if tokens can continue.
1176
- */
1177
- (0, _createClass2.default)(Parser, [
1178
- {
1179
- key: "addToken",
1180
- value: function addToken(token) {
1181
- if (this._state === "complete") throw new Error("Cannot add a new token to a completed Parser");
1182
- var state = states[this._state];
1183
- var startExpr = this._exprStr;
1184
- this._exprStr += token.raw;
1185
- if (state.subHandler) {
1186
- if (!this._subParser) this._startSubExpression(startExpr);
1187
- var stopState = this._subParser.addToken(token);
1188
- if (stopState) {
1189
- this._endSubExpression();
1190
- if (this._parentStop) return stopState;
1191
- this._state = stopState;
1192
- }
1193
- } else if (state.tokenTypes[token.type]) {
1194
- var typeOpts = state.tokenTypes[token.type];
1195
- var handleFunc = handlers[token.type];
1196
- if (typeOpts.handler) handleFunc = typeOpts.handler;
1197
- if (handleFunc) handleFunc.call(this, token);
1198
- if (typeOpts.toState) this._state = typeOpts.toState;
1199
- } else if (this._stopMap[token.type]) return this._stopMap[token.type];
1200
- else throw new Error("Token ".concat(token.raw, " (").concat(token.type, ") unexpected in expression: ").concat(this._exprStr));
1201
- return false;
1202
- }
1203
- },
1204
- {
1205
- key: "addTokens",
1206
- value: function addTokens(tokens) {
1207
- tokens.forEach(this.addToken, this);
1208
- }
1209
- },
1210
- {
1211
- key: "complete",
1212
- value: function complete() {
1213
- if (this._cursor && !states[this._state].completable) throw new Error("Unexpected end of expression: ".concat(this._exprStr));
1214
- if (this._subParser) this._endSubExpression();
1215
- this._state = "complete";
1216
- return this._cursor ? this._tree : null;
1217
- }
1218
- },
1219
- {
1220
- key: "isRelative",
1221
- value: function isRelative() {
1222
- return this._relative;
1223
- }
1224
- },
1225
- {
1226
- key: "_endSubExpression",
1227
- value: function _endSubExpression() {
1228
- states[this._state].subHandler.call(this, this._subParser.complete());
1229
- this._subParser = null;
1230
- }
1231
- },
1232
- {
1233
- key: "_placeAtCursor",
1234
- value: function _placeAtCursor(node) {
1235
- if (!this._cursor) this._tree = node;
1236
- else {
1237
- this._cursor.right = node;
1238
- this._setParent(node, this._cursor);
1239
- }
1240
- this._cursor = node;
1241
- }
1242
- },
1243
- {
1244
- key: "_placeBeforeCursor",
1245
- value: function _placeBeforeCursor(node) {
1246
- this._cursor = this._cursor._parent;
1247
- this._placeAtCursor(node);
1248
- }
1249
- },
1250
- {
1251
- key: "_setParent",
1252
- value: function _setParent(node, parent) {
1253
- Object.defineProperty(node, "_parent", {
1254
- value: parent,
1255
- writable: true
1256
- });
1257
- }
1258
- },
1259
- {
1260
- key: "_startSubExpression",
1261
- value: function _startSubExpression(exprStr) {
1262
- var endStates = states[this._state].endStates;
1263
- if (!endStates) {
1264
- this._parentStop = true;
1265
- endStates = this._stopMap;
1266
- }
1267
- this._subParser = new Parser(this._grammar, exprStr, endStates);
1268
- }
1269
- }
1270
- ]);
1271
- return Parser;
1272
- }();
1273
- module.exports = Parser;
1274
- }));
1275
-
1276
- //#endregion
1277
- //#region ../../node_modules/.pnpm/jexl@2.3.0/node_modules/jexl/dist/PromiseSync.js
1278
- var require_PromiseSync = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1279
- var _interopRequireDefault = require_interopRequireDefault();
1280
- var _classCallCheck2 = _interopRequireDefault(require_classCallCheck());
1281
- var _createClass2 = _interopRequireDefault(require_createClass());
1282
- var PromiseSync = /*#__PURE__*/ function() {
1283
- function PromiseSync(fn) {
1284
- (0, _classCallCheck2.default)(this, PromiseSync);
1285
- fn(this._resolve.bind(this), this._reject.bind(this));
1286
- }
1287
- (0, _createClass2.default)(PromiseSync, [
1288
- {
1289
- key: "catch",
1290
- value: function _catch(rejected) {
1291
- if (this.error) try {
1292
- this._resolve(rejected(this.error));
1293
- } catch (e) {
1294
- this._reject(e);
1295
- }
1296
- return this;
1297
- }
1298
- },
1299
- {
1300
- key: "then",
1301
- value: function then(resolved, rejected) {
1302
- if (!this.error) try {
1303
- this._resolve(resolved(this.value));
1304
- } catch (e) {
1305
- this._reject(e);
1306
- }
1307
- if (rejected) this.catch(rejected);
1308
- return this;
1309
- }
1310
- },
1311
- {
1312
- key: "_reject",
1313
- value: function _reject(error) {
1314
- this.value = void 0;
1315
- this.error = error;
1316
- }
1317
- },
1318
- {
1319
- key: "_resolve",
1320
- value: function _resolve(val) {
1321
- if (val instanceof PromiseSync) {
1322
- if (val.error) this._reject(val.error);
1323
- else this._resolve(val.value);
1324
- } else {
1325
- this.value = val;
1326
- this.error = void 0;
1327
- }
1328
- }
1329
- }
1330
- ]);
1331
- return PromiseSync;
1332
- }();
1333
- PromiseSync.all = function(vals) {
1334
- return new PromiseSync(function(resolve) {
1335
- resolve(vals.map(function(val) {
1336
- while (val instanceof PromiseSync) {
1337
- if (val.error) throw Error(val.error);
1338
- val = val.value;
1339
- }
1340
- return val;
1341
- }));
1342
- });
1343
- };
1344
- PromiseSync.resolve = function(val) {
1345
- return new PromiseSync(function(resolve) {
1346
- return resolve(val);
1347
- });
1348
- };
1349
- PromiseSync.reject = function(error) {
1350
- return new PromiseSync(function(resolve, reject) {
1351
- return reject(error);
1352
- });
1353
- };
1354
- module.exports = PromiseSync;
1355
- }));
1356
-
1357
- //#endregion
1358
- //#region ../../node_modules/.pnpm/jexl@2.3.0/node_modules/jexl/dist/Expression.js
1359
- var require_Expression = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1360
- var _interopRequireDefault = require_interopRequireDefault();
1361
- var _classCallCheck2 = _interopRequireDefault(require_classCallCheck());
1362
- var _createClass2 = _interopRequireDefault(require_createClass());
1363
- var Evaluator = require_Evaluator();
1364
- var Lexer = require_Lexer();
1365
- var Parser = require_Parser();
1366
- var PromiseSync = require_PromiseSync();
1367
- var Expression = /*#__PURE__*/ function() {
1368
- function Expression(grammar, exprStr) {
1369
- (0, _classCallCheck2.default)(this, Expression);
1370
- this._grammar = grammar;
1371
- this._exprStr = exprStr;
1372
- this._ast = null;
1373
- }
1374
- /**
1375
- * Forces a compilation of the expression string that this Expression object
1376
- * was constructed with. This function can be called multiple times; useful
1377
- * if the language elements of the associated Jexl instance change.
1378
- * @returns {Expression} this Expression instance, for convenience
1379
- */
1380
- (0, _createClass2.default)(Expression, [
1381
- {
1382
- key: "compile",
1383
- value: function compile() {
1384
- var lexer = new Lexer(this._grammar);
1385
- var parser = new Parser(this._grammar);
1386
- var tokens = lexer.tokenize(this._exprStr);
1387
- parser.addTokens(tokens);
1388
- this._ast = parser.complete();
1389
- return this;
1390
- }
1391
- },
1392
- {
1393
- key: "eval",
1394
- value: function _eval() {
1395
- var context = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
1396
- return this._eval(context, Promise);
1397
- }
1398
- },
1399
- {
1400
- key: "evalSync",
1401
- value: function evalSync() {
1402
- var context = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
1403
- var res = this._eval(context, PromiseSync);
1404
- if (res.error) throw res.error;
1405
- return res.value;
1406
- }
1407
- },
1408
- {
1409
- key: "_eval",
1410
- value: function _eval(context, promise) {
1411
- var _this = this;
1412
- return promise.resolve().then(function() {
1413
- var ast = _this._getAst();
1414
- return new Evaluator(_this._grammar, context, void 0, promise).eval(ast);
1415
- });
1416
- }
1417
- },
1418
- {
1419
- key: "_getAst",
1420
- value: function _getAst() {
1421
- if (!this._ast) this.compile();
1422
- return this._ast;
1423
- }
1424
- }
1425
- ]);
1426
- return Expression;
1427
- }();
1428
- module.exports = Expression;
1429
- }));
1430
-
1431
- //#endregion
1432
- //#region ../../node_modules/.pnpm/jexl@2.3.0/node_modules/jexl/dist/grammar.js
1433
- var require_grammar = /* @__PURE__ */ __commonJSMin(((exports) => {
1434
- exports.getGrammar = function() {
1435
- return {
1436
- /**
1437
- * A map of all expression elements to their properties. Note that changes
1438
- * here may require changes in the Lexer or Parser.
1439
- * @type {{}}
1440
- */
1441
- elements: {
1442
- ".": { type: "dot" },
1443
- "[": { type: "openBracket" },
1444
- "]": { type: "closeBracket" },
1445
- "|": { type: "pipe" },
1446
- "{": { type: "openCurl" },
1447
- "}": { type: "closeCurl" },
1448
- ":": { type: "colon" },
1449
- ",": { type: "comma" },
1450
- "(": { type: "openParen" },
1451
- ")": { type: "closeParen" },
1452
- "?": { type: "question" },
1453
- "+": {
1454
- type: "binaryOp",
1455
- precedence: 30,
1456
- eval: function _eval(left, right) {
1457
- return left + right;
1458
- }
1459
- },
1460
- "-": {
1461
- type: "binaryOp",
1462
- precedence: 30,
1463
- eval: function _eval(left, right) {
1464
- return left - right;
1465
- }
1466
- },
1467
- "*": {
1468
- type: "binaryOp",
1469
- precedence: 40,
1470
- eval: function _eval(left, right) {
1471
- return left * right;
1472
- }
1473
- },
1474
- "/": {
1475
- type: "binaryOp",
1476
- precedence: 40,
1477
- eval: function _eval(left, right) {
1478
- return left / right;
1479
- }
1480
- },
1481
- "//": {
1482
- type: "binaryOp",
1483
- precedence: 40,
1484
- eval: function _eval(left, right) {
1485
- return Math.floor(left / right);
1486
- }
1487
- },
1488
- "%": {
1489
- type: "binaryOp",
1490
- precedence: 50,
1491
- eval: function _eval(left, right) {
1492
- return left % right;
1493
- }
1494
- },
1495
- "^": {
1496
- type: "binaryOp",
1497
- precedence: 50,
1498
- eval: function _eval(left, right) {
1499
- return Math.pow(left, right);
1500
- }
1501
- },
1502
- "==": {
1503
- type: "binaryOp",
1504
- precedence: 20,
1505
- eval: function _eval(left, right) {
1506
- return left == right;
1507
- }
1508
- },
1509
- "!=": {
1510
- type: "binaryOp",
1511
- precedence: 20,
1512
- eval: function _eval(left, right) {
1513
- return left != right;
1514
- }
1515
- },
1516
- ">": {
1517
- type: "binaryOp",
1518
- precedence: 20,
1519
- eval: function _eval(left, right) {
1520
- return left > right;
1521
- }
1522
- },
1523
- ">=": {
1524
- type: "binaryOp",
1525
- precedence: 20,
1526
- eval: function _eval(left, right) {
1527
- return left >= right;
1528
- }
1529
- },
1530
- "<": {
1531
- type: "binaryOp",
1532
- precedence: 20,
1533
- eval: function _eval(left, right) {
1534
- return left < right;
1535
- }
1536
- },
1537
- "<=": {
1538
- type: "binaryOp",
1539
- precedence: 20,
1540
- eval: function _eval(left, right) {
1541
- return left <= right;
1542
- }
1543
- },
1544
- "&&": {
1545
- type: "binaryOp",
1546
- precedence: 10,
1547
- evalOnDemand: function evalOnDemand(left, right) {
1548
- return left.eval().then(function(leftVal) {
1549
- if (!leftVal) return leftVal;
1550
- return right.eval();
1551
- });
1552
- }
1553
- },
1554
- "||": {
1555
- type: "binaryOp",
1556
- precedence: 10,
1557
- evalOnDemand: function evalOnDemand(left, right) {
1558
- return left.eval().then(function(leftVal) {
1559
- if (leftVal) return leftVal;
1560
- return right.eval();
1561
- });
1562
- }
1563
- },
1564
- in: {
1565
- type: "binaryOp",
1566
- precedence: 20,
1567
- eval: function _eval(left, right) {
1568
- if (typeof right === "string") return right.indexOf(left) !== -1;
1569
- if (Array.isArray(right)) return right.some(function(elem) {
1570
- return elem === left;
1571
- });
1572
- return false;
1573
- }
1574
- },
1575
- "!": {
1576
- type: "unaryOp",
1577
- precedence: Infinity,
1578
- eval: function _eval(right) {
1579
- return !right;
1580
- }
1581
- }
1582
- },
1583
- /**
1584
- * A map of function names to javascript functions. A Jexl function
1585
- * takes zero ore more arguemnts:
1586
- *
1587
- * - {*} ...args: A variable number of arguments passed to this function.
1588
- * All of these are pre-evaluated to their actual values before calling
1589
- * the function.
1590
- *
1591
- * The Jexl function should return either the transformed value, or
1592
- * a Promises/A+ Promise object that resolves with the value and rejects
1593
- * or throws only when an unrecoverable error occurs. Functions should
1594
- * generally return undefined when they don't make sense to be used on the
1595
- * given value type, rather than throw/reject. An error is only
1596
- * appropriate when the function would normally return a value, but
1597
- * cannot due to some other failure.
1598
- */
1599
- functions: {},
1600
- /**
1601
- * A map of transform names to transform functions. A transform function
1602
- * takes one ore more arguemnts:
1603
- *
1604
- * - {*} val: A value to be transformed
1605
- * - {*} ...args: A variable number of arguments passed to this transform.
1606
- * All of these are pre-evaluated to their actual values before calling
1607
- * the function.
1608
- *
1609
- * The transform function should return either the transformed value, or
1610
- * a Promises/A+ Promise object that resolves with the value and rejects
1611
- * or throws only when an unrecoverable error occurs. Transforms should
1612
- * generally return undefined when they don't make sense to be used on the
1613
- * given value type, rather than throw/reject. An error is only
1614
- * appropriate when the transform would normally return a value, but
1615
- * cannot due to some other failure.
1616
- */
1617
- transforms: {}
1618
- };
1619
- };
1620
- }));
1621
-
1622
- //#endregion
1623
- //#region ../../node_modules/.pnpm/jexl@2.3.0/node_modules/jexl/dist/Jexl.js
1624
- var require_Jexl = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1625
- var _interopRequireDefault = require_interopRequireDefault();
1626
- var _defineProperty2 = _interopRequireDefault(require_defineProperty());
1627
- var _classCallCheck2 = _interopRequireDefault(require_classCallCheck());
1628
- var _createClass2 = _interopRequireDefault(require_createClass());
1629
- var Expression = require_Expression();
1630
- var getGrammar = require_grammar().getGrammar;
1631
- /**
1632
- * Jexl is the Javascript Expression Language, capable of parsing and
1633
- * evaluating basic to complex expression strings, combined with advanced
1634
- * xpath-like drilldown into native Javascript objects.
1635
- * @constructor
1636
- */
1637
- var Jexl = /*#__PURE__*/ function() {
1638
- function Jexl() {
1639
- (0, _classCallCheck2.default)(this, Jexl);
1640
- this.expr = this.expr.bind(this);
1641
- this._grammar = getGrammar();
1642
- }
1643
- /**
1644
- * Adds a binary operator to Jexl at the specified precedence. The higher the
1645
- * precedence, the earlier the operator is applied in the order of operations.
1646
- * For example, * has a higher precedence than +, because multiplication comes
1647
- * before division.
1648
- *
1649
- * Please see grammar.js for a listing of all default operators and their
1650
- * precedence values in order to choose the appropriate precedence for the
1651
- * new operator.
1652
- * @param {string} operator The operator string to be added
1653
- * @param {number} precedence The operator's precedence
1654
- * @param {function} fn A function to run to calculate the result. The function
1655
- * will be called with two arguments: left and right, denoting the values
1656
- * on either side of the operator. It should return either the resulting
1657
- * value, or a Promise that resolves with the resulting value.
1658
- * @param {boolean} [manualEval] If true, the `left` and `right` arguments
1659
- * will be wrapped in objects with an `eval` function. Calling
1660
- * left.eval() or right.eval() will return a promise that resolves to
1661
- * that operand's actual value. This is useful to conditionally evaluate
1662
- * operands.
1663
- */
1664
- (0, _createClass2.default)(Jexl, [
1665
- {
1666
- key: "addBinaryOp",
1667
- value: function addBinaryOp(operator, precedence, fn, manualEval) {
1668
- this._addGrammarElement(operator, (0, _defineProperty2.default)({
1669
- type: "binaryOp",
1670
- precedence
1671
- }, manualEval ? "evalOnDemand" : "eval", fn));
1672
- }
1673
- },
1674
- {
1675
- key: "addFunction",
1676
- value: function addFunction(name, fn) {
1677
- this._grammar.functions[name] = fn;
1678
- }
1679
- },
1680
- {
1681
- key: "addFunctions",
1682
- value: function addFunctions(map) {
1683
- for (var key in map) this._grammar.functions[key] = map[key];
1684
- }
1685
- },
1686
- {
1687
- key: "addUnaryOp",
1688
- value: function addUnaryOp(operator, fn) {
1689
- this._addGrammarElement(operator, {
1690
- type: "unaryOp",
1691
- weight: Infinity,
1692
- eval: fn
1693
- });
1694
- }
1695
- },
1696
- {
1697
- key: "addTransform",
1698
- value: function addTransform(name, fn) {
1699
- this._grammar.transforms[name] = fn;
1700
- }
1701
- },
1702
- {
1703
- key: "addTransforms",
1704
- value: function addTransforms(map) {
1705
- for (var key in map) this._grammar.transforms[key] = map[key];
1706
- }
1707
- },
1708
- {
1709
- key: "compile",
1710
- value: function compile(expression) {
1711
- return this.createExpression(expression).compile();
1712
- }
1713
- },
1714
- {
1715
- key: "createExpression",
1716
- value: function createExpression(expression) {
1717
- return new Expression(this._grammar, expression);
1718
- }
1719
- },
1720
- {
1721
- key: "getFunction",
1722
- value: function getFunction(name) {
1723
- return this._grammar.functions[name];
1724
- }
1725
- },
1726
- {
1727
- key: "getTransform",
1728
- value: function getTransform(name) {
1729
- return this._grammar.transforms[name];
1730
- }
1731
- },
1732
- {
1733
- key: "eval",
1734
- value: function _eval(expression) {
1735
- var context = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
1736
- return this.createExpression(expression).eval(context);
1737
- }
1738
- },
1739
- {
1740
- key: "evalSync",
1741
- value: function evalSync(expression) {
1742
- var context = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
1743
- return this.createExpression(expression).evalSync(context);
1744
- }
1745
- },
1746
- {
1747
- key: "expr",
1748
- value: function expr(strs) {
1749
- for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) args[_key - 1] = arguments[_key];
1750
- var exprStr = strs.reduce(function(acc, str, idx) {
1751
- var arg = idx < args.length ? args[idx] : "";
1752
- acc += str + arg;
1753
- return acc;
1754
- }, "");
1755
- return this.createExpression(exprStr);
1756
- }
1757
- },
1758
- {
1759
- key: "removeOp",
1760
- value: function removeOp(operator) {
1761
- if (this._grammar.elements[operator] && (this._grammar.elements[operator].type === "binaryOp" || this._grammar.elements[operator].type === "unaryOp")) delete this._grammar.elements[operator];
1762
- }
1763
- },
1764
- {
1765
- key: "_addGrammarElement",
1766
- value: function _addGrammarElement(str, obj) {
1767
- this._grammar.elements[str] = obj;
1768
- }
1769
- }
1770
- ]);
1771
- return Jexl;
1772
- }();
1773
- module.exports = new Jexl();
1774
- module.exports.Jexl = Jexl;
1775
- }));
1776
-
1777
- //#endregion
1778
- //#region src/export/expression.ts
1779
- var import_Jexl = /* @__PURE__ */ __toESM(require_Jexl(), 1);
1780
- /** jexl ships a UMD bundle whose `module.exports` is the ready-made instance. */
1781
- const jexl = import_Jexl.default?.default ?? import_Jexl.default;
1782
- /** Handlebars sub-expressions/blocks — never wrap these in `{{esc}}`. */
1783
- const NON_VALUE_MUSTACHE = /^[#/!>^&]|^\s*else\b/;
1784
- /**
1785
- * Evaluate one Jexl expression.
1786
- *
1787
- * Jexl is used instead of `eval()` so a template can never reach globals, the
1788
- * DOM, or `fetch` — the worst a malicious template can do is compute a wrong
1789
- * number.
1790
- */
1791
- function evaluateExpression(expression, context) {
1792
- try {
1793
- return jexl.evalSync(expression, context);
1794
- } catch (err) {
1795
- const reason = err instanceof Error ? err.message : String(err);
1796
- throw new Error(`[mono-export] cannot evaluate {{= ${expression} }} — ${reason}`);
1797
- }
1798
- }
1799
- /**
1800
- * Normalise JS habits that Jexl's grammar doesn't share. Everyone types `===`;
1801
- * Jexl only knows `==`, and would otherwise throw a bare "Token = unexpected".
1802
- */
1803
- function normalizeExpression(expression) {
1804
- return expression.replace(/===/g, "==").replace(/!==/g, "!=");
1805
- }
1806
- /** Escape a string for embedding in a Handlebars double-quoted literal. */
1807
- function toHandlebarsLiteral(value) {
1808
- return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
1809
- }
1810
- /**
1811
- * Find the `}}` that closes a mustache opened at `start`, ignoring any that
1812
- * appear inside a quoted string (`{{= name == "a}}b" }}` is one expression).
1813
- * Returns the index of the `}}`, or `-1` when unterminated.
1814
- */
1815
- function findMustacheEnd(src, start) {
1816
- let quote = null;
1817
- for (let i = start; i < src.length - 1; i += 1) {
1818
- const ch = src[i];
1819
- if (quote) {
1820
- if (ch === "\\") i += 1;
1821
- else if (ch === quote) quote = null;
1822
- continue;
1823
- }
1824
- if (ch === "\"" || ch === "'") {
1825
- quote = ch;
1826
- continue;
1827
- }
1828
- if (ch === "}" && src[i + 1] === "}") return i;
1829
- }
1830
- return -1;
1831
- }
1832
- /** Whether `line` is a GFM table row (`| a | b |`), ignoring indentation. */
1833
- function isTableRow(line) {
1834
- return /^\s{0,3}\|/.test(line);
1835
- }
1836
- /**
1837
- * Rewrite a template's mustaches. Single pass, line-aware (for table rows) and
1838
- * code-aware (fenced blocks + inline spans are copied verbatim).
1839
- */
1840
- function preprocessTemplate(src, opts = {}) {
1841
- const escapeCells = opts.escapeTableCells !== false;
1842
- const lines = src.split("\n");
1843
- const state = {
1844
- fence: null,
1845
- inCode: false
1846
- };
1847
- const out = [];
1848
- for (const line of lines) {
1849
- const fenceMatch = /^\s{0,3}(`{3,}|~{3,})/.exec(line);
1850
- if (fenceMatch) {
1851
- const marker = fenceMatch[1][0].repeat(3);
1852
- if (state.fence === null) state.fence = marker;
1853
- else if (state.fence === marker) state.fence = null;
1854
- out.push(line);
1855
- continue;
1856
- }
1857
- if (state.fence) {
1858
- out.push(line);
1859
- continue;
1860
- }
1861
- out.push(rewriteLine(line, escapeCells && isTableRow(line), state));
1862
- }
1863
- return out.join("\n");
1864
- }
1865
- /** Rewrite the mustaches on one non-fenced line. */
1866
- function rewriteLine(line, wrapCells, state) {
1867
- let out = "";
1868
- let i = 0;
1869
- while (i < line.length) {
1870
- const ch = line[i];
1871
- if (ch === "`") {
1872
- state.inCode = !state.inCode;
1873
- out += ch;
1874
- i += 1;
1875
- continue;
1876
- }
1877
- if (state.inCode || ch !== "{" || line[i + 1] !== "{") {
1878
- out += ch;
1879
- i += 1;
1880
- continue;
1881
- }
1882
- const isTriple = line[i + 2] === "{";
1883
- const open = isTriple ? i + 3 : i + 2;
1884
- const end = findMustacheEnd(line, open);
1885
- if (end === -1) {
1886
- out += line.slice(i);
1887
- break;
1888
- }
1889
- const closeLength = isTriple && line[end + 2] === "}" ? 3 : 2;
1890
- const inner = line.slice(open, end);
1891
- out += renderMustache(inner, {
1892
- isTriple,
1893
- wrapCells
1894
- });
1895
- i = end + closeLength;
1896
- }
1897
- return out;
1898
- }
1899
- /**
1900
- * Split a mustache body into its Handlebars whitespace-control markers and the
1901
- * expression between them, so `{{~ foo ~}}` keeps its `~`s after rewriting.
1902
- */
1903
- function splitWhitespaceControl(inner) {
1904
- let body = inner;
1905
- let open = "";
1906
- let close = "";
1907
- if (body.startsWith("~")) {
1908
- open = "~";
1909
- body = body.slice(1);
1910
- }
1911
- if (body.endsWith("~")) {
1912
- close = "~";
1913
- body = body.slice(0, -1);
1914
- }
1915
- return {
1916
- open,
1917
- body: body.trim(),
1918
- close
1919
- };
1920
- }
1921
- /**
1922
- * Whether `body` is a bare path (`Name.Full`, `[my field]`, `@index`) rather
1923
- * than a helper call (`currency salary`).
1924
- *
1925
- * This distinction decides how the value is handed to `esc`: a path is passed
1926
- * as an **argument** (`{{esc Name.Full}}`), while a helper call must become a
1927
- * **sub-expression** (`{{esc (currency salary)}}`). Getting it backwards breaks
1928
- * at runtime — `(Name.Full)` compiles to a helper invocation, and Handlebars
1929
- * then tries to *call* the string it resolved.
1930
- */
1931
- function isBarePath(body) {
1932
- return (body.startsWith("[") ? body.slice(body.indexOf("]") + 1) : body.replace(/^\S+/, "")).trim() === "";
1933
- }
1934
- /** Turn one mustache body into its rewritten `{{…}}` form. */
1935
- function renderMustache(inner, { isTriple, wrapCells }) {
1936
- const { open, body, close } = splitWhitespaceControl(inner);
1937
- const wrap = (expr) => `{{${open}${expr}${close}}}`;
1938
- if (body.startsWith("=")) {
1939
- const call = `__jexl ${toHandlebarsLiteral(normalizeExpression(body.slice(1).trim()))}`;
1940
- return wrap(wrapCells ? `esc (${call})` : call);
1941
- }
1942
- if (isTriple) return `{{{${inner}}}}`;
1943
- if (NON_VALUE_MUSTACHE.test(body)) return wrap(body);
1944
- if (wrapCells) return wrap(isBarePath(body) ? `esc ${body}` : `esc (${body})`);
1945
- return wrap(body);
1946
- }
1947
- /**
1948
- * Escape an interpolated value for a GFM table cell. Registered as the `esc`
1949
- * helper and applied automatically to table-row mustaches by
1950
- * {@link preprocessTemplate}; also callable by hand.
1951
- */
1952
- function escapeForCell(value) {
1953
- if (value == null) return "";
1954
- return escapeCellText(String(value));
1955
- }
1956
-
1957
- //#endregion
1958
- //#region src/export/helpers.ts
1959
- /**
1960
- * Built-in Handlebars helpers for report templates.
1961
- *
1962
- * Three families:
1963
- *
1964
- * - **Formatting** (`currency`, `number`, `date`, `percent`) — emit pretty
1965
- * display text *plus* a hidden {@link ValueDirective} carrying the raw value
1966
- * and an Excel number format. That's what keeps `SUM()` working: Markdown
1967
- * shows `Rp 1.000.000`, the spreadsheet stores `1000000`.
1968
- * - **Aggregation / logic** (`sum`, `avg`, `count`, `eq`, `gt`, …) — plain
1969
- * values, so they nest as sub-expressions: `{{currency (sum rows "Salary")}}`.
1970
- * - **Excel-only** (`style`, `rowStyle`, `merge`, `formula`, `image`) — emit a
1971
- * directive and no visible text, so they vanish from Markdown output.
1972
- */
1973
- /** Drop Handlebars' trailing options object, returning it alongside the args. */
1974
- function splitArgs(args) {
1975
- const last = args[args.length - 1];
1976
- const isOptions = !!last && typeof last === "object" && "hash" in last;
1977
- return {
1978
- args: isOptions ? args.slice(0, -1) : args,
1979
- hash: (isOptions ? last.hash : void 0) ?? {}
1980
- };
1981
- }
1982
- /** Coerce to a finite number, or `null` when the value isn't numeric. */
1983
- function toNumber(value) {
1984
- if (typeof value === "number") return Number.isFinite(value) ? value : null;
1985
- if (typeof value === "string" && value.trim() !== "") {
1986
- const n = Number(value);
1987
- return Number.isFinite(n) ? n : null;
1988
- }
1989
- return null;
1990
- }
1991
- /** Coerce to a Date, or `null`. Accepts a Date, an ISO string, or epoch ms. */
1992
- function toDate(value) {
1993
- if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value;
1994
- if (typeof value === "number" || typeof value === "string") {
1995
- const d = new Date(value);
1996
- return Number.isNaN(d.getTime()) ? null : d;
1997
- }
1998
- return null;
1999
- }
2000
- /** Pull `field` off each item (or the item itself when no field is given). */
2001
- function pluck(list, field) {
2002
- if (!Array.isArray(list)) return [];
2003
- if (typeof field !== "string" || !field) return list;
2004
- return list.map((item) => item?.[field]);
2005
- }
2006
- /** The numeric values of `list[field]`, skipping anything non-numeric. */
2007
- function numbersOf(list, field) {
2008
- return pluck(list, field).map(toNumber).filter((n) => n !== null);
2009
- }
2010
- /**
2011
- * Derive an Excel number format from a currency code by asking `Intl` where the
2012
- * symbol goes and how many decimals it uses — so IDR renders `"Rp"#,##0` and
2013
- * EUR-in-German renders `#,##0.00" €"` without a hard-coded lookup table.
2014
- */
2015
- function deriveCurrencyFormat(locale, currency) {
2016
- try {
2017
- const parts = new Intl.NumberFormat(locale, {
2018
- style: "currency",
2019
- currency
2020
- }).formatToParts(1);
2021
- const symbol = parts.find((p) => p.type === "currency")?.value ?? currency;
2022
- const fraction = parts.find((p) => p.type === "fraction")?.value ?? "";
2023
- const digits = fraction.length ? `.${"0".repeat(fraction.length)}` : "";
2024
- const symbolFirst = parts.findIndex((p) => p.type === "currency") === 0;
2025
- const quoted = `"${symbol}"`;
2026
- return symbolFirst ? `${quoted}#,##0${digits}` : `#,##0${digits}${quoted}`;
2027
- } catch {
2028
- return "#,##0.00";
2029
- }
2030
- }
2031
- /**
2032
- * Display text + the raw value/format directive that Excel will pick up. The
2033
- * display text is echoed back into the directive (`t`) so the renderer can tell
2034
- * "this cell *is* the value" from "this value is mentioned mid-sentence".
2035
- */
2036
- function formatted(display, directive) {
2037
- return display + encodeDirective({
2038
- k: "val",
2039
- ...directive,
2040
- t: display
2041
- });
2042
- }
2043
- /**
2044
- * Build the built-in helper map for one render. Bound to `formatting` so
2045
- * locale/currency choices apply consistently across every helper.
2046
- */
2047
- function createHelpers(formatting = {}) {
2048
- const locale = formatting.locale;
2049
- const currencyCode = formatting.currency ?? "USD";
2050
- const currencyFormat = formatting.currencyFormat ?? deriveCurrencyFormat(locale, currencyCode);
2051
- const numberFormat = formatting.numberFormat ?? "#,##0";
2052
- const dateFormat = formatting.dateFormat ?? "yyyy-mm-dd";
2053
- const percentFormat = formatting.percentFormat ?? "0.00%";
2054
- return {
2055
- /** `{{currency salary}}` → `$1,234.00` in Markdown, `1234` + format in Excel. */
2056
- currency(...raw) {
2057
- const { args, hash } = splitArgs(raw);
2058
- const n = toNumber(args[0]);
2059
- if (n === null) return "";
2060
- const code = hash.code ?? currencyCode;
2061
- return formatted(new Intl.NumberFormat(locale, {
2062
- style: "currency",
2063
- currency: code
2064
- }).format(n), {
2065
- n,
2066
- f: hash.fmt ?? (code === currencyCode ? currencyFormat : deriveCurrencyFormat(locale, code))
2067
- });
2068
- },
2069
- /** `{{number qty}}` / `{{number rate decimals=2}}`. */
2070
- number(...raw) {
2071
- const { args, hash } = splitArgs(raw);
2072
- const n = toNumber(args[0]);
2073
- if (n === null) return "";
2074
- const decimals = toNumber(hash.decimals);
2075
- return formatted(new Intl.NumberFormat(locale, {
2076
- minimumFractionDigits: decimals ?? void 0,
2077
- maximumFractionDigits: decimals ?? void 0
2078
- }).format(n), {
2079
- n,
2080
- f: hash.fmt ?? (decimals ? `#,##0.${"0".repeat(decimals)}` : numberFormat)
2081
- });
2082
- },
2083
- /** `{{date createdAt}}` — Markdown gets the locale date, Excel a real Date. */
2084
- date(...raw) {
2085
- const { args, hash } = splitArgs(raw);
2086
- const d = toDate(args[0]);
2087
- if (!d) return "";
2088
- return formatted(new Intl.DateTimeFormat(locale, {
2089
- year: "numeric",
2090
- month: "2-digit",
2091
- day: "2-digit"
2092
- }).format(d), {
2093
- d: d.toISOString(),
2094
- f: hash.fmt ?? dateFormat
2095
- });
2096
- },
2097
- /** `{{percent 0.155}}` → `15.50%`; Excel stores the fraction with a % format. */
2098
- percent(...raw) {
2099
- const { args, hash } = splitArgs(raw);
2100
- const n = toNumber(args[0]);
2101
- if (n === null) return "";
2102
- return formatted(new Intl.NumberFormat(locale, {
2103
- style: "percent",
2104
- minimumFractionDigits: 2
2105
- }).format(n), {
2106
- n,
2107
- f: hash.fmt ?? percentFormat
2108
- });
2109
- },
2110
- /** `{{sum employees "salary"}}` — or `{{sum numbers}}` for a bare array. */
2111
- sum: (...raw) => {
2112
- const { args } = splitArgs(raw);
2113
- return numbersOf(args[0], args[1]).reduce((total, n) => total + n, 0);
2114
- },
2115
- avg: (...raw) => {
2116
- const { args } = splitArgs(raw);
2117
- const values = numbersOf(args[0], args[1]);
2118
- return values.length ? values.reduce((t, n) => t + n, 0) / values.length : 0;
2119
- },
2120
- /** `{{count employees}}` — length, or how many have a truthy `field`. */
2121
- count: (...raw) => {
2122
- const { args } = splitArgs(raw);
2123
- const list = args[0];
2124
- if (!Array.isArray(list)) return 0;
2125
- return typeof args[1] === "string" ? pluck(list, args[1]).filter((v) => v != null && v !== "").length : list.length;
2126
- },
2127
- max: (...raw) => {
2128
- const { args } = splitArgs(raw);
2129
- const values = numbersOf(args[0], args[1]);
2130
- return values.length ? Math.max(...values) : 0;
2131
- },
2132
- min: (...raw) => {
2133
- const { args } = splitArgs(raw);
2134
- const values = numbersOf(args[0], args[1]);
2135
- return values.length ? Math.min(...values) : 0;
2136
- },
2137
- eq: (...raw) => {
2138
- const { args } = splitArgs(raw);
2139
- return args[0] === args[1];
2140
- },
2141
- ne: (...raw) => {
2142
- const { args } = splitArgs(raw);
2143
- return args[0] !== args[1];
2144
- },
2145
- gt: (...raw) => compare(raw, (a, b) => a > b),
2146
- gte: (...raw) => compare(raw, (a, b) => a >= b),
2147
- lt: (...raw) => compare(raw, (a, b) => a < b),
2148
- lte: (...raw) => compare(raw, (a, b) => a <= b),
2149
- and: (...raw) => splitArgs(raw).args.every(Boolean),
2150
- or: (...raw) => splitArgs(raw).args.some(Boolean),
2151
- not: (...raw) => !splitArgs(raw).args[0],
2152
- /** `{{default value "-"}}` — fall back when null / undefined / empty. */
2153
- default: (...raw) => {
2154
- const { args } = splitArgs(raw);
2155
- const value = args[0];
2156
- return value == null || value === "" ? args[1] ?? "" : value;
2157
- },
2158
- /**
2159
- * Escape a value for a GFM table cell. Applied automatically to mustaches on
2160
- * table rows by the preprocessor; call it by hand elsewhere if needed.
2161
- */
2162
- esc: (...raw) => escapeForCell(splitArgs(raw).args[0]),
2163
- /** `{{style "header"}}` — apply a named style to this cell. */
2164
- style: (...raw) => {
2165
- const { args } = splitArgs(raw);
2166
- const name = args[0];
2167
- return typeof name === "string" && name ? encodeDirective({
2168
- k: "style",
2169
- v: name
2170
- }) : "";
2171
- },
2172
- /** `{{rowStyle "groupHeader"}}` — apply a named style to the whole row. */
2173
- rowStyle: (...raw) => {
2174
- const { args } = splitArgs(raw);
2175
- const name = args[0];
2176
- return typeof name === "string" && name ? encodeDirective({
2177
- k: "rowStyle",
2178
- v: name
2179
- }) : "";
2180
- },
2181
- /** `{{merge cols=4}}` — merge this cell across columns and/or rows. */
2182
- merge: (...raw) => {
2183
- const { hash } = splitArgs(raw);
2184
- const cols = toNumber(hash.cols);
2185
- const rows = toNumber(hash.rows);
2186
- if (!cols && !rows) return "";
2187
- return encodeDirective({
2188
- k: "merge",
2189
- ...cols ? { cols: Math.max(1, Math.floor(cols)) } : {},
2190
- ...rows ? { rows: Math.max(1, Math.floor(rows)) } : {}
2191
- });
2192
- },
2193
- /**
2194
- * `{{formula "SUM(C{row}:D{row})"}}` — an Excel formula for this cell.
2195
- * `{row}`, `{firstRow}`, `{lastRow}` and `{col:Field}` are resolved when the
2196
- * cell is written, since a template can't know its own row number.
2197
- */
2198
- formula: (...raw) => {
2199
- const { args } = splitArgs(raw);
2200
- const expr = args[0];
2201
- return typeof expr === "string" && expr ? encodeDirective({
2202
- k: "formula",
2203
- v: expr
2204
- }) : "";
2205
- },
2206
- /** `{{image logo width=120 height=40}}` — anchor an image at this cell. */
2207
- image: (...raw) => {
2208
- const { args, hash } = splitArgs(raw);
2209
- const src = args[0];
2210
- if (typeof src !== "string" || !src) return "";
2211
- const width = toNumber(hash.width);
2212
- const height = toNumber(hash.height);
2213
- return encodeDirective({
2214
- k: "image",
2215
- v: src,
2216
- ...width ? { width } : {},
2217
- ...height ? { height } : {}
2218
- });
2219
- }
2220
- };
2221
- }
2222
- /** Numeric-aware comparison shared by `gt` / `gte` / `lt` / `lte`. */
2223
- function compare(raw, test) {
2224
- const { args } = splitArgs(raw);
2225
- const a = toNumber(args[0]);
2226
- const b = toNumber(args[1]);
2227
- if (a !== null && b !== null) return test(a, b);
2228
- return test(args[0], args[1]);
2229
- }
2230
-
2231
- //#endregion
2232
- //#region src/export/template.ts
2233
- /** Load the optional `handlebars` peer, with an actionable error when it's absent. */
2234
- async function loadHandlebars() {
2235
- try {
2236
- const mod = await import("handlebars");
2237
- return mod?.default ?? mod;
2238
- } catch (err) {
2239
- throw new Error("[mono-export] rendering a report needs the optional peer dependency \"handlebars\". Install it in your app: pnpm add handlebars" + (err instanceof Error ? `\n (resolution failed: ${err.message})` : ""));
2240
- }
2241
- }
2242
- /**
2243
- * Render a report template to Markdown (still carrying directive tokens).
2244
- *
2245
- * `noEscape` is deliberate: Handlebars' default escaping is *HTML* escaping,
2246
- * which would turn `&` into `&amp;` and `"` into `&quot;` inside a spreadsheet
2247
- * cell. Table cells are protected instead by the `esc` helper, which the
2248
- * preprocessor injects only where it matters (see `expression.ts`).
2249
- */
2250
- async function renderTemplate(options) {
2251
- const env = (await loadHandlebars()).create();
2252
- env.registerHelper(createHelpers(options.formatting));
2253
- /**
2254
- * The bridge to Jexl. `this` is the current block context (inside `{{#each}}`
2255
- * it's the item), `options.data.root` is the whole report context — merging
2256
- * them lets an expression name a loop-local field *and* a top-level one.
2257
- */
2258
- env.registerHelper("__jexl", function(...args) {
2259
- const helperOptions = args[args.length - 1];
2260
- const expression = String(args[0] ?? "");
2261
- const root = helperOptions?.data?.root ?? {};
2262
- const local = typeof this === "object" && this !== null ? this : {};
2263
- const value = evaluateExpression(expression, {
2264
- ...root,
2265
- ...local,
2266
- this: local
2267
- });
2268
- return value == null ? "" : value;
2269
- });
2270
- if (options.helpers) env.registerHelper(options.helpers);
2271
- if (options.partials) for (const [name, source] of Object.entries(options.partials)) env.registerPartial(name, preprocessTemplate(source));
2272
- return env.compile(preprocessTemplate(options.md ?? ""), { noEscape: true })(options.data ?? {});
2273
- }
2274
-
2275
- //#endregion
2276
- //#region src/export/index.ts
2277
- /**
2278
- * `@mono-lit/helper/export` — render a Markdown template into a report.
2279
- *
2280
- * The pipeline: **Handlebars** fills the template from your data, **Jexl**
2281
- * evaluates any `{{= … }}` expressions, **remark** parses the result into an
2282
- * AST, and a renderer walks that AST. Markdown is the template language, so the
2283
- * layout stays readable and diffable, and the data stays separate from the
2284
- * presentation.
2285
- *
2286
- * @example
2287
- * import { exportTable } from '@mono-lit/helper/export'
2288
- * import md from './payroll.md?raw'
2289
- *
2290
- * const report = await exportTable({ md, data: { employees }, fileName: 'payroll.xlsx' })
2291
- * report.markdown // the rendered markdown, for a preview pane
2292
- *
2293
- * Bound to a grid, `monoDataGrid(...).export({ md, … })` does the same thing
2294
- * with the table's rows, groups and columns already in the context.
2295
- */
2296
- /** Pick the renderer from a file name's extension. */
2297
- function formatFromFileName(fileName) {
2298
- if (!fileName) return null;
2299
- const ext = fileName.slice(fileName.lastIndexOf(".") + 1).toLowerCase();
2300
- if (ext === "xlsx" || ext === "xls") return "xlsx";
2301
- if (ext === "md" || ext === "markdown") return "md";
2302
- return null;
2303
- }
2304
- /** Give a file name the extension its format implies. */
2305
- function withExtension(fileName, format) {
2306
- return formatFromFileName(fileName) === format ? fileName : `${fileName}.${format}`;
2307
- }
2308
- /**
2309
- * Render a Markdown report template.
2310
- *
2311
- * When `fileName` is given its extension selects the renderer and the file
2312
- * downloads automatically (pass `download: false` to suppress that). Without
2313
- * one, nothing is written — you just get the result object.
2314
- */
2315
- async function exportTable(options) {
2316
- const data = await resolveExportData(options.data, { chunkSize: options.chunkSize });
2317
- const rendered = await renderTemplate({
2318
- ...options,
2319
- data
2320
- });
2321
- const markdown = stripDirectives(rendered);
2322
- const resolvedFormat = options.format ?? formatFromFileName(options.fileName);
2323
- const detailSheets = [];
2324
- const skipped = [];
2325
- if (options.detail) {
2326
- const detail = options.detail;
2327
- const masterRows = data[detail.from ?? "rows"];
2328
- const { details, skipped: dropped } = await resolveDetails(Array.isArray(masterRows) ? masterRows : [], detail);
2329
- skipped.push(...dropped);
2330
- for (const item of details) detailSheets.push({
2331
- key: item.key,
2332
- name: detail.sheetName?.(item.row) ?? item.key,
2333
- markdown: await renderTemplate({
2334
- ...options,
2335
- md: detail.md,
2336
- data: {
2337
- row: item.row,
2338
- rows: item.rows
2339
- }
2340
- })
2341
- });
2342
- }
2343
- let workbookPromise = null;
2344
- const workbook = () => {
2345
- workbookPromise ??= import("./excel-BXzr3uI1.js").then(({ renderExcel }) => renderExcel(parseMarkdown(rendered), {
2346
- ...options,
2347
- back: options.detail?.back,
2348
- sheets: detailSheets.map((s) => ({
2349
- key: s.key,
2350
- name: s.name,
2351
- ast: parseMarkdown(s.markdown)
2352
- }))
2353
- })).then(async (book) => {
2354
- await options.onWorkbook?.(book);
2355
- return book;
2356
- });
2357
- return workbookPromise;
2358
- };
2359
- const toBuffer = async (format) => {
2360
- if ((format ?? resolvedFormat ?? "md") === "md") return new TextEncoder().encode(markdown).buffer;
2361
- return await (await workbook()).xlsx.writeBuffer();
2362
- };
2363
- const toBlob = async (format) => {
2364
- const target = format ?? resolvedFormat ?? "md";
2365
- return new Blob([await toBuffer(target)], { type: MIME[target] });
2366
- };
2367
- const download = async (fileName) => {
2368
- const target = resolvedFormat ?? formatFromFileName(fileName) ?? "md";
2369
- const name = withExtension(fileName ?? options.fileName ?? "export", target);
2370
- downloadBlob(await toBlob(target), name);
2371
- };
2372
- const result = {
2373
- markdown,
2374
- format: resolvedFormat,
2375
- fileName: options.fileName ?? null,
2376
- sheets: [options.sheetName ?? "Sheet1", ...detailSheets.map((s) => s.name)],
2377
- skipped,
2378
- toBlob,
2379
- toBuffer,
2380
- workbook,
2381
- download
2382
- };
2383
- if (options.fileName && options.download !== false) await download();
2384
- return result;
2385
- }
2386
-
2387
- //#endregion
2388
- export { exportTable };