@texuli/spec 0.7.0 → 0.9.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.
@@ -1,3 +1,3 @@
1
1
  // Generated by @texuli/spec from schemas/diagnostics.schema.json. Do not edit: run the spec generator.
2
- // Spec 0.7.0, digest 43e44fa9a198d337d686b4e2d86882a06a676ae1e1c1f02d023b3a525795a8b2
2
+ // Spec 0.9.0, digest 497df4d3b0c67d53483163ebd9bd73733b52caf5f8e2966478f1cf860e6f9d9d
3
3
  export {};
@@ -1,3 +1,3 @@
1
1
  // Generated by @texuli/spec from schemas/manifest.schema.json. Do not edit: run the spec generator.
2
- // Spec 0.7.0, digest 43e44fa9a198d337d686b4e2d86882a06a676ae1e1c1f02d023b3a525795a8b2
2
+ // Spec 0.9.0, digest 497df4d3b0c67d53483163ebd9bd73733b52caf5f8e2966478f1cf860e6f9d9d
3
3
  export {};
@@ -1,7 +1,7 @@
1
1
  /** The built catalog this vocabulary was projected from. */
2
- export declare const SPEC_CATALOG_HASH = "c6bd7047eba3e1f32e9ed74097c390a58416cf4260267c8958e0ea70821abf35";
2
+ export declare const SPEC_CATALOG_HASH = "8e72aaa2c94dba6b4245a9778fdd21fd86c6398e5a0fca410da0aa51a3190b72";
3
3
  /** Every closed component id, sorted. */
