@svadmin/ui 0.70.0 → 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/README.md +40 -25
  2. package/THIRD_PARTY_NOTICES.md +52 -0
  3. package/dist/actions.js +1 -1
  4. package/dist/app.css +7804 -5188
  5. package/dist/app.theme.css +7738 -5173
  6. package/dist/class-properties.generated.d.ts +1 -0
  7. package/dist/class-properties.generated.js +2 -0
  8. package/dist/classnames.d.ts +8 -0
  9. package/dist/classnames.js +26 -0
  10. package/dist/component-registry.svelte.d.ts +33 -19
  11. package/dist/component-registry.svelte.js +6 -4
  12. package/dist/components/AdminApp.svelte +55 -53
  13. package/dist/components/AdminApp.svelte.d.ts +2 -2
  14. package/dist/components/ApiSettings.svelte +19 -1
  15. package/dist/components/AuditLogDrawer.svelte +14 -3
  16. package/dist/components/AutoForm.svelte +162 -50
  17. package/dist/components/AutoForm.svelte.d.ts +4 -0
  18. package/dist/components/AutoTable.svelte +599 -259
  19. package/dist/components/AutoTable.svelte.d.ts +6 -0
  20. package/dist/components/BoundRecordDetailDrawer.svelte +172 -0
  21. package/dist/components/BoundRecordDetailDrawer.svelte.d.ts +11 -0
  22. package/dist/components/Breadcrumbs.svelte +7 -4
  23. package/dist/components/CancelTaskButton.svelte +9 -5
  24. package/dist/components/ColumnHeaderFilter.svelte +4 -3
  25. package/dist/components/ColumnSettings.svelte +1 -0
  26. package/dist/components/ComboboxField.svelte +118 -36
  27. package/dist/components/ComboboxField.svelte.d.ts +5 -4
  28. package/dist/components/CreatePage.svelte +7 -1
  29. package/dist/components/CreatePage.svelte.d.ts +2 -0
  30. package/dist/components/DateRangeInput.svelte +75 -0
  31. package/dist/components/DateRangeInput.svelte.d.ts +25 -0
  32. package/dist/components/DateTimeInput.svelte +65 -0
  33. package/dist/components/DateTimeInput.svelte.d.ts +19 -0
  34. package/dist/components/DetailDrawer.svelte +4 -0
  35. package/dist/components/DetailDrawer.svelte.d.ts +1 -0
  36. package/dist/components/DevTools.svelte +8 -21
  37. package/dist/components/DraggableGrid.svelte +1 -0
  38. package/dist/components/DraggableHeader.svelte +5 -9
  39. package/dist/components/DraggableHeader.svelte.d.ts +43 -18
  40. package/dist/components/DraggableRowTable.svelte +2 -2
  41. package/dist/components/DynamicFormList.svelte +17 -17
  42. package/dist/components/DynamicFormList.svelte.d.ts +2 -1
  43. package/dist/components/EditPage.svelte +7 -1
  44. package/dist/components/EditPage.svelte.d.ts +2 -0
  45. package/dist/components/EditableTable.svelte +4 -0
  46. package/dist/components/ErrorPage.svelte +3 -1
  47. package/dist/components/FieldDisplay.svelte +14 -0
  48. package/dist/components/FieldDisplay.svelte.d.ts +7 -0
  49. package/dist/components/FieldRenderer.svelte +96 -20
  50. package/dist/components/FileUpload.svelte +250 -0
  51. package/dist/components/FileUpload.svelte.d.ts +32 -0
  52. package/dist/components/FilterBuilder.svelte +236 -268
  53. package/dist/components/FilterBuilder.svelte.d.ts +3 -0
  54. package/dist/components/FilterDropdown.svelte.d.ts +1 -1
  55. package/dist/components/Header.svelte +5 -6
  56. package/dist/components/ImportWizard.svelte +182 -94
  57. package/dist/components/InfiniteList.svelte +22 -8
  58. package/dist/components/InfiniteList.svelte.d.ts +5 -3
  59. package/dist/components/InlineEdit.svelte +114 -44
  60. package/dist/components/JsonSchemaForm.svelte +256 -95
  61. package/dist/components/JsonSchemaForm.svelte.d.ts +12 -1
  62. package/dist/components/Layout.svelte +20 -17
  63. package/dist/components/LazyTaskQueueDrawer.svelte +26 -0
  64. package/dist/components/LazyTaskQueueDrawer.svelte.d.ts +8 -0
  65. package/dist/components/ListPage.svelte +11 -6
  66. package/dist/components/ListPage.svelte.d.ts +2 -0
  67. package/dist/components/LoginPage.svelte +1 -1
  68. package/dist/components/MasterDetailView.svelte +3 -3
  69. package/dist/components/MediaLibraryModal.svelte +5 -2
  70. package/dist/components/MentionsInput.svelte +4 -3
  71. package/dist/components/MoneyInput.svelte +25 -0
  72. package/dist/components/MoneyInput.svelte.d.ts +20 -0
  73. package/dist/components/NavigateToResource.svelte +3 -2
  74. package/dist/components/NumberInput.svelte +25 -0
  75. package/dist/components/NumberInput.svelte.d.ts +19 -0
  76. package/dist/components/NumericInput.svelte +110 -0
  77. package/dist/components/NumericInput.svelte.d.ts +23 -0
  78. package/dist/components/PercentInput.svelte +25 -0
  79. package/dist/components/PercentInput.svelte.d.ts +20 -0
  80. package/dist/components/PermissionMatrix.svelte +4 -3
  81. package/dist/components/ProfilePage.svelte +2 -2
  82. package/dist/components/QuickEditDrawer.svelte +42 -0
  83. package/dist/components/QuickEditDrawer.svelte.d.ts +10 -0
  84. package/dist/components/RecordDetailDrawer.svelte +16 -108
  85. package/dist/components/RecordDetailDrawer.svelte.d.ts +2 -0
  86. package/dist/components/RecordRowActions.svelte +41 -0
  87. package/dist/components/RecordRowActions.svelte.d.ts +14 -0
  88. package/dist/components/ResourceAccessGuard.svelte +7 -5
  89. package/dist/components/ResourceOperationsPage.svelte +25 -19
  90. package/dist/components/ResourceOperationsPage.svelte.d.ts +5 -1
  91. package/dist/components/RetryTaskButton.svelte +9 -5
  92. package/dist/components/RowActions.svelte +5 -3
  93. package/dist/components/SensitiveDataMask.svelte +3 -3
  94. package/dist/components/SettingsPage.svelte +1 -1
  95. package/dist/components/ShowInferencer.svelte +4 -2
  96. package/dist/components/ShowInferencer.svelte.d.ts +2 -0
  97. package/dist/components/ShowPage.svelte +49 -39
  98. package/dist/components/ShowPage.svelte.d.ts +2 -0
  99. package/dist/components/Sidebar.svelte +15 -13
  100. package/dist/components/SplitPaneLayout.svelte +4 -2
  101. package/dist/components/SpreadsheetView.svelte +81 -286
  102. package/dist/components/StepsForm.svelte +166 -49
  103. package/dist/components/StepsForm.svelte.d.ts +1 -0
  104. package/dist/components/SvarAutoTable.svelte +39 -0
  105. package/dist/components/SvarAutoTable.svelte.d.ts +13 -0
  106. package/dist/components/SvarDataGrid.svelte +362 -0
  107. package/dist/components/SvarDataGrid.svelte.d.ts +57 -0
  108. package/dist/components/SvarGridCell.svelte +10 -0
  109. package/dist/components/SvarGridCell.svelte.d.ts +7 -0
  110. package/dist/components/SvarResourceRead.svelte +50 -0
  111. package/dist/components/SvarResourceRead.svelte.d.ts +23 -0
  112. package/dist/components/SvarResourceTable.svelte +63 -0
  113. package/dist/components/SvarResourceTable.svelte.d.ts +42 -0
  114. package/dist/components/SvarResourceTableView.svelte +364 -0
  115. package/dist/components/SvarResourceTableView.svelte.d.ts +4 -0
  116. package/dist/components/TaskDetails.svelte +20 -7
  117. package/dist/components/TaskList.svelte +19 -7
  118. package/dist/components/TaskQueueDrawer.svelte +92 -37
  119. package/dist/components/Toast.svelte +4 -2
  120. package/dist/components/TooltipButton.svelte +1 -1
  121. package/dist/components/TreeSelect.svelte +212 -30
  122. package/dist/components/TreeSelect.svelte.d.ts +3 -1
  123. package/dist/components/ValidatedField.svelte +27 -0
  124. package/dist/components/ValidatedField.svelte.d.ts +35 -0
  125. package/dist/components/account/ImportMembersPage.svelte +2 -2
  126. package/dist/components/account/SecurityLogPage.svelte +3 -1
  127. package/dist/components/account/SettingsEnterprisePage.svelte +7 -5
  128. package/dist/components/account/TeamMembersPage.svelte +1 -1
  129. package/dist/components/auto-table-grid.d.ts +26 -0
  130. package/dist/components/auto-table-grid.js +1 -0
  131. package/dist/components/buttons/CloneButton.svelte +6 -4
  132. package/dist/components/buttons/DeleteButton.svelte +95 -29
  133. package/dist/components/buttons/DeleteButton.svelte.d.ts +2 -0
  134. package/dist/components/buttons/EditButton.svelte +6 -4
  135. package/dist/components/buttons/ExportButton.svelte +22 -4
  136. package/dist/components/buttons/ImportButton.svelte +83 -38
  137. package/dist/components/buttons/ImportButton.svelte.d.ts +6 -10
  138. package/dist/components/buttons/RefreshButton.svelte +48 -8
  139. package/dist/components/buttons/ShowButton.svelte +6 -4
  140. package/dist/components/content/ApiKeyList.svelte +3 -1
  141. package/dist/components/content/ContentPageHeader.svelte +12 -9
  142. package/dist/components/content/ContentPageShell.svelte +8 -9
  143. package/dist/components/content/FileBrowser.svelte +35 -0
  144. package/dist/components/content/FileBrowser.svelte.d.ts +14 -0
  145. package/dist/components/content/FileList.svelte +3 -1
  146. package/dist/components/content/MemberList.svelte +3 -1
  147. package/dist/components/content/MetricBlock.svelte +10 -13
  148. package/dist/components/content/NetworkTable.svelte +6 -4
  149. package/dist/components/content/NetworkTable.svelte.d.ts +1 -0
  150. package/dist/components/content/PageToolbar.svelte +6 -10
  151. package/dist/components/content/SectionHeader.svelte +8 -13
  152. package/dist/components/content/SecurityEventTable.svelte +3 -1
  153. package/dist/components/content/SettingsFieldRow.svelte +9 -23
  154. package/dist/components/content/SettingsGroup.svelte +11 -27
  155. package/dist/components/content/StatusBadge.svelte +3 -8
  156. package/dist/components/content/StatusTabs.svelte +2 -2
  157. package/dist/components/content/WorkspaceLayout.svelte +8 -12
  158. package/dist/components/enterprise/filter-tree.d.ts +48 -0
  159. package/dist/components/enterprise/filter-tree.js +224 -0
  160. package/dist/components/enterprise/json-schema-form.d.ts +39 -0
  161. package/dist/components/enterprise/json-schema-form.js +195 -0
  162. package/dist/components/enterprise/recursive-schema-form.d.ts +30 -0
  163. package/dist/components/enterprise/recursive-schema-form.js +196 -0
  164. package/dist/components/enterprise/spreadsheet-formula.d.ts +12 -0
  165. package/dist/components/enterprise/spreadsheet-formula.js +245 -0
  166. package/dist/components/fieldComponentMap.d.ts +18 -13
  167. package/dist/components/fieldComponentMap.js +100 -47
  168. package/dist/components/fields/AvatarField.svelte +1 -1
  169. package/dist/components/fields/ChoiceField.svelte +16 -0
  170. package/dist/components/fields/ChoiceField.svelte.d.ts +10 -0
  171. package/dist/components/fields/CodeField.svelte +11 -12
  172. package/dist/components/fields/CodeField.svelte.d.ts +1 -1
  173. package/dist/components/fields/DateField.svelte +4 -3
  174. package/dist/components/fields/DateRangeField.svelte +2 -4
  175. package/dist/components/fields/ImageField.svelte +3 -1
  176. package/dist/components/fields/ImagesField.svelte +23 -0
  177. package/dist/components/fields/ImagesField.svelte.d.ts +6 -0
  178. package/dist/components/fields/JsonField.svelte +19 -13
  179. package/dist/components/fields/PasswordField.svelte +5 -0
  180. package/dist/components/fields/PasswordField.svelte.d.ts +6 -0
  181. package/dist/components/fields/date-field-value.d.ts +2 -0
  182. package/dist/components/fields/date-field-value.js +13 -0
  183. package/dist/components/fields/json-value.d.ts +11 -0
  184. package/dist/components/fields/json-value.js +28 -0
  185. package/dist/components/json-schema-form-state.d.ts +37 -0
  186. package/dist/components/json-schema-form-state.js +168 -0
  187. package/dist/components/profile/ActivityTimeline.svelte +2 -2
  188. package/dist/components/record-detail.svelte.d.ts +19 -0
  189. package/dist/components/record-detail.svelte.js +34 -0
  190. package/dist/components/saved-list-views.js +29 -29
  191. package/dist/components/svar-grid-cells.d.ts +14 -0
  192. package/dist/components/svar-grid-cells.js +2 -0
  193. package/dist/components/svar-grid-contract.d.ts +80 -0
  194. package/dist/components/svar-grid-contract.js +159 -0
  195. package/dist/components/svar-grid-interactions.d.ts +54 -0
  196. package/dist/components/svar-grid-interactions.js +174 -0
  197. package/dist/components/svar-grid-loading.d.ts +40 -0
  198. package/dist/components/svar-grid-loading.js +180 -0
  199. package/dist/components/svar-grid-operations.d.ts +37 -0
  200. package/dist/components/svar-grid-operations.js +186 -0
  201. package/dist/components/svar-grid-panes.d.ts +34 -0
  202. package/dist/components/svar-grid-panes.js +66 -0
  203. package/dist/components/svar-grid-resource-loading.d.ts +18 -0
  204. package/dist/components/svar-grid-resource-loading.js +68 -0
  205. package/dist/components/svar-grid-resource-session.svelte.d.ts +29 -0
  206. package/dist/components/svar-grid-resource-session.svelte.js +61 -0
  207. package/dist/components/table-contract.d.ts +13 -0
  208. package/dist/components/table-contract.js +42 -0
  209. package/dist/components/task-utils.js +4 -2
  210. package/dist/components/ui/alert/alert-variants.d.ts +2 -3
  211. package/dist/components/ui/alert/alert-variants.js +1 -2
  212. package/dist/components/ui/alert/alert.svelte +4 -5
  213. package/dist/components/ui/alert/alert.svelte.d.ts +3 -8
  214. package/dist/components/ui/alert/index.js +0 -2
  215. package/dist/components/ui/avatar/avatar-variants.d.ts +2 -3
  216. package/dist/components/ui/avatar/avatar-variants.js +1 -2
  217. package/dist/components/ui/avatar/avatar.svelte +5 -6
  218. package/dist/components/ui/avatar/avatar.svelte.d.ts +3 -8
  219. package/dist/components/ui/badge/badge-variants.d.ts +2 -3
  220. package/dist/components/ui/badge/badge-variants.js +3 -2
  221. package/dist/components/ui/badge/badge.svelte +4 -5
  222. package/dist/components/ui/badge/badge.svelte.d.ts +3 -8
  223. package/dist/components/ui/badge/index.js +0 -2
  224. package/dist/components/ui/button/button-variants.d.ts +2 -3
  225. package/dist/components/ui/button/button-variants.js +5 -3
  226. package/dist/components/ui/button/button.svelte +100 -44
  227. package/dist/components/ui/button/button.svelte.d.ts +8 -12
  228. package/dist/components/ui/button/index.js +0 -2
  229. package/dist/components/ui/command/command-dialog.svelte +3 -1
  230. package/dist/components/ui/command/command-dialog.svelte.d.ts +1 -1
  231. package/dist/components/ui/command/command-group.svelte +4 -2
  232. package/dist/components/ui/command/command-item.svelte +4 -2
  233. package/dist/components/ui/command/command-separator.svelte +3 -1
  234. package/dist/components/ui/command/index.d.ts +5 -5
  235. package/dist/components/ui/input/input.svelte +41 -24
  236. package/dist/components/ui/input/input.svelte.d.ts +5 -4
  237. package/dist/components/ui/sheet/sheet.svelte +9 -3
  238. package/dist/components/ui/sheet/sheet.svelte.d.ts +1 -0
  239. package/dist/components/ui/textarea/textarea.svelte +2 -1
  240. package/dist/components/ui/tooltip/tooltip.svelte +4 -2
  241. package/dist/components.css +3079 -0
  242. package/dist/design-contract.d.ts +13 -0
  243. package/dist/design-contract.js +11 -0
  244. package/dist/design-system.d.ts +15 -0
  245. package/dist/design-system.js +7 -0
  246. package/dist/index.d.ts +15 -1
  247. package/dist/index.js +9 -0
  248. package/dist/inline-value.d.ts +5 -0
  249. package/dist/inline-value.js +24 -0
  250. package/dist/numeric-input.d.ts +2 -0
  251. package/dist/numeric-input.js +9 -0
  252. package/dist/page-chrome.css +12 -49
  253. package/dist/recipes.d.ts +4 -0
  254. package/dist/recipes.js +4 -0
  255. package/dist/rendering/index.d.ts +87 -0
  256. package/dist/rendering/index.js +117 -0
  257. package/dist/styled-system/css/conditions.js +36 -0
  258. package/dist/styled-system/css/css.d.ts +22 -0
  259. package/dist/styled-system/css/css.js +45 -0
  260. package/dist/styled-system/css/cva.d.ts +6 -0
  261. package/dist/styled-system/css/cva.js +87 -0
  262. package/dist/styled-system/css/cx.d.ts +5 -0
  263. package/dist/styled-system/css/cx.js +15 -0
  264. package/dist/styled-system/css/index.d.ts +5 -0
  265. package/dist/styled-system/css/index.js +4 -0
  266. package/dist/styled-system/css/sva.d.ts +4 -0
  267. package/dist/styled-system/css/sva.js +46 -0
  268. package/dist/styled-system/helpers.js +316 -0
  269. package/dist/styled-system/patterns/aspect-ratio.d.ts +20 -0
  270. package/dist/styled-system/patterns/aspect-ratio.js +38 -0
  271. package/dist/styled-system/patterns/bleed.d.ts +21 -0
  272. package/dist/styled-system/patterns/bleed.js +24 -0
  273. package/dist/styled-system/patterns/box.d.ts +20 -0
  274. package/dist/styled-system/patterns/box.js +15 -0
  275. package/dist/styled-system/patterns/center.d.ts +20 -0
  276. package/dist/styled-system/patterns/center.js +21 -0
  277. package/dist/styled-system/patterns/circle.d.ts +20 -0
  278. package/dist/styled-system/patterns/circle.js +25 -0
  279. package/dist/styled-system/patterns/container.d.ts +20 -0
  280. package/dist/styled-system/patterns/container.js +21 -0
  281. package/dist/styled-system/patterns/cq.d.ts +21 -0
  282. package/dist/styled-system/patterns/cq.js +21 -0
  283. package/dist/styled-system/patterns/divider.d.ts +22 -0
  284. package/dist/styled-system/patterns/divider.js +25 -0
  285. package/dist/styled-system/patterns/flex.d.ts +26 -0
  286. package/dist/styled-system/patterns/flex.js +26 -0
  287. package/dist/styled-system/patterns/float.d.ts +23 -0
  288. package/dist/styled-system/patterns/float.js +52 -0
  289. package/dist/styled-system/patterns/grid-item.d.ts +25 -0
  290. package/dist/styled-system/patterns/grid-item.js +25 -0
  291. package/dist/styled-system/patterns/grid.d.ts +24 -0
  292. package/dist/styled-system/patterns/grid.js +27 -0
  293. package/dist/styled-system/patterns/hstack.d.ts +21 -0
  294. package/dist/styled-system/patterns/hstack.js +24 -0
  295. package/dist/styled-system/patterns/index.d.ts +21 -0
  296. package/dist/styled-system/patterns/index.js +20 -0
  297. package/dist/styled-system/patterns/link-overlay.d.ts +20 -0
  298. package/dist/styled-system/patterns/link-overlay.js +24 -0
  299. package/dist/styled-system/patterns/spacer.d.ts +20 -0
  300. package/dist/styled-system/patterns/spacer.js +25 -0
  301. package/dist/styled-system/patterns/square.d.ts +20 -0
  302. package/dist/styled-system/patterns/square.js +24 -0
  303. package/dist/styled-system/patterns/stack.d.ts +23 -0
  304. package/dist/styled-system/patterns/stack.js +24 -0
  305. package/dist/styled-system/patterns/visually-hidden.d.ts +20 -0
  306. package/dist/styled-system/patterns/visually-hidden.js +18 -0
  307. package/dist/styled-system/patterns/vstack.d.ts +21 -0
  308. package/dist/styled-system/patterns/vstack.js +24 -0
  309. package/dist/styled-system/patterns/wrap.d.ts +24 -0
  310. package/dist/styled-system/patterns/wrap.js +25 -0
  311. package/dist/styled-system/recipes/content-header.d.ts +31 -0
  312. package/dist/styled-system/recipes/content-header.js +65 -0
  313. package/dist/styled-system/recipes/content-page.d.ts +34 -0
  314. package/dist/styled-system/recipes/content-page.js +43 -0
  315. package/dist/styled-system/recipes/create-recipe.js +82 -0
  316. package/dist/styled-system/recipes/index.d.ts +17 -0
  317. package/dist/styled-system/recipes/index.js +16 -0
  318. package/dist/styled-system/recipes/metric-block.d.ts +34 -0
  319. package/dist/styled-system/recipes/metric-block.js +76 -0
  320. package/dist/styled-system/recipes/product-list.d.ts +31 -0
  321. package/dist/styled-system/recipes/product-list.js +73 -0
  322. package/dist/styled-system/recipes/product-section.d.ts +31 -0
  323. package/dist/styled-system/recipes/product-section.js +49 -0
  324. package/dist/styled-system/recipes/product-settings-row.d.ts +34 -0
  325. package/dist/styled-system/recipes/product-settings-row.js +58 -0
  326. package/dist/styled-system/recipes/product-settings.d.ts +31 -0
  327. package/dist/styled-system/recipes/product-settings.js +57 -0
  328. package/dist/styled-system/recipes/product-status.d.ts +34 -0
  329. package/dist/styled-system/recipes/product-status.js +45 -0
  330. package/dist/styled-system/recipes/product-toolbar.d.ts +31 -0
  331. package/dist/styled-system/recipes/product-toolbar.js +41 -0
  332. package/dist/styled-system/recipes/product-workspace.d.ts +34 -0
  333. package/dist/styled-system/recipes/product-workspace.js +58 -0
  334. package/dist/styled-system/recipes/surface-metric.d.ts +38 -0
  335. package/dist/styled-system/recipes/surface-metric.js +63 -0
  336. package/dist/styled-system/recipes/surface-table.d.ts +34 -0
  337. package/dist/styled-system/recipes/surface-table.js +62 -0
  338. package/dist/styled-system/recipes/ui-badge.d.ts +31 -0
  339. package/dist/styled-system/recipes/ui-badge.js +38 -0
  340. package/dist/styled-system/recipes/ui-button.d.ts +32 -0
  341. package/dist/styled-system/recipes/ui-button.js +43 -0
  342. package/dist/styled-system/recipes/ui-input.d.ts +31 -0
  343. package/dist/styled-system/recipes/ui-input.js +49 -0
  344. package/dist/styled-system/recipes/ui-textarea.d.ts +31 -0
  345. package/dist/styled-system/recipes/ui-textarea.js +24 -0
  346. package/dist/styled-system/styles.css +1257 -0
  347. package/dist/styled-system/tokens/index.d.ts +9 -0
  348. package/dist/styled-system/tokens/index.js +268 -0
  349. package/dist/styled-system/tokens/tokens.d.ts +36 -0
  350. package/dist/styled-system/types/composition.d.ts +227 -0
  351. package/dist/styled-system/types/conditions.d.ts +236 -0
  352. package/dist/styled-system/types/csstype.d.ts +22570 -0
  353. package/dist/styled-system/types/index.d.ts +6 -0
  354. package/dist/styled-system/types/parts.d.ts +8 -0
  355. package/dist/styled-system/types/pattern.d.ts +78 -0
  356. package/dist/styled-system/types/prop-type.d.ts +223 -0
  357. package/dist/styled-system/types/recipe.d.ts +181 -0
  358. package/dist/styled-system/types/selectors.d.ts +59 -0
  359. package/dist/styled-system/types/static-css.d.ts +56 -0
  360. package/dist/styled-system/types/style-props.d.ts +8088 -0
  361. package/dist/styled-system/types/system-types.d.ts +151 -0
  362. package/dist/styles/aliases.css +49 -0
  363. package/dist/styles/compatibility.epilogue.css +384 -0
  364. package/dist/styles/compatibility.prelude.css +5513 -0
  365. package/dist/styles/conditional-states.css +28 -0
  366. package/dist/styles/conditional-utilities.css +22 -0
  367. package/dist/styles/recipes.css +1262 -0
  368. package/dist/types.d.ts +3 -3
  369. package/dist/utils.d.ts +1 -1
  370. package/dist/utils.js +1 -1
  371. package/package.json +38 -14
  372. package/styles-compatibility.json +12 -0
