@stonecrop/aform 0.31.0 → 0.33.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 (92) hide show
  1. package/dist/aform.js +3024 -2256
  2. package/dist/aform.js.map +1 -1
  3. package/dist/assets/index.css +1170 -1
  4. package/dist/src/components/AForm.vue.d.ts +20 -0
  5. package/dist/src/components/AForm.vue.d.ts.map +1 -0
  6. package/dist/src/components/AFormLoading.vue.d.ts +14 -0
  7. package/dist/src/components/AFormLoading.vue.d.ts.map +1 -0
  8. package/dist/src/components/base/CollapseButton.vue.d.ts +7 -0
  9. package/dist/src/components/base/CollapseButton.vue.d.ts.map +1 -0
  10. package/dist/src/components/base/ExpandButton.vue.d.ts +7 -0
  11. package/dist/src/components/base/ExpandButton.vue.d.ts.map +1 -0
  12. package/dist/src/components/form/ABadge.vue.d.ts +14 -0
  13. package/dist/src/components/form/ABadge.vue.d.ts.map +1 -0
  14. package/dist/src/components/form/ACheckbox.vue.d.ts +15 -0
  15. package/dist/src/components/form/ACheckbox.vue.d.ts.map +1 -0
  16. package/dist/src/components/form/ACurrencyInput.vue.d.ts +20 -0
  17. package/dist/src/components/form/ACurrencyInput.vue.d.ts.map +1 -0
  18. package/dist/src/components/form/ADate.vue.d.ts +14 -0
  19. package/dist/src/components/form/ADate.vue.d.ts.map +1 -0
  20. package/dist/src/components/form/ADatePicker.vue.d.ts +28 -0
  21. package/dist/src/components/form/ADatePicker.vue.d.ts.map +1 -0
  22. package/dist/src/components/form/ADateRange.vue.d.ts +18 -0
  23. package/dist/src/components/form/ADateRange.vue.d.ts.map +1 -0
  24. package/dist/src/components/form/ADateSelection.vue.d.ts +52 -0
  25. package/dist/src/components/form/ADateSelection.vue.d.ts.map +1 -0
  26. package/dist/src/components/form/ADateTime.vue.d.ts +17 -0
  27. package/dist/src/components/form/ADateTime.vue.d.ts.map +1 -0
  28. package/dist/src/components/form/ADateTimeInput.vue.d.ts +30 -0
  29. package/dist/src/components/form/ADateTimeInput.vue.d.ts.map +1 -0
  30. package/dist/src/components/form/ADropdown.vue.d.ts +20 -0
  31. package/dist/src/components/form/ADropdown.vue.d.ts.map +1 -0
  32. package/dist/src/components/form/ADuration.vue.d.ts +18 -0
  33. package/dist/src/components/form/ADuration.vue.d.ts.map +1 -0
  34. package/dist/src/components/form/AFieldset.vue.d.ts +28 -0
  35. package/dist/src/components/form/AFieldset.vue.d.ts.map +1 -0
  36. package/dist/src/components/form/AFileAttach.vue.d.ts +5 -0
  37. package/dist/src/components/form/AFileAttach.vue.d.ts.map +1 -0
  38. package/dist/src/components/form/AFormLink.vue.d.ts +40 -0
  39. package/dist/src/components/form/AFormLink.vue.d.ts.map +1 -0
  40. package/dist/src/components/form/ANumericInput.vue.d.ts +14 -0
  41. package/dist/src/components/form/ANumericInput.vue.d.ts.map +1 -0
  42. package/dist/src/components/form/AQuantityInput.vue.d.ts +20 -0
  43. package/dist/src/components/form/AQuantityInput.vue.d.ts.map +1 -0
  44. package/dist/src/components/form/ASegmentedControl.vue.d.ts +23 -0
  45. package/dist/src/components/form/ASegmentedControl.vue.d.ts.map +1 -0
  46. package/dist/src/components/form/ATextInput.vue.d.ts +14 -0
  47. package/dist/src/components/form/ATextInput.vue.d.ts.map +1 -0
  48. package/dist/src/components/form/ATextboxInput.vue.d.ts +21 -0
  49. package/dist/src/components/form/ATextboxInput.vue.d.ts.map +1 -0
  50. package/dist/src/components/utilities/Login.vue.d.ts +14 -0
  51. package/dist/src/components/utilities/Login.vue.d.ts.map +1 -0
  52. package/dist/{tsdoc-metadata.json → src/tsdoc-metadata.json} +1 -1
  53. package/package.json +35 -30
  54. package/dist/aform.d.ts +0 -441
  55. package/dist/aform.tsbuildinfo +0 -1
  56. package/dist/src/directives/mask.js +0 -107
  57. package/dist/src/index.js +0 -58
  58. package/dist/src/types/index.js +0 -0
  59. package/dist/src/utils/badge.js +0 -71
  60. package/dist/src/utils/columns.js +0 -33
  61. package/dist/src/utils/deserialize.js +0 -20
  62. package/src/components/AForm.vue +0 -314
  63. package/src/components/AFormLoading.vue +0 -76
  64. package/src/components/base/CollapseButton.vue +0 -36
  65. package/src/components/base/ExpandButton.vue +0 -34
  66. package/src/components/form/ABadge.vue +0 -135
  67. package/src/components/form/ACheckbox.vue +0 -62
  68. package/src/components/form/ACurrencyInput.vue +0 -357
  69. package/src/components/form/ADate.vue +0 -93
  70. package/src/components/form/ADatePicker.vue +0 -470
  71. package/src/components/form/ADateRange.vue +0 -133
  72. package/src/components/form/ADateSelection.vue +0 -174
  73. package/src/components/form/ADateTime.vue +0 -149
  74. package/src/components/form/ADateTimeInput.vue +0 -299
  75. package/src/components/form/ADropdown.vue +0 -222
  76. package/src/components/form/ADuration.vue +0 -124
  77. package/src/components/form/AFieldset.vue +0 -72
  78. package/src/components/form/AFileAttach.vue +0 -97
  79. package/src/components/form/AFormLink.vue +0 -368
  80. package/src/components/form/ANumericInput.vue +0 -32
  81. package/src/components/form/AQuantityInput.vue +0 -349
  82. package/src/components/form/ASegmentedControl.vue +0 -342
  83. package/src/components/form/ATextInput.vue +0 -40
  84. package/src/components/form/ATextboxInput.vue +0 -66
  85. package/src/components/utilities/Login.vue +0 -189
  86. package/src/directives/mask.ts +0 -122
  87. package/src/index.ts +0 -92
  88. package/src/shims-vue.d.ts +0 -5
  89. package/src/types/index.ts +0 -333
  90. package/src/utils/badge.ts +0 -94
  91. package/src/utils/columns.ts +0 -38
  92. package/src/utils/deserialize.ts +0 -20