4
- export declare const SPEC_COMPONENT_IDS: readonly ["action-form", "alert", "alert-dialog", "analytics-grid", "app-nav", "badge", "banner", "blocks-code", "blocks-data", "blocks-diagram", "blocks-embed", "blocks-interactive", "blocks-map", "blocks-media", "blocks-structure", "blocks-text", "breadcrumb", "button", "button-group", "callout", "card", "charts-area", "charts-bar", "charts-bubble", "charts-bullet", "charts-canvas-renderer", "charts-cartesian", "charts-combo", "charts-donut", "charts-funnel", "charts-gauge", "charts-geo-map", "charts-geo-point-map", "charts-heatmap", "charts-line", "charts-network", "charts-pie", "charts-progress-ring", "charts-sankey", "charts-scatter", "charts-sparkline", "charts-stacked-bar", "charts-sunburst", "charts-treemap", "chat-message", "chat-thread", "checkbox", "chip", "code", "combobox", "command-palette", "content-layout", "context-menu", "context-menu-trigger", "control-choice", "control-filter", "control-slider", "control-toggle", "data-board", "data-calendar", "data-cohort-table", "data-files", "data-filter-builder", "data-grid", "data-map", "data-notification-inbox", "data-timeline", "data-tree-view", "deck-slide", "description", "detail-panel", "dialog", "document", "drawer", "dropdown-menu", "dropdown-menu-content", "dropdown-menu-item", "dropdown-menu-trigger", "empty-state", "error-state", "field", "field-error", "flow-action", "flow-view", "form", "form-field", "form-submit", "host-region", "hover-card", "hover-card-content", "icon-button", "inline-text", "input", "input-group", "kbd", "kpi", "label", "layout-auth-split", "layout-blog", "layout-card", "layout-chrome", "layout-dashboard-grid", "layout-deck", "layout-doc", "layout-docs", "layout-drawer", "layout-dual-sidebar", "layout-editorial", "layout-grid", "layout-host", "layout-landing", "layout-marketing", "layout-page", "layout-pricing", "layout-row", "layout-settings", "layout-sidebar", "layout-split", "layout-stack", "layout-tile", "layout-top-nav", "layout-wizard", "media-composition-canvas", "media-composition-svg", "media-image", "menubar", "menubar-trigger", "multi-select", "nav-icon", "navigation-menu", "pagination", "popover", "popover-content", "radio", "radio-group", "responsive-modal", "screen-outlet", "select", "select-content", "select-group", "select-item", "select-label", "select-portal", "select-separator", "select-trigger", "select-value", "select-viewport", "sheet", "sidebar", "sortable-list", "split-view", "stat", "stepper", "switch", "table", "tag", "text-counter", "textarea", "time-field", "timeline", "toaster", "tooltip", "workflow-graph"];
4
+ export declare const SPEC_COMPONENT_IDS: readonly ["action-form", "alert", "alert-dialog", "analytics-grid", "app-nav", "badge", "banner", "blocks-code", "blocks-data", "blocks-diagram", "blocks-embed", "blocks-interactive", "blocks-map", "blocks-media", "blocks-structure", "blocks-text", "breadcrumb", "button", "button-group", "callout", "canvas", "card", "charts-area", "charts-bar", "charts-bubble", "charts-bullet", "charts-canvas-renderer", "charts-cartesian", "charts-combo", "charts-donut", "charts-funnel", "charts-gauge", "charts-geo-map", "charts-geo-point-map", "charts-heatmap", "charts-line", "charts-network", "charts-pie", "charts-progress-ring", "charts-sankey", "charts-scatter", "charts-sparkline", "charts-stacked-bar", "charts-sunburst", "charts-treemap", "chat-message", "chat-thread", "checkbox", "chip", "code", "combobox", "command-palette", "content-layout", "context-menu", "context-menu-trigger", "control-choice", "control-filter", "control-slider", "control-toggle", "data-board", "data-calendar", "data-cohort-table", "data-dashboard", "data-dashboard-widget", "data-files", "data-filter-builder", "data-grid", "data-map", "data-notification-inbox", "data-timeline", "data-tree-view", "deck-slide", "description", "detail-panel", "dialog", "document", "drawer", "dropdown-menu", "dropdown-menu-content", "dropdown-menu-item", "dropdown-menu-trigger", "empty-state", "error-state", "field", "field-error", "flow-action", "flow-view", "form", "form-field", "form-submit", "host-region", "hover-card", "hover-card-content", "icon-button", "inline-text", "input", "input-group", "kbd", "kpi", "label", "layout-auth-split", "layout-blog", "layout-card", "layout-chrome", "layout-dashboard-grid", "layout-deck", "layout-doc", "layout-docs", "layout-drawer", "layout-dual-sidebar", "layout-editorial", "layout-grid", "layout-host", "layout-landing", "layout-marketing", "layout-page", "layout-pricing", "layout-row", "layout-settings", "layout-sidebar", "layout-split", "layout-stack", "layout-tile", "layout-top-nav", "layout-wizard", "media-composition-canvas", "media-composition-svg", "media-image", "menubar", "menubar-trigger", "multi-select", "nav-icon", "navigation-menu", "pagination", "popover", "popover-content", "radio", "radio-group", "responsive-modal", "schema-form", "screen-outlet", "select", "select-content", "select-group", "select-item", "select-label", "select-portal", "select-separator", "select-trigger", "select-value", "select-viewport", "sheet", "sidebar", "sortable-list", "split-view", "spreadsheet", "stat", "stepper", "switch", "table", "tag", "text-counter", "textarea", "time-field", "timeline", "toaster", "tooltip", "workflow-graph"];
5
5
  export type SpecComponentId = (typeof SPEC_COMPONENT_IDS)[number];
6
6
  /** The props a blueprint may set on each component (platform extensions left out). */