@@ -0,0 +1,195 @@
1
+ const rootKeys = new Set(['$schema', '$id', '$comment', 'title', 'description', 'type', 'properties', 'required', 'additionalProperties']);
2
+ const fieldKeys = new Set(['$id', '$comment', 'title', 'description', 'type', 'enum', 'const', 'default', 'minimum', 'maximum', 'exclusiveMinimum', 'exclusiveMaximum', 'multipleOf', 'minLength', 'maxLength', 'readOnly', 'writeOnly', 'deprecated', 'examples']);
3
+ const unsafeKeys = new Set(['__proto__', 'constructor', 'prototype']);
4
+ const pointer = (key) => `/${key.replaceAll('~', '~0').replaceAll('/', '~1')}`;
5
+ const record = (value) => value !== null && typeof value === 'object' && !Array.isArray(value) && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
6
+ const scalar = (value) => value === null || typeof value === 'string' || typeof value === 'boolean' || (typeof value === 'number' && Number.isFinite(value));
7
+ const same = (a, b) => a === b;
8
+ function matches(field, value) {
9
+ if (value === null)
10
+ return field.nullable;
11
+ if (field.type === 'enum')
12
+ return scalar(value);
13
+ if (field.type === 'integer')
14
+ return typeof value === 'number' && Number.isSafeInteger(value);
15
+ if (field.type === 'number')
16
+ return typeof value === 'number' && Number.isFinite(value);
17
+ return typeof value === field.type;
18
+ }
19
+ export function readSchemaForm(schema) {
20
+ const model = { fields: [], issues: [], additionalProperties: true };
21
+ const issue = (path, code) => { model.issues.push({ path, code }); };
22
+ if (!record(schema)) {
23
+ issue('', 'invalid-schema');
24
+ return model;
25
+ }
26
+ for (const key of Object.keys(schema))
27
+ if (!rootKeys.has(key))
28
+ issue(pointer(key), 'unsupported-schema');
29
+ if (schema['type'] !== undefined && schema['type'] !== 'object')
30
+ issue('/type', 'unsupported-schema');
31
+ if (schema['additionalProperties'] !== undefined && typeof schema['additionalProperties'] !== 'boolean')
32
+ issue('/additionalProperties', 'unsupported-schema');
33
+ model.additionalProperties = schema['additionalProperties'] !== false;
34
+ const properties = schema['properties'] === undefined ? {} : schema['properties'];
35
+ if (!record(properties) || Object.keys(properties).length > 256) {
36
+ issue('/properties', 'invalid-schema');
37
+ return model;
38
+ }
39
+ const required = schema['required'] === undefined ? [] : schema['required'];
40
+ if (!Array.isArray(required) || required.length > 256 || required.some((key) => typeof key !== 'string' || !Object.hasOwn(properties, key)))
41
+ issue('/required', 'invalid-schema');
42
+ const requiredKeys = new Set(Array.isArray(required) ? required : []);
43
+ for (const [key, raw] of Object.entries(properties)) {
44
+ const path = pointer(key);
45
+ if (unsafeKeys.has(key) || !record(raw)) {
46
+ issue(path, 'invalid-schema');
47
+ continue;
48
+ }
49
+ for (const keyword of Object.keys(raw))
50
+ if (!fieldKeys.has(keyword))
51
+ issue(`${path}${pointer(keyword)}`, 'unsupported-schema');
52
+ let type = raw['type'];
53
+ let nullable = false;
54
+ if (Array.isArray(type)) {
55
+ nullable = type.includes('null');
56
+ const nonNull = type.filter((item) => item !== 'null');
57
+ if (type.length !== 2 || nonNull.length !== 1)
58
+ issue(path, 'unsupported-schema');
59
+ type = nonNull[0];
60
+ }
61
+ const hasEnum = Object.hasOwn(raw, 'enum');
62
+ const hasConst = Object.hasOwn(raw, 'const');
63
+ const rawChoices = hasEnum ? raw['enum'] : hasConst ? [raw['const']] : undefined;
64
+ let choices;
65
+ if (rawChoices !== undefined) {
66
+ if (!Array.isArray(rawChoices) || rawChoices.length === 0 || rawChoices.length > 1000 || !rawChoices.every(scalar))
67
+ issue(path, 'invalid-schema');
68
+ else {
69
+ choices = [...rawChoices];
70
+ if (hasConst)
71
+ choices = choices.filter((item) => same(item, raw['const']));
72
+ if (!choices.length)
73
+ issue(path, 'invalid-schema');
74
+ }
75
+ }
76
+ else if (hasEnum)
77
+ issue(path, 'invalid-schema');
78
+ if (type === undefined)
79
+ type = choices ? 'enum' : 'string';
80
+ else if (type === 'enum') {
81
+ issue(path, 'invalid-schema');
82
+ continue;
83
+ }
84
+ if (!['string', 'number', 'integer', 'boolean', 'enum'].includes(String(type))) {
85
+ issue(path, 'unsupported-schema');
86
+ continue;
87
+ }
88
+ if (type === 'enum')
89
+ nullable = choices?.includes(null) ?? false;
90
+ const field = {
91
+ key, title: String(raw['title'] ?? key), description: String(raw['description'] ?? ''),
92
+ type: type, nullable, required: requiredKeys.has(key), readonly: raw['readOnly'] === true,
93
+ choices, hasDefault: Object.hasOwn(raw, 'default'), defaultValue: scalar(raw['default']) ? raw['default'] : undefined,
94
+ minimum: undefined, maximum: undefined, exclusiveMinimum: undefined, exclusiveMaximum: undefined,
95
+ multipleOf: undefined, minLength: undefined, maxLength: undefined,
96
+ };
97
+ for (const constraint of ['minimum', 'maximum', 'exclusiveMinimum', 'exclusiveMaximum', 'multipleOf', 'minLength', 'maxLength']) {
98
+ const value = raw[constraint];
99
+ if (value === undefined)
100
+ continue;
101
+ if (typeof value !== 'number' || !Number.isFinite(value)
102
+ || (constraint === 'multipleOf' && value <= 0)
103
+ || ((constraint === 'minLength' || constraint === 'maxLength') && (!Number.isSafeInteger(value) || value < 0)))
104
+ issue(`${path}/${constraint}`, 'invalid-schema');
105
+ else
106
+ field[constraint] = value;
107
+ }
108
+ if (choices?.some((choice) => !matches(field, choice)))
109
+ issue(path, 'invalid-schema');
110
+ if (field.hasDefault && (!scalar(raw['default']) || !matches(field, raw['default']) || (choices && !choices.some((choice) => same(choice, raw['default'])))))
111
+ issue(path, 'invalid-schema');
112
+ model.fields.push(field);
113
+ }
114
+ return model;
115
+ }
116
+ /** 只为不存在的键补默认值;显式 undefined 表示用户已清空,不重新灌回默认值。 */
117
+ export function schemaFormValues(model, value) {
118
+ const result = { ...value };
119
+ for (const field of model.fields)
120
+ if (!Object.hasOwn(value, field.key) && field.hasDefault)
121
+ result[field.key] = field.defaultValue;
122
+ return result;
123
+ }
124
+ export function parseSchemaNumber(raw) {
125
+ if (raw.trim() === '')
126
+ return undefined;
127
+ if (!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i.test(raw.trim()))
128
+ throw new Error('invalid-value');
129
+ const value = Number(raw);
130
+ if (!Number.isFinite(value))
131
+ throw new Error('invalid-value');
132
+ return value;
133
+ }
134
+ export function enumIndex(choices, value) {
135
+ const index = choices.findIndex((choice) => same(choice, value));
136
+ return index < 0 ? '' : String(index);
137
+ }
138
+ export function enumValue(choices, index) {
139
+ if (index === '')
140
+ return undefined;
141
+ if (!/^(0|[1-9]\d*)$/.test(index))
142
+ throw new Error('invalid-value');
143
+ const value = choices[Number(index)];
144
+ if (value === undefined)
145
+ throw new Error('invalid-value');
146
+ return value;
147
+ }
148
+ export function validateSchemaForm(model, value) {
149
+ const issues = [...model.issues];
150
+ if (!record(value))
151
+ return [...issues, { path: '', code: 'invalid-value' }];
152
+ for (const field of model.fields) {
153
+ const path = pointer(field.key), current = Object.hasOwn(value, field.key) ? value[field.key] : undefined;
154
+ const issue = (code) => { issues.push({ path, code }); };
155
+ if (current === undefined) {
156
+ if (field.required)
157
+ issue('required');
158
+ continue;
159
+ }
160
+ if (!matches(field, current)) {
161
+ issue('type');
162
+ continue;
163
+ }
164
+ if (field.choices && !field.choices.some((choice) => same(choice, current)))
165
+ issue('enum');
166
+ if (typeof current === 'number') {
167
+ if ((field.minimum !== undefined && current < field.minimum) || (field.exclusiveMinimum !== undefined && current <= field.exclusiveMinimum))
168
+ issue('minimum');
169
+ if ((field.maximum !== undefined && current > field.maximum) || (field.exclusiveMaximum !== undefined && current >= field.exclusiveMaximum))
170
+ issue('maximum');
171
+ if (field.multipleOf !== undefined) {
172
+ const quotient = current / field.multipleOf;
173
+ if (!Number.isFinite(quotient) || Math.abs(quotient - Math.round(quotient)) > Math.min(1e-8, Number.EPSILON * Math.max(1, Math.abs(quotient)) * 4))
174
+ issue('multipleOf');
175
+ }
176
+ }
177
+ if (typeof current === 'string') {
178
+ const length = Array.from(current).length;
179
+ if (field.minLength !== undefined && length < field.minLength)
180
+ issue('minLength');
181
+ if (field.maxLength !== undefined && length > field.maxLength)
182
+ issue('maxLength');
183
+ }
184
+ }
185
+ const keys = new Set(model.fields.map((field) => field.key));
186
+ for (const [key, current] of Object.entries(value)) {
187
+ if (unsafeKeys.has(key))
188
+ issues.push({ path: pointer(key), code: 'invalid-value' });
189
+ if (!model.additionalProperties && !keys.has(key) && current !== undefined)
190
+ issues.push({ path: pointer(key), code: 'additionalProperties' });
191
+ }
192
+ return issues;
193
+ }
194
+ // Reuse the hardened recursive form transport boundary, including accessor/symbol rejection.
195
+ export { schemaFormSnapshot } from '../json-schema-form-state.js';
@@ -0,0 +1,30 @@
1
+ import { type SchemaFormModel, type SchemaFormIssue } from './json-schema-form.js';
2
+ type Node = {
3
+ kind: 'object';
4
+ properties: Record<string, Node>;
5
+ required: Set<string>;
6
+ additional: boolean;
7
+ nullable: boolean;
8
+ } | {
9
+ kind: 'array';
10
+ item: Node;
11
+ min: number | undefined;
12
+ max: number | undefined;
13
+ nullable: boolean;
14
+ } | {
15
+ kind: 'scalar';
16
+ model: SchemaFormModel;
17
+ };
18
+ export interface RecursiveSchemaFormModel {
19
+ node: Node | undefined;
20
+ issues: SchemaFormIssue[];
21
+ }
22
+ export declare const schemaFormPointer: (path: readonly string[]) => string;
23
+ /** Compile bounded objects/arrays, delegating scalar assertions to the reviewed leaf validator.
24
+ * Unsupported assertions fail closed; this is deliberately not a complete JSON Schema engine.
25
+ * TypeBox's symbol annotations are not JSON assertion keywords and are not executed.
26
+ */
27
+ export declare function readRecursiveSchemaForm(schema: unknown): RecursiveSchemaFormModel;
28
+ /** Validate a detached JSON payload without defaults, coercion, cleaning or partial acceptance. */
29
+ export declare function validateRecursiveSchemaForm(model: RecursiveSchemaFormModel, value: unknown): SchemaFormIssue[];
30
+ export {};
@@ -0,0 +1,196 @@
1
+ import { readSchemaForm, validateSchemaForm } from './json-schema-form.js';
2
+ import { SCHEMA_FORM_LIMITS, schemaFormSnapshot } from '../json-schema-form-state.js';
3
+ const annotationKeys = ['$schema', '$id', '$comment', 'title', 'description', 'type', 'default', 'readOnly', 'writeOnly', 'deprecated', 'examples'];
4
+ const objectKeys = new Set([...annotationKeys, 'properties', 'required', 'additionalProperties']);
5
+ const arrayKeys = new Set([...annotationKeys, 'items', 'minItems', 'maxItems']);
6
+ const unsafe = new Set(['__proto__', 'prototype', 'constructor']);
7
+ export const schemaFormPointer = (path) => path.map(key => '/' + key.replaceAll('~', '~0').replaceAll('/', '~1')).join('');
8
+ function record(value) {
9
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
10
+ && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
11
+ }
12
+ function dataRecord(value) {
13
+ return record(value) && Object.keys(value).every(key => {
14
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
15
+ return descriptor !== undefined && 'value' in descriptor;
16
+ });
17
+ }
18
+ /** Compile bounded objects/arrays, delegating scalar assertions to the reviewed leaf validator.
19
+ * Unsupported assertions fail closed; this is deliberately not a complete JSON Schema engine.
20
+ * TypeBox's symbol annotations are not JSON assertion keywords and are not executed.
21
+ */
22
+ export function readRecursiveSchemaForm(schema) {
23
+ const issues = [];
24
+ const active = new Set();
25
+ let visited = 0;
26
+ const issue = (path, code) => {
27
+ if (issues.length < 128)
28
+ issues.push({ path, code });
29
+ };
30
+ function read(raw, path, depth, root = false) {
31
+ if (++visited > SCHEMA_FORM_LIMITS.nodes || depth > SCHEMA_FORM_LIMITS.depth || !dataRecord(raw) || active.has(raw)) {
32
+ issue(path, 'invalid-schema');
33
+ return;
34
+ }
35
+ active.add(raw);
36
+ try {
37
+ let type = raw['type'];
38
+ let nullable = false;
39
+ if (Array.isArray(type)) {
40
+ const concrete = type.filter(value => value !== 'null');
41
+ if (type.length !== 2 || concrete.length !== 1 || !type.includes('null')) {
42
+ issue(path, 'unsupported-schema');
43
+ return;
44
+ }
45
+ nullable = true;
46
+ type = concrete[0];
47
+ }
48
+ if (type === undefined && (root || Object.hasOwn(raw, 'properties')))
49
+ type = 'object';
50
+ if (root && type !== 'object') {
51
+ issue(path, 'unsupported-schema');
52
+ return;
53
+ }
54
+ for (const key of ['readOnly', 'writeOnly', 'deprecated']) {
55
+ if (raw[key] !== undefined && typeof raw[key] !== 'boolean')
56
+ issue(path + '/' + key, 'invalid-schema');
57
+ }
58
+ if (Object.hasOwn(raw, 'default')) {
59
+ try {
60
+ schemaFormSnapshot({ value: raw['default'] });
61
+ }
62
+ catch {
63
+ issue(path + '/default', 'invalid-schema');
64
+ }
65
+ }
66
+ if (type !== 'object' && type !== 'array') {
67
+ const model = readSchemaForm({ type: 'object', properties: { value: raw } });
68
+ for (const failure of model.issues)
69
+ issue(path + failure.path.replace(/^\/value(?=\/|$)/u, ''), failure.code);
70
+ return { kind: 'scalar', model };
71
+ }
72
+ const allowed = type === 'object' ? objectKeys : arrayKeys;
73
+ for (const key of Object.keys(raw))
74
+ if (!allowed.has(key))
75
+ issue(path + '/' + key, 'unsupported-schema');
76
+ if (type === 'object') {
77
+ const properties = raw['properties'] ?? {};
78
+ if (!dataRecord(properties) || Object.keys(properties).length > 256 || raw['properties'] === null) {
79
+ issue(path + '/properties', 'invalid-schema');
80
+ return;
81
+ }
82
+ const keys = raw['required'] ?? [];
83
+ if (!Array.isArray(keys) || keys.length > 256 || raw['required'] === null
84
+ || new Set(keys).size !== keys.length || keys.some(key => typeof key !== 'string' || !Object.hasOwn(properties, key))) {
85
+ issue(path + '/required', 'invalid-schema');
86
+ return;
87
+ }
88
+ if (raw['additionalProperties'] !== undefined && typeof raw['additionalProperties'] !== 'boolean') {
89
+ issue(path + '/additionalProperties', 'unsupported-schema');
90
+ }
91
+ const result = Object.create(null);
92
+ for (const [key, child] of Object.entries(properties)) {
93
+ const childPath = path + schemaFormPointer([key]);
94
+ if (unsafe.has(key)) {
95
+ issue(childPath, 'invalid-schema');
96
+ continue;
97
+ }
98
+ const node = read(child, childPath, depth + 1);
99
+ if (node)
100
+ result[key] = node;
101
+ }
102
+ return { kind: 'object', properties: result, required: new Set(keys), additional: raw['additionalProperties'] !== false, nullable };
103
+ }
104
+ const item = read(raw['items'], path + '/items', depth + 1);
105
+ const definition = raw;
106
+ function bound(key) {
107
+ const value = definition[key];
108
+ if (value === undefined)
109
+ return;
110
+ if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {
111
+ issue(path + '/' + key, 'invalid-schema');
112
+ return;
113
+ }
114
+ return value;
115
+ }
116
+ const min = bound('minItems'), max = bound('maxItems');
117
+ if (min !== undefined && max !== undefined && min > max)
118
+ issue(path, 'invalid-schema');
119
+ return item ? { kind: 'array', item, min, max, nullable } : undefined;
120
+ }
121
+ finally {
122
+ active.delete(raw);
123
+ }
124
+ }
125
+ let node;
126
+ try {
127
+ node = read(schema, '', 0, true);
128
+ }
129
+ catch {
130
+ issue('', 'invalid-schema');
131
+ }
132
+ return { node, issues };
133
+ }
134
+ /** Validate a detached JSON payload without defaults, coercion, cleaning or partial acceptance. */
135
+ export function validateRecursiveSchemaForm(model, value) {
136
+ if (model.issues.length || !model.node)
137
+ return model.issues.length ? [...model.issues] : [{ path: '', code: 'invalid-schema' }];
138
+ const issues = [];
139
+ const issue = (path, code) => {
140
+ if (issues.length < 128)
141
+ issues.push({ path, code });
142
+ };
143
+ let payload;
144
+ try {
145
+ payload = schemaFormSnapshot(value);
146
+ }
147
+ catch {
148
+ return [{ path: '', code: 'invalid-value' }];
149
+ }
150
+ let visited = 0;
151
+ function visit(node, current, path, required, depth) {
152
+ if (++visited > SCHEMA_FORM_LIMITS.nodes || depth > SCHEMA_FORM_LIMITS.depth) {
153
+ issue(path, 'invalid-value');
154
+ return;
155
+ }
156
+ if (current === undefined) {
157
+ if (required)
158
+ issue(path, 'required');
159
+ return;
160
+ }
161
+ if (node.kind === 'scalar') {
162
+ for (const failure of validateSchemaForm(node.model, { value: current }))
163
+ issue(path + failure.path.replace(/^\/value(?=\/|$)/u, ''), failure.code);
164
+ return;
165
+ }
166
+ if (current === null && node.nullable)
167
+ return;
168
+ if (node.kind === 'object') {
169
+ if (!record(current)) {
170
+ issue(path, 'type');
171
+ return;
172
+ }
173
+ for (const [key, child] of Object.entries(node.properties)) {
174
+ visit(child, Object.hasOwn(current, key) ? current[key] : undefined, path + schemaFormPointer([key]), node.required.has(key), depth + 1);
175
+ }
176
+ if (!node.additional)
177
+ for (const key of Object.keys(current)) {
178
+ if (!Object.hasOwn(node.properties, key))
179
+ issue(path + schemaFormPointer([key]), 'additionalProperties');
180
+ }
181
+ return;
182
+ }
183
+ if (!Array.isArray(current)) {
184
+ issue(path, 'type');
185
+ return;
186
+ }
187
+ if (node.min !== undefined && current.length < node.min)
188
+ issue(path, 'minItems');
189
+ if (node.max !== undefined && current.length > node.max)
190
+ issue(path, 'maxItems');
191
+ for (const [index, item] of current.entries())
192
+ visit(node.item, item, path + '/' + index, true, depth + 1);
193
+ }
194
+ visit(model.node, payload, '', true, 0);
195
+ return issues;
196
+ }
@@ -0,0 +1,12 @@
1
+ /** 有界、无动态代码执行的轻量公式解析器;不是完整 Excel 公式引擎。 */
2
+ export declare const FORMULA_LIMITS: Readonly<{
3
+ length: 2048;
4
+ tokens: 1024;
5
+ depth: 64;
6
+ work: 10000;
7
+ range: 10000;
8
+ }>;
9
+ export type FormulaErrorCode = '#VALUE!' | '#REF!' | '#NAME?' | '#DIV/0!' | '#NUM!' | '#CYCLE!' | '#LIMIT!';
10
+ export declare function evaluateFormula(raw: string, cells: Readonly<Record<string, string>>): number | string;
11
+ /** 文本导出不能把危险前缀当成外部电子表格公式;调用者仍需完成 CSV 引号转义。 */
12
+ export declare function safeSpreadsheetCsvText(value: string): string;
@@ -0,0 +1,245 @@
1
+ /** 有界、无动态代码执行的轻量公式解析器;不是完整 Excel 公式引擎。 */
2
+ export const FORMULA_LIMITS = Object.freeze({ length: 2048, tokens: 1024, depth: 64, work: 10000, range: 10000 });
3
+ class FormulaError extends Error {
4
+ code;
5
+ constructor(code) { super(code); this.code = code; }
6
+ }
7
+ function fail(code) { throw new FormulaError(code); }
8
+ function finite(value) { return Number.isFinite(value) ? value : fail('#NUM!'); }
9
+ function numeric(value) {
10
+ if (value === null)
11
+ return 0;
12
+ return typeof value === 'number' ? value : fail('#VALUE!');
13
+ }
14
+ const decimal = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i;
15
+ function address(key) {
16
+ const match = /^\$?([A-Z]+)\$?(\d+)$/i.exec(key);
17
+ if (!match?.[1] || !match[2])
18
+ return fail('#REF!');
19
+ let column = 0;
20
+ for (const char of match[1].toUpperCase()) {
21
+ column = column * 26 + char.charCodeAt(0) - 64;
22
+ if (column > 16384)
23
+ return fail('#REF!');
24
+ }
25
+ const row = Number(match[2]);
26
+ if (row < 1 || row > 1048576 || !Number.isSafeInteger(row))
27
+ return fail('#REF!');
28
+ return { column, row };
29
+ }
30
+ function columnName(column) {
31
+ let name = '';
32
+ while (column > 0) {
33
+ column--;
34
+ name = String.fromCharCode(65 + column % 26) + name;
35
+ column = Math.floor(column / 26);
36
+ }
37
+ return name;
38
+ }
39
+ class Evaluation {
40
+ work = 0;
41
+ depth = 0;
42
+ active = new Set();
43
+ cache = new Map();
44
+ cells;
45
+ constructor(cells) { this.cells = cells; }
46
+ tick() { if (++this.work > FORMULA_LIMITS.work)
47
+ fail('#LIMIT!'); }
48
+ bounded(fn) {
49
+ if (++this.depth > FORMULA_LIMITS.depth) {
50
+ this.depth--;
51
+ return fail('#LIMIT!');
52
+ }
53
+ try {
54
+ return fn();
55
+ }
56
+ finally {
57
+ this.depth--;
58
+ }
59
+ }
60
+ cell(key) {
61
+ this.tick();
62
+ const parsed = address(key);
63
+ const normalized = `${columnName(parsed.column)}${parsed.row}`;
64
+ if (this.active.has(normalized))
65
+ return fail('#CYCLE!');
66
+ if (this.cache.has(normalized))
67
+ return this.cache.get(normalized) ?? null;
68
+ const raw = Object.hasOwn(this.cells, normalized) ? this.cells[normalized] : '';
69
+ if (typeof raw !== 'string')
70
+ return fail('#VALUE!');
71
+ this.active.add(normalized);
72
+ try {
73
+ const trimmed = raw.trim();
74
+ const value = raw.startsWith('=')
75
+ ? new Parser(raw.slice(1), this).parse()
76
+ : trimmed === '' ? null : decimal.test(trimmed) ? finite(Number(trimmed)) : raw;
77
+ this.cache.set(normalized, value);
78
+ return value;
79
+ }
80
+ finally {
81
+ this.active.delete(normalized);
82
+ }
83
+ }
84
+ range(start, end) {
85
+ const a = address(start);
86
+ const b = address(end);
87
+ const left = Math.min(a.column, b.column), right = Math.max(a.column, b.column);
88
+ const top = Math.min(a.row, b.row), bottom = Math.max(a.row, b.row);
89
+ if ((right - left + 1) * (bottom - top + 1) > FORMULA_LIMITS.range)
90
+ return fail('#LIMIT!');
91
+ const values = [];
92
+ for (let row = top; row <= bottom; row++) {
93
+ for (let column = left; column <= right; column++)
94
+ values.push(this.cell(`${columnName(column)}${row}`));
95
+ }
96
+ return values;
97
+ }
98
+ }
99
+ class Parser {
100
+ tokens = [];
101
+ position = 0;
102
+ context;
103
+ constructor(source, context) {
104
+ this.context = context;
105
+ if (source.length + 1 > FORMULA_LIMITS.length)
106
+ fail('#LIMIT!');
107
+ let rest = source;
108
+ while (rest.length) {
109
+ rest = rest.trimStart();
110
+ if (!rest)
111
+ break;
112
+ context.tick();
113
+ if (this.tokens.length >= FORMULA_LIMITS.tokens)
114
+ fail('#LIMIT!');
115
+ const number = /^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?/i.exec(rest)?.[0];
116
+ const cell = /^\$?[A-Z]+\$?\d+/i.exec(rest)?.[0];
117
+ const name = /^[A-Z_][A-Z_0-9]*/i.exec(rest)?.[0];
118
+ let token;
119
+ if (number)
120
+ token = { kind: 'number', text: number };
121
+ else if (cell)
122
+ token = { kind: 'cell', text: cell.toUpperCase() };
123
+ else if (name)
124
+ token = { kind: 'name', text: name.toUpperCase() };
125
+ else if (/^[+\-*/(),:]/.test(rest))
126
+ token = { kind: 'symbol', text: rest[0] ?? '' };
127
+ else
128
+ return fail('#VALUE!');
129
+ this.tokens.push(token);
130
+ rest = rest.slice(token.text.length);
131
+ }
132
+ this.tokens.push({ kind: 'end', text: '' });
133
+ }
134
+ peek() { return this.tokens[this.position] ?? { kind: 'end', text: '' }; }
135
+ take() { this.context.tick(); const token = this.peek(); this.position++; return token; }
136
+ expect(text) { if (this.take().text !== text)
137
+ fail('#VALUE!'); }
138
+ parse() {
139
+ return this.context.bounded(() => {
140
+ const result = this.expression();
141
+ if (this.peek().kind !== 'end')
142
+ return fail('#VALUE!');
143
+ return result;
144
+ });
145
+ }
146
+ expression() {
147
+ let value = this.product();
148
+ while (this.peek().text === '+' || this.peek().text === '-') {
149
+ const op = this.take().text;
150
+ const right = numeric(this.product()), left = numeric(value);
151
+ value = finite(op === '+' ? left + right : left - right);
152
+ }
153
+ return value;
154
+ }
155
+ product() {
156
+ let value = this.unary();
157
+ while (this.peek().text === '*' || this.peek().text === '/') {
158
+ const op = this.take().text;
159
+ const right = numeric(this.unary()), left = numeric(value);
160
+ if (op === '/' && right === 0)
161
+ return fail('#DIV/0!');
162
+ value = finite(op === '*' ? left * right : left / right);
163
+ }
164
+ return value;
165
+ }
166
+ unary() {
167
+ if (this.peek().text === '+' || this.peek().text === '-') {
168
+ const negative = this.take().text === '-';
169
+ return this.context.bounded(() => finite(numeric(this.unary()) * (negative ? -1 : 1)));
170
+ }
171
+ return this.primary();
172
+ }
173
+ primary() {
174
+ const token = this.take();
175
+ if (token.kind === 'number')
176
+ return finite(Number(token.text));
177
+ if (token.kind === 'cell')
178
+ return this.context.cell(token.text);
179
+ if (token.text === '(')
180
+ return this.context.bounded(() => {
181
+ const value = this.expression();
182
+ this.expect(')');
183
+ return value;
184
+ });
185
+ if (token.kind === 'name')
186
+ return this.context.bounded(() => this.aggregate(token.text));
187
+ return fail('#VALUE!');
188
+ }
189
+ aggregate(name) {
190
+ if (!['SUM', 'AVG', 'AVERAGE', 'COUNT', 'MIN', 'MAX'].includes(name))
191
+ return fail('#NAME?');
192
+ this.expect('(');
193
+ const values = [];
194
+ if (this.peek().text !== ')') {
195
+ while (true) {
196
+ if (this.peek().kind === 'cell' && this.tokens[this.position + 1]?.text === ':') {
197
+ const start = this.take().text;
198
+ this.expect(':');
199
+ const end = this.take();
200
+ if (end.kind !== 'cell')
201
+ return fail('#REF!');
202
+ for (const value of this.context.range(start, end.text))
203
+ if (typeof value === 'number')
204
+ values.push(value);
205
+ }
206
+ else {
207
+ const value = this.expression();
208
+ if (typeof value === 'number')
209
+ values.push(value);
210
+ }
211
+ if (this.peek().text !== ',')
212
+ break;
213
+ this.take();
214
+ }
215
+ }
216
+ this.expect(')');
217
+ if (name === 'COUNT')
218
+ return values.length;
219
+ if (name === 'MIN' || name === 'MAX') {
220
+ if (!values.length)
221
+ return 0;
222
+ return values.reduce((a, b) => name === 'MIN' ? Math.min(a, b) : Math.max(a, b));
223
+ }
224
+ const sum = finite(values.reduce((a, b) => finite(a + b), 0));
225
+ if (name === 'SUM')
226
+ return sum;
227
+ return values.length ? finite(sum / values.length) : fail('#DIV/0!');
228
+ }
229
+ }
230
+ export function evaluateFormula(raw, cells) {
231
+ if (!raw.startsWith('='))
232
+ return raw;
233
+ try {
234
+ return new Parser(raw.slice(1), new Evaluation(cells)).parse() ?? 0;
235
+ }
236
+ catch (error) {
237
+ if (error instanceof FormulaError)
238
+ return error.code;
239
+ throw error;
240
+ }
241
+ }
242
+ /** 文本导出不能把危险前缀当成外部电子表格公式;调用者仍需完成 CSV 引号转义。 */
243
+ export function safeSpreadsheetCsvText(value) {
244
+ return /^[\s\uFEFF]*[=+\-@]/u.test(value) || /^[\t\r\n]/.test(value) ? `'${value}` : value;
245
+ }