@@ -1,333 +0,0 @@
1
- import type {
2
- ColumnSchema,
3
- FieldValidation,
4
- GetRecordsOptions,
5
- GetRecordsResult,
6
- TableViewConfig,
7
- ValueField,
8
- } from '@stonecrop/schema'
9
-
10
- // ---------------------------------------------------------------------------
11
- // InteractionMode — canonical home is @stonecrop/schema
12
- // ---------------------------------------------------------------------------
13
-
14
- /**
15
- * Controls the level of user interaction for a field, container, or table.
16
- * `'edit'` — interactive; `'read'` — non-interactive with form chrome;
17
- * `'display'` — non-interactive plain-text rendering.
18
- * @public
19
- */
20
- export type { InteractionMode } from '@stonecrop/schema'
21
-
22
- // ---------------------------------------------------------------------------
23
- // ResolvedField — the output-space type that AForm consumes
24
- //
25
- // Usually produced by resolveSchema() from an authoring-space DoctypeField[].
26
- // It may also be hand-authored, for view chrome that has no backing doctype
27
- // (see Desktop.vue's doctype list) — annotate such literals with `satisfies
28
- // ResolvedTable`/`satisfies ResolvedField` so they stay checked.
29
- //
30
- // Authoring space and output space are NOT interchangeable. The trap is tables:
31
- // an authoring TableField carries its columns under `columns`, while resolveSchema
32
- // renames that key to `schema` (registry.ts) because `schema` is the ATable prop
33
- // that runs schemaToColumns(). Hand-authoring `columns` here — or feeding an
34
- // authoring-space field straight to AForm — produces a field AForm does not
35
- // recognise as a table.
36
- // ---------------------------------------------------------------------------
37
-
38
- /**
39
- * A resolved scalar field. Derived from ValueField with `cardinality` omitted
40
- * (consumed by resolveSchema) and an optional `doctype` added for unresolved Link fields.
41
- * @public
42
- */
43
- export type ResolvedScalar = Omit<ValueField, 'cardinality'> & {
44
- /** Doctype slug for unresolved Link fields — added by resolveSchema when AFormLink is available */
45
- doctype?: string
46
- }
47
-
48
- /**
49
- * A resolved Link field with cardinality `one` or `atMostOne` — embedded as a nested form.
50
- * @public
51
- */
52
- export interface ResolvedLink {
53
- /** Discriminator */
54
- kind: 'link'
55
- /** Field identifier */
56
- fieldname: string
57
- /** Component to render; defaults to `'AForm'` */
58
- component: string
59
- /** Human-readable label */
60
- label?: string
61
- /** Interaction mode */
62
- mode?: import('@stonecrop/schema').InteractionMode
63
- /** Resolved child fields */
64
- schema: ResolvedField[]
65
- /** Preserved from the original ValueField */
66
- required?: boolean
67
- /** Preserved from the original ValueField */
68
- readOnly?: boolean
69
- /** Preserved from the original ValueField */
70
- hidden?: boolean
71
- /** Preserved from the original ValueField */
72
- default?: unknown
73
- /** Preserved from the original ValueField */
74
- validation?: FieldValidation
75
- }
76
-
77
- /**
78
- * A resolved table — either from a Link with `noneOrMany`/`atLeastOne` cardinality,
79
- * or from an inline TableField. ATable receives columns via `:schema` (ColumnSchema[])
80
- * and row data via `:rows` from formData at render time.
81
- *
82
- * Note the key rename: an authoring `TableField` declares its columns under `columns`;
83
- * `resolveSchema` moves them to `schema` here, because `schema` is the ATable prop that
84
- * runs `schemaToColumns()` (ATable's own `columns` prop means already-converted
85
- * `TableColumn[]`). A hand-authored table must therefore use `schema`, not `columns`.
86
- *
87
- * Rows are never part of the schema. AForm sources them from the data model at
88
- * `dataModel[fieldname]`, so a `rows` key placed on this object is ignored.
89
- * @public
90
- */
91
- export interface ResolvedTable {
92
- /** Discriminator */
93
- kind: 'table'
94
- /** Field identifier */
95
- fieldname: string
96
- /** Component to render; defaults to `'ATable'` */
97
- component: string
98
- /** Human-readable label */
99
- label?: string
100
- /** Interaction mode for all cells */
101
- mode?: import('@stonecrop/schema').InteractionMode
102
- /** Column definitions — passed to ATable's `:schema` prop */
103
- schema: ColumnSchema[]
104
- /** View configuration — always present; defaults to `{ view: 'list' }` */
105
- config: TableViewConfig
106
- /** Preserved from the original ValueField or TableField */
107
- required?: boolean
108
- /** Preserved from the original ValueField or TableField */
109
- readOnly?: boolean
110
- /** Preserved from the original ValueField or TableField */
111
- hidden?: boolean
112
- /** Preserved from the original ValueField or TableField */
113
- default?: unknown
114
- /** Preserved from the original ValueField or TableField */
115
- validation?: FieldValidation
116
- /** When set, ATable fetches list pages through this callback (server paging). */
117
- getRecords?: (options?: GetRecordsOptions) => Promise<GetRecordsResult>
118
- /** When this changes, ATable refetches from offset 0. */
119
- sourceKey?: string
120
- }
121
-
122
- /**
123
- * A resolved fieldset — groups child fields inside an AFieldset component.
124
- * @public
125
- */
126
- export interface ResolvedFieldset {
127
- /** Discriminator */
128
- kind: 'fieldset'
129
- /** Field identifier */
130
- fieldname: string
131
- /** Component to render; defaults to `'AFieldset'` */
132
- component?: string
133
- /** Human-readable label for the legend */
134
- label?: string
135
- /** Whether the fieldset can be collapsed */
136
- collapsible?: boolean
137
- /** Interaction mode for all children */
138
- mode?: import('@stonecrop/schema').InteractionMode
139
- /** Resolved child fields */
140
- schema: ResolvedField[]
141
- }
142
-
143
- /**
144
- * The discriminated union of all resolved field types — what AForm consumes,
145
- * usually after `resolveSchema()` has transformed the authoring `DoctypeField[]`,
146
- * but also valid hand-authored for view chrome with no backing doctype.
147
- * Narrowed by `kind`: `'field'` | `'link'` | `'table'` | `'fieldset'`.
148
- *
149
- * `kind` is required — AForm dispatches on it alone and does not infer a field's
150
- * type from its structure.
151
- * @public
152
- */
153
- export type ResolvedField = ResolvedScalar | ResolvedLink | ResolvedTable | ResolvedFieldset
154
-
155
- // ---------------------------------------------------------------------------
156
- // Utility types
157
- // ---------------------------------------------------------------------------
158
-
159
- /**
160
- * Defined props for AForm components
161
- * @public
162
- */
163
- export type ComponentProps = {
164
- /**
165
- * The schema object to pass to the component
166
- * @public
167
- */
168
- schema?: ResolvedField
169
-
170
- /**
171
- * The label to display in the component
172
- * @public
173
- */
174
- label?: string
175
-
176
- // TODO: add docstring
177
- selectRange?: boolean
178
-
179
- /**
180
- * The mask to apply to inputs inside the component. Accepts either a plain
181
- * mask string (e.g. `"(###) ###-####"`) or a stringified arrow function that
182
- * receives `locale` and returns a mask string
183
- * (e.g. `"(locale) => locale === 'en-US' ? '(###) ###-####' : '####-######'"`).
184
- * @public
185
- */
186
- mask?: string
187
-
188
- /**
189
- * Indicate whether input is required for text and/or select elements inside the component
190
- * @public
191
- */
192
- required?: boolean
193
-
194
- /**
195
- * The rendering mode for the component
196
- * @public
197
- */
198
- mode?: import('@stonecrop/schema').InteractionMode
199
-
200
- /**
201
- * Set a unique identifier for elements inside the component
202
- * @public
203
- */
204
- uuid?: string
205
-
206
- /**
207
- * Validation options for elements inside the component
208
- * @public
209
- */
210
- validation?: {
211
- /**
212
- * The error message to display when validation fails
213
- * @public
214
- */
215
- errorMessage: string
216
-
217
- [key: string]: any
218
- }
219
-
220
- /**
221
- * Inline validation error messages to display on this field. Fed by the host
222
- * (e.g. mapped from the core validation store) — the renderer stays dumb and just
223
- * shows what it is given. Takes precedence over the static `validation.errorMessage`.
224
- * @public
225
- */
226
- errors?: string[]
227
- }
228
-
229
- /**
230
- * The value shape for AFormLink — a linked document reference with optional display text
231
- * @public
232
- */
233
- export interface AFormLinkValue {
234
- /** The FK/linked document ID. `id: 0` is a valid ID. */
235
- id: string | number
236
- /** Display text shown in the input. Falls back to `String(id)` if omitted. */
237
- displayText?: string
238
- /** Additional properties passed through to the underlying input component */
239
- [extra: string]: any
240
- }
241
-
242
- /**
243
- * What AFormLink accepts as its `v-model`.
244
- *
245
- * Wider than {@link AFormLinkValue} because a link is as often bound straight to its FK column as
246
- * to a resolved reference: a record loaded from the DB carries the raw scalar, and a parent bound
247
- * to that column coerces every update it receives back to a scalar. The component reads through
248
- * `linkId`/`linkDisplayText`/`asLinkValue`, so all three shapes render and resolve identically.
249
- *
250
- * Emitting is narrower — AFormLink always writes back an {@link AFormLinkValue}.
251
- * @public
252
- */
253
- export type AFormLinkModelValue = AFormLinkValue | string | number
254
-
255
- /**
256
- * Navigation contract for AFormLink. Provide via `provide('aformLinkNavigator', ...)` in the app plugin.
257
- * @public
258
- */
259
- export interface AFormLinkNavigator {
260
- /** Navigate to the linked document. Implementation is app-defined. */
261
- navigate(doctype: string, id: string | number): void
262
- }
263
-
264
- /**
265
- * The value shape for AQuantityInput — a quantity paired with its unit of measure, plus the
266
- * derived stock-equivalent quantity/UOM. `conversionFactor` is carried on the value so it
267
- * round-trips with the record even though it is never shown in the UI.
268
- * @public
269
- */
270
- export interface QuantityValue {
271
- /** The entered quantity, in `uom` units */
272
- qty: number
273
- /** Unit of measure the user entered `qty` in */
274
- uom: string
275
- /** `qty` converted into `stockUom` units — `qty * conversionFactor` */
276
- stockQty: number
277
- /** The item's base/stock unit of measure — fixed, not user-editable */
278
- stockUom: string
279
- /** Multiplier from `uom` to `stockUom` — hidden from the UI, drives `stockQty` */
280
- conversionFactor: number
281
- }
282
-
283
- /**
284
- * Type-specific configuration for AQuantityInput, passed via the field's `options` property.
285
- * @public
286
- */
287
- export interface QuantityOptions {
288
- /** Dropdown choices for the `uom` field */
289
- uoms?: string[]
290
- /** The item's base/stock unit of measure — fixed, not user-editable */
291
- stockUom?: string
292
- /** Conversion factor lookup for each non-stock UOM, relative to `stockUom` (which is implicitly `1`) */
293
- conversionFactors?: Record<string, number>
294
- }
295
-
296
- /**
297
- * The value shape for ACurrencyInput — an amount paired with its currency (an
298
- * {@link AFormLinkValue} FK reference), plus the derived base-currency-equivalent amount.
299
- * `exchangeRate` is carried on the value so it round-trips with the record even though it is
300
- * never directly edited by the user.
301
- * @public
302
- */
303
- export interface CurrencyValue {
304
- /** The entered amount, in `currency` units */
305
- amount: number
306
- /** FK reference to the Currency doctype the user entered `amount` in */
307
- currency: AFormLinkValue
308
- /** `amount` converted into `baseCurrency` units — `amount * exchangeRate` */
309
- baseAmount: number
310
- /** The record's base currency — fixed, not user-editable */
311
- baseCurrency: AFormLinkValue
312
- /** Multiplier from `currency` to `baseCurrency` — hidden from the UI, drives `baseAmount` */
313
- exchangeRate: number
314
- }
315
-
316
- /**
317
- * Type-specific configuration for ACurrencyInput, passed via the field's `options` property.
318
- * @public
319
- */
320
- export interface CurrencyOptions {
321
- /** Currency doctype name, used for FK resolution via `aformLinkResolver`. The currency picker is embedded, so it renders no navigate button. */
322
- doctype?: string
323
- /** The record's base currency — fixed, not user-editable. A bare id resolves to displayText via `aformLinkResolver`. */
324
- baseCurrency?: AFormLinkValue | string
325
- /** Exchange rate lookup for each non-base currency id, relative to `baseCurrency` (which is implicitly `1`) */
326
- exchangeRates?: Record<string, number>
327
- /** Decimal places to round the derived `baseAmount` to — the base currency's scale (JPY carries 0, most carry 2, KWD 3). Applies only to `baseAmount`; the entered `amount` is left as typed. Omit to round only enough to shed binary floating-point noise, which never discards a digit the rate actually produced. A non-integer or out-of-range value falls back to that default. */
328
- precision?: number
329
- /** Search function backing the `currency` autocomplete dropdown — see AFormLink's `filterFunction` */
330
- filterFunction?: string | ((search: string) => AFormLinkValue[] | Promise<AFormLinkValue[]>)
331
- /** Whether `filterFunction` results should show a loading state — see AFormLink's `isAsync` */
332
- isAsync?: boolean
333
- }
@@ -1,94 +0,0 @@
1
- import type { BadgeDescriptor, FieldOptions } from '@stonecrop/schema'
2
- import { isBadgeDescriptor, lookupBadge } from '@stonecrop/schema'
3
-
4
- import { deserializeFunction } from './deserialize'
5
-
6
- /**
7
- * Row context passed to badge `format` functions in form fields.
8
- * @public
9
- */
10
- export type BadgeFormatContext = {
11
- record?: Record<string, unknown>
12
- row?: Record<string, unknown>
13
- }
14
-
15
- /**
16
- * Badge-aware field `format` function signature.
17
- * @public
18
- */
19
- export type BadgeFormatFn = (value: unknown, context: BadgeFormatContext) => string | BadgeDescriptor
20
-
21
- /**
22
- * Resolve a field value to a badge descriptor using format (if present) then options map.
23
- * @public
24
- */
25
- export function resolveFieldBadge(
26
- value: unknown,
27
- options: FieldOptions | undefined,
28
- format: string | BadgeFormatFn | undefined,
29
- context: BadgeFormatContext = {}
30
- ): BadgeDescriptor | undefined {
31
- if (format) {
32
- let formatted: unknown
33
- if (typeof format === 'function') {
34
- formatted = format(value, context)
35
- } else {
36
- const formatFn = deserializeFunction<BadgeFormatFn>(format)
37
- formatted = formatFn(value, context)
38
- }
39
- if (isBadgeDescriptor(formatted)) {
40
- const label = formatted.label.trim()
41
- return label ? formatted : undefined
42
- }
43
- if (typeof formatted === 'string' && formatted !== '') {
44
- return lookupBadge(options, formatted) ?? { label: formatted, variant: 'neutral' }
45
- }
46
- }
47
-
48
- const key = badgeLookupKey(value)
49
- if (key === undefined) return undefined
50
- return lookupBadge(options, key)
51
- }
52
-
53
- /**
54
- * Stored choice value as an options-map key. Only primitives can match a declared choice, so
55
- * anything else yields undefined rather than the '[object Object]' that String() would produce.
56
- */
57
- function badgeLookupKey(value: unknown): string | undefined {
58
- switch (typeof value) {
59
- case 'string':
60
- return value === '' ? undefined : value
61
- case 'number':
62
- case 'boolean':
63
- case 'bigint':
64
- return String(value)
65
- default:
66
- return undefined
67
- }
68
- }
69
-
70
- const BADGE_VARIANTS = new Set<string>(['neutral', 'success', 'warning', 'danger', 'brand'])
71
-
72
- /**
73
- * CSS custom properties for input-accent styling on a native input.
74
- * @public
75
- */
76
- export function badgeInputAccentStyle(descriptor: BadgeDescriptor | undefined): Record<string, string> | undefined {
77
- if (!descriptor?.label?.trim()) return undefined
78
- const variant = descriptor.variant ?? 'neutral'
79
- if (descriptor.color) {
80
- return {
81
- borderLeftWidth: '4px',
82
- borderLeftStyle: 'solid',
83
- borderLeftColor: descriptor.color,
84
- paddingLeft: 'calc(1ch - 4px)',
85
- }
86
- }
87
- if (!BADGE_VARIANTS.has(variant)) return undefined
88
- return {
89
- borderLeftWidth: '4px',
90
- borderLeftStyle: 'solid',
91
- borderLeftColor: `var(--sc-badge-${variant}-accent)`,
92
- paddingLeft: 'calc(1ch - 4px)',
93
- }
94
- }
@@ -1,38 +0,0 @@
1
- import type { ColumnSchema } from '@stonecrop/schema'
2
-
3
- import type { ResolvedField } from '../types'
4
-
5
- /**
6
- * The resolved fields that can be columns in a list or table view, in declaration order.
7
- *
8
- * A cell renders one value, so only `kind: 'field'` qualifies. The other three kinds are
9
- * containers: a `fieldset` groups fields for layout and has no value of its own, while a `link`
10
- * and a `table` hold a nested record and an array of them. Neither has a `cellComponent`, so a
11
- * container reaching `ACell` falls through to plain-text rendering and stringifies its children —
12
- * no error and no log, just a wrong column.
13
- *
14
- * A fieldset's *children* are real columns, so it is flattened rather than dropped; losing them is
15
- * the same silent defect in the other direction.
16
- *
17
- * One definition, called by both consumers: `Registry.buildTableConfig` (a child table's columns,
18
- * from its target's resolved schema) and Desktop's records list. Re-deriving it at either call
19
- * site produced exactly one of the two failures above at each.
20
- *
21
- * @param fields - resolved fields, as produced by `resolveSchema`
22
- * @returns column definitions, with the `kind` discriminator stripped
23
- * @public
24
- */
25
- export function resolvedFieldsToColumns(fields: readonly ResolvedField[]): ColumnSchema[] {
26
- const columns: ColumnSchema[] = []
27
-
28
- for (const field of fields) {
29
- if (field.kind === 'fieldset') {
30
- columns.push(...resolvedFieldsToColumns(field.schema))
31
- } else if (field.kind === 'field') {
32
- const { kind: _kind, ...column } = field
33
- columns.push(column)
34
- }
35
- }
36
-
37
- return columns
38
- }
@@ -1,20 +0,0 @@
1
- /**
2
- * Deserializes a stringified function expression into a typed callable.
3
- *
4
- * Throws if the string cannot be parsed as a function (SyntaxError) or if the
5
- * resulting expression is not callable (TypeError), or if the expression references
6
- * an undefined variable (ReferenceError). Callers are responsible for try/catch.
7
- *
8
- * @example
9
- * ```ts
10
- * const fn = deserializeFunction<(x: number) => number>('(x) => x * 2')
11
- * fn(5) // 10
12
- * ```
13
- * @public
14
- */
15
- // T is intentionally a caller-supplied return type — this utility is unsafe by design (Function constructor).
16
- // oxlint-disable-next-line typescript/no-unnecessary-type-parameters
17
- export function deserializeFunction<T extends (...args: any[]) => any>(source: string): T {
18
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion, typescript/no-implied-eval
19
- return Function(`"use strict"; return (${source})`)() as T
20
- }