7
7
  export interface SpecComponentProps {
@@ -139,6 +139,10 @@ export interface SpecComponentProps {
139
139
  title?: string;
140
140
  tone?: 'info' | 'success' | 'warning' | 'error' | 'brand' | 'neutral';
141
141
  };
142
+ canvas: {
143
+ canvas: Readonly<Record<string, unknown>>;
144
+ label?: string;
145
+ };
142
146
  card: {
143
147
  href?: string;
144
148
  hrefTrust?: 'developer' | 'untrusted';
@@ -150,20 +154,24 @@ export interface SpecComponentProps {
150
154
  description: string;
151
155
  fullDomain?: string;
152
156
  interactive?: string;
157
+ locale?: string;
153
158
  mode?: 'light' | 'dark';
154
159
  series: readonly unknown[];
155
160
  title: string;
156
161
  visibleDomain?: string;
162
+ xKind?: 'linear' | 'category' | 'time';
157
163
  };
158
164
  'charts-bar': {
159
165
  annotations?: string;
160
166
  description: string;
161
167
  fullDomain?: string;
162
168
  interactive?: string;
169
+ locale?: string;
163
170
  mode?: 'light' | 'dark';
164
171
  series: readonly unknown[];
165
172
  title: string;
166
173
  visibleDomain?: string;
174
+ xKind?: 'linear' | 'category' | 'time';
167
175
  };
168
176
  'charts-bubble': {
169
177
  annotations?: string;
@@ -198,20 +206,24 @@ export interface SpecComponentProps {
198
206
  fullDomain?: string;
199
207
  interactive?: string;
200
208
  kind: 'line' | 'area' | 'bar' | 'stacked-bar' | 'combo';
209
+ locale?: string;
201
210
  mode?: 'light' | 'dark';
202
211
  series: readonly unknown[];
203
212
  title: string;
204
213
  visibleDomain?: string;
214
+ xKind?: 'linear' | 'category' | 'time';
205
215
  };
206
216
  'charts-combo': {
207
217
  annotations?: string;
208
218
  description: string;
209
219
  fullDomain?: string;
210
220
  interactive?: string;
221
+ locale?: string;
211
222
  mode?: 'light' | 'dark';
212
223
  series: readonly unknown[];
213
224
  title: string;
214
225
  visibleDomain?: string;
226
+ xKind?: 'linear' | 'category' | 'time';
215
227
  };
216
228
  'charts-donut': {
217
229
  data: readonly unknown[];
@@ -277,10 +289,12 @@ export interface SpecComponentProps {
277
289
  description: string;
278
290
  fullDomain?: string;
279
291
  interactive?: string;
292
+ locale?: string;
280
293
  mode?: 'light' | 'dark';
281
294
  series: readonly unknown[];
282
295
  title: string;
283
296
  visibleDomain?: string;
297
+ xKind?: 'linear' | 'category' | 'time';
284
298
  };
285
299
  'charts-network': {
286
300
  description?: string;
@@ -346,10 +360,12 @@ export interface SpecComponentProps {
346
360
  description: string;
347
361
  fullDomain?: string;
348
362
  interactive?: string;
363
+ locale?: string;
349
364
  mode?: 'light' | 'dark';
350
365
  series: readonly unknown[];
351
366
  title: string;
352
367
  visibleDomain?: string;
368
+ xKind?: 'linear' | 'category' | 'time';
353
369
  };
354
370
  'charts-sunburst': {
355
371
  description: string;
@@ -493,6 +509,20 @@ export interface SpecComponentProps {
493
509
  rows: readonly unknown[];
494
510
  valueKind?: 'rate' | 'count';
495
511
  };
512
+ 'data-dashboard': {
513
+ columns?: number;
514
+ compaction?: 'vertical' | 'none';
515
+ density?: 'compact' | 'default' | 'comfortable';
516
+ editable?: boolean;
517
+ gap?: 'none' | 'small' | 'medium' | 'large';
518
+ label: string;
519
+ layout?: readonly unknown[];
520
+ };
521
+ 'data-dashboard-widget': {
522
+ place?: Readonly<Record<string, unknown>>;
523
+ title: string;
524
+ widgetId: string;
525
+ };
496
526
  'data-files': {
497
527
  density?: 'comfortable' | 'compact';
498
528
  entries: readonly unknown[];
@@ -985,6 +1015,11 @@ export interface SpecComponentProps {
985
1015
  side?: 'top' | 'right' | 'bottom' | 'left' | 'start' | 'end' | 'center';
986
1016
  size?: 'sm' | 'md' | 'lg' | 'xl';
987
1017
  };
1018
+ 'schema-form': {
1019
+ action: string;
1020
+ label?: string;
1021
+ schema: Readonly<Record<string, unknown>>;
1022
+ };
988
1023
  'screen-outlet': Record<string, never>;
989
1024
  select: {
990
1025
  defaultValue?: string;
@@ -1052,6 +1087,10 @@ export interface SpecComponentProps {
1052
1087
  detailLabel?: string;
1053
1088
  listLabel?: string;
1054
1089
  };
1090
+ spreadsheet: {
1091
+ label?: string;
1092
+ sheet: Readonly<Record<string, unknown>>;
1093
+ };
1055
1094
  stat: {
1056
1095
  delta?: string;
1057
1096
  hint?: string;
@@ -1,7 +1,7 @@
1
1
  // Generated by @texuli/spec from catalog/components.json. Do not edit: run the spec generator.
2
- // Spec 0.7.0, digest 43e44fa9a198d337d686b4e2d86882a06a676ae1e1c1f02d023b3a525795a8b2
2
+ // Spec 0.9.0, digest 497df4d3b0c67d53483163ebd9bd73733b52caf5f8e2966478f1cf860e6f9d9d
3
3
  /** The built catalog this vocabulary was projected from. */
4
- export const SPEC_CATALOG_HASH = 'c6bd7047eba3e1f32e9ed74097c390a58416cf4260267c8958e0ea70821abf35';
4
+ export const SPEC_CATALOG_HASH = '8e72aaa2c94dba6b4245a9778fdd21fd86c6398e5a0fca410da0aa51a3190b72';
5
5
  /** Every closed component id, sorted. */
6
6
  export const SPEC_COMPONENT_IDS = [
7
7
  'action-form',
@@ -24,6 +24,7 @@ export const SPEC_COMPONENT_IDS = [
24
24
  'button',
25
25
  'button-group',
26
26
  'callout',
27
+ 'canvas',
27
28
  'card',
28
29
  'charts-area',
29
30
  'charts-bar',
@@ -65,6 +66,8 @@ export const SPEC_COMPONENT_IDS = [
65
66
  'data-board',
66
67
  'data-calendar',
67
68
  'data-cohort-table',
69
+ 'data-dashboard',
70
+ 'data-dashboard-widget',
68
71
  'data-files',
69
72
  'data-filter-builder',
70
73
  'data-grid',
@@ -140,6 +143,7 @@ export const SPEC_COMPONENT_IDS = [
140
143
  'radio',
141
144
  'radio-group',
142
145
  'responsive-modal',
146
+ 'schema-form',
143
147
  'screen-outlet',
144
148
  'select',
145
149
  'select-content',
@@ -155,6 +159,7 @@ export const SPEC_COMPONENT_IDS = [
155
159
  'sidebar',
156
160
  'sortable-list',
157
161
  'split-view',
162
+ 'spreadsheet',
158
163
  'stat',
159
164
  'stepper',
160
165
  'switch',
@@ -1,3 +1,3 @@
1
1
  // Generated by @texuli/spec from schemas/workflow.schema.json. Do not edit: run the spec generator.
2
- // Spec 0.7.0, digest 43e44fa9a198d337d686b4e2d86882a06a676ae1e1c1f02d023b3a525795a8b2
2
+ // Spec 0.9.0, digest 497df4d3b0c67d53483163ebd9bd73733b52caf5f8e2966478f1cf860e6f9d9d
3
3
  export {};
package/dist/index.d.ts CHANGED
@@ -20,6 +20,7 @@ export { CAPABILITIES, type Capability, type SpecPropKind, WEB_ONLY_KINDS, WEB_O
20
20
  export { ACTION_FIELDS, contractRoot, DATA_BINDING_KEY, SPEC_ACTION_OPS, SPEC_EVENT_NAMES, SPEC_LIMITS, SPEC_PATTERNS, SPEC_PROP_REFS, SPEC_STATE_TYPES, type SpecActionOp, type SpecStateType, STATE_BINDING_KEY, STATE_FIELDS, toDialectSchema, } from './contract.js';
21
21
  export { checkSchemaDocument, DIALECT_KEYWORDS, DIALECT_TYPES, DIALECT_URI, type DialectHooks, type DialectType, type Schema, type SchemaIssue, validateInstance, } from './dialect.js';
22
22
  export type { SpecMigration, SpecMigrationResult } from './migrations/types.js';
23
+ export { checkSourceBinding, isSourceBinding, isSpecSourceDate, SOURCE_BINDING_FIELDS, SOURCE_BINDING_KEY, type SourceBindingContext, type SourceBindingIssue, SPEC_SOURCE_FIELD_TYPES, SPEC_SOURCE_FILTER_OPERATORS, SPEC_SOURCE_LIMITS, SPEC_SOURCE_OPERATIONS, SPEC_SOURCE_PATTERNS, type SpecSourceDescriptor, type SpecSourceField, type SpecSourceFieldType, type SpecSourceFilterOperator, type SpecSourceOperation, } from './source.js';
23
24
  export { checkStateSurface, LIST_TEXT_PATTERN, SPEC_CONTROL_STATE_TYPES, SURFACE_PLAYER_CODES, type SurfaceCode, type SurfaceInputs, type SurfaceIssue, surfaceInputs, } from './surface.js';
24
25
  export { type SpecDocuments, type SpecFlowInfo, type SpecStateVariable, type TreeOptions, validateBlueprint, validateTree, type WorkflowGraphValidator, } from './validate.js';
25
26
  export { SPEC_VERSION } from './version.js';
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ export { canonicalJson, sha256 } from "./canonical.js";
14
14
  export { CAPABILITIES, WEB_ONLY_KINDS, WEB_ONLY_PROP_NAMES, } from "./catalog.js";
15
15
  export { ACTION_FIELDS, contractRoot, DATA_BINDING_KEY, SPEC_ACTION_OPS, SPEC_EVENT_NAMES, SPEC_LIMITS, SPEC_PATTERNS, SPEC_PROP_REFS, SPEC_STATE_TYPES, STATE_BINDING_KEY, STATE_FIELDS, toDialectSchema, } from "./contract.js";
16
16
  export { checkSchemaDocument, DIALECT_KEYWORDS, DIALECT_TYPES, DIALECT_URI, validateInstance, } from "./dialect.js";
17
+ export { checkSourceBinding, isSourceBinding, isSpecSourceDate, SOURCE_BINDING_FIELDS, SOURCE_BINDING_KEY, SPEC_SOURCE_FIELD_TYPES, SPEC_SOURCE_FILTER_OPERATORS, SPEC_SOURCE_LIMITS, SPEC_SOURCE_OPERATIONS, SPEC_SOURCE_PATTERNS, } from "./source.js";
17
18
  export { checkStateSurface, LIST_TEXT_PATTERN, SPEC_CONTROL_STATE_TYPES, SURFACE_PLAYER_CODES, surfaceInputs, } from "./surface.js";
18
19
  export { validateBlueprint, validateTree, } from "./validate.js";
19
20
  export { SPEC_VERSION } from "./version.js";
@@ -0,0 +1,8 @@
1
+ import type { SpecMigration } from './types.js';
2
+ /**
3
+ * 0.7.0 → 0.8.0 is additive (PLAN_010 wave 4–6, ADR-012 and ADR-015): it
4
+ * adds vocabulary (data-source bindings and the other 0.8.0 additions) and
5
+ * removes nothing. Every 0.7.0 envelope is a valid 0.8.0 envelope, so the
6
+ * step only stamps `spec`.
7
+ */
8
+ export declare const migration070to080: SpecMigration;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 0.7.0 → 0.8.0 is additive (PLAN_010 wave 4–6, ADR-012 and ADR-015): it
3
+ * adds vocabulary (data-source bindings and the other 0.8.0 additions) and
4
+ * removes nothing. Every 0.7.0 envelope is a valid 0.8.0 envelope, so the
5
+ * step only stamps `spec`.
6
+ */
7
+ export const migration070to080 = Object.freeze({
8
+ from: '0.7.0',
9
+ to: '0.8.0',
10
+ migrate: (envelope) => ({ ...envelope, spec: '0.8.0' }),
11
+ });
@@ -0,0 +1,8 @@
1
+ import type { SpecMigration } from './types.js';
2
+ /**
3
+ * 0.8.0 → 0.9.0 is additive (PLAN_011 T-gaps-87-95): it refreshes the catalog
4
+ * projection (the button pending note and the gap props that reach the
5
+ * manifests) and removes nothing. Every 0.8.0 envelope is a valid 0.9.0
6
+ * envelope, so the step only stamps `spec`.
7
+ */
8
+ export declare const migration080to090: SpecMigration;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 0.8.0 → 0.9.0 is additive (PLAN_011 T-gaps-87-95): it refreshes the catalog
3
+ * projection (the button pending note and the gap props that reach the
4
+ * manifests) and removes nothing. Every 0.8.0 envelope is a valid 0.9.0
5
+ * envelope, so the step only stamps `spec`.
6
+ */
7
+ export const migration080to090 = Object.freeze({
8
+ from: '0.8.0',
9
+ to: '0.9.0',
10
+ migrate: (envelope) => ({ ...envelope, spec: '0.9.0' }),
11
+ });
@@ -5,6 +5,8 @@ import { migration030to040 } from "./0.3.0-0.4.0.js";
5
5
  import { migration040to050 } from "./0.4.0-0.5.0.js";
6
6
  import { migration050to060 } from "./0.5.0-0.6.0.js";
7
7
  import { migration060to070 } from "./0.6.0-0.7.0.js";
8
+ import { migration070to080 } from "./0.7.0-0.8.0.js";
9
+ import { migration080to090 } from "./0.8.0-0.9.0.js";
8
10
  /** The version an envelope without `spec` was written for. */
9
11
  export const UNDECLARED_SPEC_VERSION = '0.2.0';
10
12
  /** Every step, in order; each `to` is the next step's `from`. */
@@ -14,6 +16,8 @@ export const SPEC_MIGRATIONS = Object.freeze([
14
16
  migration040to050,
15
17
  migration050to060,
16
18
  migration060to070,
19
+ migration070to080,
20
+ migration080to090,
17
21
  ]);
18
22
  /**
19
23
  * Bring a blueprint envelope up to `target` (the current spec by default)
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Data-source bindings (spec 0.8.0, ADR-012 and ADR-015): a sourceable prop
3
+ * reads rows from a source the host registered,
4
+ * `{"$source": name, "query": {...}, "map": {...}}`. The schema
5
+ * (`$defs.sourceBinding`) fixes the closed shape; this module checks a
6
+ * binding against the host's source descriptors: the name, every field,
7
+ * operator and value of the query, the page size and the map. It mirrors
8
+ * `checkSourceQuery` in `@texuli/core/data-source` (the spec cannot import
9
+ * core: both are L0), and a parity test keeps the two in agreement.
10
+ * With no descriptors a binding is refused: the spec fails closed.
11
+ */
12
+ /** The binding key that reads a host data source: `{ "$source": name, … }`. */
13
+ export declare const SOURCE_BINDING_KEY = "$source";
14
+ /** The members a binding takes besides `$source`. */
15
+ export declare const SOURCE_BINDING_FIELDS: readonly ["query", "map"];
16
+ export declare const SPEC_SOURCE_FIELD_TYPES: readonly ["text", "enum", "number", "date", "boolean"];
17
+ export type SpecSourceFieldType = (typeof SPEC_SOURCE_FIELD_TYPES)[number];
18
+ export declare const SPEC_SOURCE_OPERATIONS: readonly ["list", "get", "create", "update", "delete", "search"];
19
+ export type SpecSourceOperation = (typeof SPEC_SOURCE_OPERATIONS)[number];
20
+ /** The `@texuli/data` grid filter model's operators (`$defs.sourceFilter.operator`). */
21
+ export declare const SPEC_SOURCE_FILTER_OPERATORS: readonly ["eq", "neq", "contains", "in", "between", "before", "after", "isEmpty", "isNotEmpty"];
22
+ export type SpecSourceFilterOperator = (typeof SPEC_SOURCE_FILTER_OPERATORS)[number];
23
+ /** Every bound of a binding; the schema writes the static ones too (`tests/source.test.ts`). */
24
+ export declare const SPEC_SOURCE_LIMITS: Readonly<{
25
+ nameLength: 64;
26
+ projection: 32;
27
+ sort: 4;
28
+ searchLength: 200;
29
+ filterDepth: 6;
30
+ filterNodes: 64;
31
+ filterValues: 100;
32
+ valueLength: 500;
33
+ pageSize: 500;
34
+ mapEntries: 16;
35
+ }>;
36
+ export declare const SPEC_SOURCE_PATTERNS: Readonly<{
37
+ sourceName: "^[a-z][a-z0-9]*([._-][a-z0-9]+)*$";
38
+ sourceFieldName: "^[A-Za-z][A-Za-z0-9_]*$";
39
+ }>;
40
+ /** One declared field, as `@texuli/core/data-source` describes it. */
41
+ export interface SpecSourceField {
42
+ readonly name: string;
43
+ readonly type: SpecSourceFieldType;
44
+ readonly options?: readonly string[];
45
+ readonly filter: readonly SpecSourceFilterOperator[];
46
+ readonly sort: boolean;
47
+ readonly editable?: boolean;
48
+ readonly required?: boolean;
49
+ }
50
+ /**
51
+ * A host source as plain data: structurally the `SourceDescriptor` of
52
+ * `@texuli/core/data-source` (`registry.describe()` can be passed as is).
53
+ */
54
+ export interface SpecSourceDescriptor {
55
+ readonly name: string;
56
+ readonly key: string;
57
+ readonly fields: readonly SpecSourceField[];
58
+ readonly operations: readonly SpecSourceOperation[];
59
+ readonly pagination?: 'cursor' | 'offset' | 'none';
60
+ readonly maxPageSize: number;
61
+ readonly defaultPageSize?: number;
62
+ }
63
+ /** One semantic problem with a binding; `at` is relative to the binding (`.query.filter`). */
64
+ export interface SourceBindingIssue {
65
+ readonly code: 'source' | 'unknown-source';
66
+ readonly at: string;
67
+ readonly message: string;
68
+ }
69
+ /** What a binding is checked against. */
70
+ export interface SourceBindingContext {
71
+ /** The host's sources. Omitted: every binding is refused (fail closed). */
72
+ readonly sources?: readonly SpecSourceDescriptor[];
73
+ /**
74
+ * The item fields the bound prop's rows may carry (its item schema's
75
+ * properties), when known: `map` keys must be among them.
76
+ */
77
+ readonly itemFields?: readonly string[];
78
+ }
79
+ /** Whether a value is shaped like a source binding (`$source` as an own key). */
80
+ export declare function isSourceBinding(value: unknown): value is Record<string, unknown>;
81
+ /** Whether `value` is an ISO 8601 date or date-time, or epoch milliseconds. */
82
+ export declare function isSpecSourceDate(value: unknown): boolean;
83
+ /**
84
+ * Check a binding: its closed shape, then its meaning against the host's
85
+ * sources (fail closed without them): the name, every field, operator and
86
+ * value of the query, the page size and the map. One issue per problem, up
87
+ * to 16. `@texuli/spec`'s validator runs the schema (`$defs.sourceBinding`)
88
+ * first; `@texuli/catalog` runs this alone.
89
+ */
90
+ export declare function checkSourceBinding(binding: Record<string, unknown>, context: SourceBindingContext): SourceBindingIssue[];