@w6w/ui 0.2.0 → 0.2.54
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.
- package/CHANGELOG.md +146 -2
- package/README.md +28 -10
- package/dist/AppPicker.d.ts +58 -2
- package/dist/CanvasContextMenu.d.ts +19 -0
- package/dist/CanvasLayer.d.ts +38 -0
- package/dist/{CodeBlock-Dot3Pd7P.js → CodeBlock-C-oIIYfC.js} +1436 -555
- package/dist/CodeBlock-C-oIIYfC.js.map +1 -0
- package/dist/CodeBlock-CymlfyeA.cjs +15 -0
- package/dist/CodeBlock-CymlfyeA.cjs.map +1 -0
- package/dist/CodeEditor.d.ts +4 -1
- package/dist/ConditionEditor.d.ts +11 -0
- package/dist/EditConnectionModal.d.ts +6 -1
- package/dist/JsonEditor.d.ts +20 -0
- package/dist/Markdown.d.ts +25 -0
- package/dist/ParamCustomization.d.ts +5 -0
- package/dist/ParamsForm.d.ts +18 -4
- package/dist/RouterEditor.d.ts +5 -0
- package/dist/StepBuilderModal.d.ts +103 -15
- package/dist/StepNameEditor.d.ts +11 -0
- package/dist/StopEditor.d.ts +5 -0
- package/dist/TriggerFillForm.d.ts +14 -1
- package/dist/WebhookListenPanel.d.ts +28 -0
- package/dist/WorkflowConnections.d.ts +29 -0
- package/dist/WorkflowFlowEditor.d.ts +74 -7
- package/dist/app-pages.d.ts +2 -0
- package/dist/assets/script-completion.worker-DDJKkj5M.js +8290 -0
- package/dist/assets/script-completion.worker-DDJKkj5M.js.map +1 -0
- package/dist/canvas-context-menu.d.ts +27 -0
- package/dist/canvas-types.d.ts +36 -0
- package/dist/canvas-utils.d.ts +44 -0
- package/dist/code.cjs +1 -1
- package/dist/code.mjs +3 -4
- package/dist/code.mjs.map +1 -1
- package/dist/components/AnchoredFlyout.d.ts +7 -0
- package/dist/components/AuthFieldsForm.d.ts +11 -0
- package/dist/components/BudgetMeter.d.ts +15 -0
- package/dist/components/CallableList.d.ts +3 -2
- package/dist/components/ColumnsEditor.d.ts +27 -0
- package/dist/components/Combobox.d.ts +19 -1
- package/dist/components/ConnectionList.d.ts +2 -3
- package/dist/components/CredentialPicker.d.ts +35 -0
- package/dist/components/CsvPanel.d.ts +21 -0
- package/dist/components/DataEntryEditor.d.ts +38 -0
- package/dist/components/DataEntryList.d.ts +33 -0
- package/dist/components/DataStoreList.d.ts +33 -0
- package/dist/components/DataTable.d.ts +27 -0
- package/dist/components/DataTableGrid.d.ts +46 -0
- package/dist/components/EmptyState.d.ts +9 -0
- package/dist/components/EventbriteTriggerPicker.d.ts +7 -0
- package/dist/components/ExecutionDetail.d.ts +17 -1
- package/dist/components/ExecutionList.d.ts +19 -1
- package/dist/components/ExecutionLogPanel.d.ts +61 -3
- package/dist/components/ExpressionEditorModal.d.ts +33 -10
- package/dist/components/ExpressionOptions.d.ts +101 -15
- package/dist/components/HtmlPreview.d.ts +7 -0
- package/dist/components/JsonTree.d.ts +32 -0
- package/dist/components/ResolvedParams.d.ts +6 -1
- package/dist/components/ResultViewer.d.ts +46 -0
- package/dist/components/ScriptBindingsNotice.d.ts +31 -0
- package/dist/components/ScriptCodeField.d.ts +13 -0
- package/dist/components/StepStatusPill.d.ts +7 -0
- package/dist/components/expression-authoring.d.ts +13 -0
- package/dist/components/expression-dom.d.ts +17 -2
- package/dist/components/expression-template.d.ts +25 -3
- package/dist/components/icons.d.ts +1 -1
- package/dist/components/json-compose.d.ts +53 -0
- package/dist/components/result-format.d.ts +13 -0
- package/dist/condition-editor.d.ts +44 -0
- package/dist/data-stores/data-store-view.d.ts +371 -0
- package/dist/dynamic-fields.d.ts +60 -0
- package/dist/editor-theme.d.ts +24 -0
- package/dist/eventbrite-trigger-selection.d.ts +13 -0
- package/dist/flow-connect.d.ts +22 -16
- package/dist/flow-delete.d.ts +16 -0
- package/dist/flow-fanout.d.ts +2 -2
- package/dist/flow-history.d.ts +75 -0
- package/dist/flow-layout.d.ts +13 -0
- package/dist/flow-loop-colors.d.ts +39 -0
- package/dist/flow-loop.d.ts +98 -0
- package/dist/flow-node-flags.d.ts +14 -0
- package/dist/flow-problems.d.ts +69 -0
- package/dist/flow-state.d.ts +20 -0
- package/dist/flow-types.d.ts +155 -10
- package/dist/flow-utils.d.ts +33 -12
- package/dist/flow.cjs +4 -2
- package/dist/flow.cjs.map +1 -1
- package/dist/flow.d.ts +15 -2
- package/dist/flow.mjs +3737 -1350
- package/dist/flow.mjs.map +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +43 -5
- package/dist/index.mjs +2855 -1333
- package/dist/index.mjs.map +1 -1
- package/dist/node-samples-ChdyMBnJ.cjs +22 -0
- package/dist/node-samples-ChdyMBnJ.cjs.map +1 -0
- package/dist/node-samples-DkJL07EX.js +12302 -0
- package/dist/node-samples-DkJL07EX.js.map +1 -0
- package/dist/node-samples.d.ts +80 -0
- package/dist/note-markdown.d.ts +22 -0
- package/dist/output-shape.d.ts +30 -14
- package/dist/param-customization.d.ts +7 -0
- package/dist/provider.d.ts +174 -13
- package/dist/resolve-params.d.ts +50 -11
- package/dist/run-visuals.d.ts +18 -22
- package/dist/script-bindings.d.ts +63 -0
- package/dist/script-completion-service.d.ts +9 -0
- package/dist/script-completion.worker.d.ts +1 -0
- package/dist/script-completions.d.ts +2 -0
- package/dist/state-shape.d.ts +38 -0
- package/dist/step-preview-state.d.ts +155 -6
- package/dist/step-problems.d.ts +64 -0
- package/dist/test-inputs.d.ts +25 -0
- package/dist/trigger-registration.d.ts +28 -0
- package/dist/types.d.ts +179 -11
- package/dist/use-app-action-defs.d.ts +9 -1
- package/dist/use-dynamic-fields.d.ts +23 -0
- package/dist/use-test-input.d.ts +18 -0
- package/dist/workflow-connections.d.ts +30 -0
- package/package.json +18 -7
- package/src/code.css +60 -6
- package/src/styles/_budget-meter.scss +46 -0
- package/src/styles/_callable-list.scss +15 -6
- package/src/styles/_canvas.scss +353 -0
- package/src/styles/_code-editor.scss +35 -0
- package/src/styles/_code.scss +6 -5
- package/src/styles/_connections.scss +2 -14
- package/src/styles/_copyable.scss +24 -0
- package/src/styles/_data-stores.scss +138 -0
- package/src/styles/_data-table.scss +55 -0
- package/src/styles/_data-vars.scss +17 -6
- package/src/styles/_empty-state.scss +21 -0
- package/src/styles/_execution-history.scss +73 -0
- package/src/styles/_execution-log.scss +145 -1
- package/src/styles/_expression-modal.scss +106 -16
- package/src/styles/_fields.scss +11 -0
- package/src/styles/_flow.scss +171 -0
- package/src/styles/_fx.scss +26 -1
- package/src/styles/_incoming-state.scss +33 -0
- package/src/styles/_layout.scss +10 -0
- package/src/styles/_markdown.scss +20 -0
- package/src/styles/_modal.scss +12 -0
- package/src/styles/_multiselect.scss +35 -0
- package/src/styles/_sections.scss +36 -0
- package/src/styles/_step-builder.scss +145 -0
- package/src/styles/_tester.scss +57 -14
- package/src/styles/_tokens.scss +27 -1
- package/src/styles.css +1861 -115
- package/src/styles.scss +7 -0
- package/dist/CodeBlock-CZu4TFSi.cjs +0 -15
- package/dist/CodeBlock-CZu4TFSi.cjs.map +0 -1
- package/dist/CodeBlock-Dot3Pd7P.js.map +0 -1
- package/dist/ConfirmModal-ChoiGy2K.cjs +0 -11
- package/dist/ConfirmModal-ChoiGy2K.cjs.map +0 -1
- package/dist/ConfirmModal-Wx3i8F1n.js +0 -6359
- package/dist/ConfirmModal-Wx3i8F1n.js.map +0 -1
- package/dist/Copyable-1niV9gUa.js +0 -771
- package/dist/Copyable-1niV9gUa.js.map +0 -1
- package/dist/Copyable-CYZU1o4X.cjs +0 -2
- package/dist/Copyable-CYZU1o4X.cjs.map +0 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { StepStartState } from '../provider.tsx';
|
|
2
|
+
/** True when `pos` sits inside a JSON string literal of `text` (after its opening quote). */
|
|
3
|
+
export declare function insideJsonString(text: string, pos: number): boolean;
|
|
4
|
+
/** The text to insert for `ref` at `pos` of `text`: a marker in a string, else a quoted one. */
|
|
5
|
+
export declare function refInsertion(text: string, pos: number, ref: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* The property name a reference gets when it is added to an object: its last meaningful
|
|
8
|
+
* segment — `var.region` → `region`, `nodes.get_event.output.id` → `id`,
|
|
9
|
+
* `nodes.get_event.output` → `get_event`, `nodes.get_event.meta` → `get_event_meta`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function keyForRef(ref: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Add a reference to a draft the author is working on — never replacing it. `pos` is the caret.
|
|
14
|
+
*
|
|
15
|
+
* - Inside a JSON string: `{{ ref }}`, interpolated.
|
|
16
|
+
* - Where a value goes (after `:`, after `[`, or after `,` in an array): `"{{ ref }}"`.
|
|
17
|
+
* - Where a property goes (after `{`, or after `,` in an object): `"key": "{{ ref }}"`.
|
|
18
|
+
* - Anywhere else (the caret is not somewhere a value fits — e.g. it was never placed): a draft
|
|
19
|
+
* that is an object gets a new property at its end, an array a new element at its end.
|
|
20
|
+
* Otherwise the quoted marker goes at the caret.
|
|
21
|
+
*
|
|
22
|
+
* With `literal`, the same placement inserts that VALUE instead of the reference (a literal-JSON
|
|
23
|
+
* field such as a workflow's starting state, where no `{{ }}` marker is ever evaluated): as JSON
|
|
24
|
+
* where a value goes, as its text inside a string. The key is still named after `ref`.
|
|
25
|
+
*
|
|
26
|
+
* Returns the new text and the caret after the inserted reference.
|
|
27
|
+
*/
|
|
28
|
+
export declare function addRefToDraft(text: string, pos: number, ref: string, literal?: {
|
|
29
|
+
value: unknown;
|
|
30
|
+
}): {
|
|
31
|
+
text: string;
|
|
32
|
+
caret: number;
|
|
33
|
+
};
|
|
34
|
+
export declare function bareRefBinding(text: string): string | null;
|
|
35
|
+
/**
|
|
36
|
+
* The ref a whole-value binding names — `"{{ ref }}"` (exactly one `var` marker, nothing
|
|
37
|
+
* else), or a legacy `{ "$": "ref" }` — else `null`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function wholeValueRef(value: unknown): string | null;
|
|
40
|
+
/**
|
|
41
|
+
* The `steps` start state a preview resolves against, rebuilt from the host's flat sample
|
|
42
|
+
* values: `steps.<id>.output` / `nodes.<id>.output` keys give a step's output, and
|
|
43
|
+
* `steps.<id>.meta.<field>` keys its metadata.
|
|
44
|
+
*/
|
|
45
|
+
export declare function sampleStepsState(sampleValues: Record<string, unknown> | undefined): StepStartState;
|
|
46
|
+
/**
|
|
47
|
+
* Resolve a composed value the way the engine resolves a `with` value: a `{ "$": ref }` object
|
|
48
|
+
* and a string holding rooted `{{ ref }}` markers are resolved by `resolveLeaf` wherever they
|
|
49
|
+
* sit; other arrays and objects are walked. A string whose markers are not all rooted stays
|
|
50
|
+
* literal, as in the engine. `resolveLeaf` is the ui's top-level resolver
|
|
51
|
+
* (`resolveParamJson` against a scope), which reads only the value it is handed.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveComposed(value: unknown, resolveLeaf: (leaf: unknown) => unknown): unknown;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** What a result pane is showing, decided once from the ROOT value (never per leaf). */
|
|
2
|
+
export type DetectedResult = {
|
|
3
|
+
format: "json";
|
|
4
|
+
data: unknown;
|
|
5
|
+
} | {
|
|
6
|
+
format: "xml" | "html" | "markdown" | "text";
|
|
7
|
+
text: string;
|
|
8
|
+
};
|
|
9
|
+
/** Above this many characters html/markdown are shown as source only, never rendered. */
|
|
10
|
+
export declare const RESULT_RENDER_MAX_CHARS = 262144;
|
|
11
|
+
export declare function detectResultFormat(value: unknown): DetectedResult;
|
|
12
|
+
/** The exact text the copy button writes: pretty JSON for a tree, else the raw string. */
|
|
13
|
+
export declare function resultCopyText(d: DetectedResult): string;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ExprValue, SecretValue } from './types.ts';
|
|
2
|
+
/** The comparisons the condition builder offers, in menu order, with their labels. */
|
|
3
|
+
export declare const CONDITION_OPERATORS: readonly [readonly ["is-true", "is true"], readonly ["is-false", "is false"], readonly ["===", "equals"], readonly ["!==", "does not equal"], readonly [">", "greater than"], readonly [">=", "at least"], readonly ["<", "less than"], readonly ["<=", "at most"], readonly ["in", "in"], readonly ["includes", "includes value"], readonly ["include-any", "includes any of (list)"], readonly ["include-all", "includes all of (list)"]];
|
|
4
|
+
/** Operand order for membership comparisons; shown on the selected operator and its options. */
|
|
5
|
+
export declare const CONDITION_OPERATOR_HINTS: Record<string, string>;
|
|
6
|
+
/** A comparison operator as the builder names it (`===` → "equals"); unknown ones as written. */
|
|
7
|
+
export declare function conditionOperatorLabel(op: string): string;
|
|
8
|
+
/** One comparison row of the builder: `left <operator> right`. */
|
|
9
|
+
export interface ConditionComparison {
|
|
10
|
+
left: unknown;
|
|
11
|
+
operator: string;
|
|
12
|
+
right: unknown;
|
|
13
|
+
/** Invert this comparison before combining it with the other rows. */
|
|
14
|
+
negated?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** How the builder joins its rows: all of (`and`), any of (`or`), exactly one of (`xor`). */
|
|
17
|
+
export type ConditionCombinator = "and" | "or" | "xor";
|
|
18
|
+
/** The combinators the builder offers, in menu order, with their labels. `xor` is the
|
|
19
|
+
* `@w6w/expr` extension (JSONLogic has none): true when exactly one row is. */
|
|
20
|
+
export declare const CONDITION_COMBINATORS: readonly [readonly ["and", "All of (AND)"], readonly ["or", "Any of (OR)"], readonly ["xor", "Exactly one of (XOR)"]];
|
|
21
|
+
/** A combinator as the builder names it (`or` → "Any of (OR)"); unknown ones as written. */
|
|
22
|
+
export declare function conditionCombinatorLabel(combinator: string): string;
|
|
23
|
+
/** The builder's whole condition: flat rows joined by one combinator (no nested groups). */
|
|
24
|
+
export interface ConditionGroup {
|
|
25
|
+
combinator: ConditionCombinator;
|
|
26
|
+
rows: ConditionComparison[];
|
|
27
|
+
}
|
|
28
|
+
/** Decode only two-operand comparisons; all other conditions keep the full editor. */
|
|
29
|
+
export declare function readComparison(value: unknown): ConditionComparison | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Decode a condition the builder can show: one comparison, or an `and` / `or` / `xor` of
|
|
32
|
+
* comparisons. Anything else (a nested group, another operator) is `undefined`, and the
|
|
33
|
+
* editor keeps the code view for it.
|
|
34
|
+
*/
|
|
35
|
+
export declare function readConditionGroup(value: unknown): ConditionGroup | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* The stored condition for a builder group. A row with no field is still being written and
|
|
38
|
+
* is left out; no complete row is `false`, one is that comparison alone (the shape a
|
|
39
|
+
* one-row condition always had), more are joined by the combinator.
|
|
40
|
+
*/
|
|
41
|
+
export declare function writeConditionGroup(group: ConditionGroup): unknown;
|
|
42
|
+
/** Typed scalar or JSON array input. Quotes preserve text that looks like a typed value. */
|
|
43
|
+
export declare function conditionOperandValue(value: string | ExprValue | SecretValue): unknown;
|
|
44
|
+
export declare function conditionOperandText(value: unknown): string;
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pure, data-free vocabulary of a Data store (F-2, lifted from Studio's
|
|
3
|
+
* `lib/data-stores-view`, `data-cells`, `data-grid` and `data-store-errors`).
|
|
4
|
+
*
|
|
5
|
+
* One import point for every consumer (Studio, `@w6w/embed`, the components in
|
|
6
|
+
* this package): the wire types, the closed kind/scalar vocabularies, the
|
|
7
|
+
* cell text codec, the row-draft/write helpers and the error locator. Paths,
|
|
8
|
+
* query builders and cache keys deliberately stay in Studio.
|
|
9
|
+
*
|
|
10
|
+
* Pure and dependency-free on purpose: no React, no SDK, no `fetch`, only
|
|
11
|
+
* relative imports, so `node --test` loads it with nothing but type-stripping.
|
|
12
|
+
*/
|
|
13
|
+
/** Display label per store kind (shared by every list and picker). */
|
|
14
|
+
export declare const DATA_STORE_KIND_LABEL: {
|
|
15
|
+
readonly kv: "Key-value";
|
|
16
|
+
readonly doc: "Document";
|
|
17
|
+
readonly table: "Table";
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The three store shapes. `kv` holds one value per key, `doc` holds a JSON
|
|
21
|
+
* document per key, `table` holds rows whose columns are declared in the
|
|
22
|
+
* store's schema.
|
|
23
|
+
*/
|
|
24
|
+
export type DataStoreKind = "kv" | "doc" | "table";
|
|
25
|
+
/**
|
|
26
|
+
* The server's scalar vocabulary (S-1). A value of this type is validated
|
|
27
|
+
* server-side and stored as the string the caller sent — never coerced.
|
|
28
|
+
*/
|
|
29
|
+
export type ScalarType = "string" | "number" | "integer" | "boolean" | "date" | "datetime";
|
|
30
|
+
/** One declared table column (S-2). `default` is the column's JSON default, verbatim. */
|
|
31
|
+
export interface TableColumn {
|
|
32
|
+
name: string;
|
|
33
|
+
type: ScalarType;
|
|
34
|
+
required: boolean;
|
|
35
|
+
default?: unknown;
|
|
36
|
+
}
|
|
37
|
+
/** A `kv` store's schema (S-2): one scalar type for every value. */
|
|
38
|
+
export interface KvSchema {
|
|
39
|
+
valueType: ScalarType;
|
|
40
|
+
}
|
|
41
|
+
/** A `table` store's schema (S-2); `key` names the column whose cell is the row's key. */
|
|
42
|
+
export interface TableSchema {
|
|
43
|
+
columns: TableColumn[];
|
|
44
|
+
key?: string;
|
|
45
|
+
}
|
|
46
|
+
/** A store as the wire carries it (S-3). Timestamps are ISO-8601 strings. */
|
|
47
|
+
export interface DataStore {
|
|
48
|
+
id: string;
|
|
49
|
+
kind: DataStoreKind;
|
|
50
|
+
name: string;
|
|
51
|
+
description: string;
|
|
52
|
+
project: string;
|
|
53
|
+
schema: Record<string, unknown>;
|
|
54
|
+
entryCount: number;
|
|
55
|
+
sizeBytes: number;
|
|
56
|
+
createdBy: string;
|
|
57
|
+
createdAt: string;
|
|
58
|
+
updatedAt: string;
|
|
59
|
+
}
|
|
60
|
+
/** One entry as the wire carries it (S-3). `expiresAt` is `null` when the entry never expires. */
|
|
61
|
+
export interface Entry {
|
|
62
|
+
key: string;
|
|
63
|
+
value: unknown;
|
|
64
|
+
version: number;
|
|
65
|
+
sizeBytes: number;
|
|
66
|
+
expiresAt: string | null;
|
|
67
|
+
createdAt: string;
|
|
68
|
+
updatedAt: string;
|
|
69
|
+
}
|
|
70
|
+
/** `GET /data-stores` — one page of stores plus the cursor for the next one. */
|
|
71
|
+
export interface DataStorePage {
|
|
72
|
+
items: DataStore[];
|
|
73
|
+
nextCursor?: string;
|
|
74
|
+
}
|
|
75
|
+
/** `GET /data-stores/:id/entries` — one page of entries (a table query never carries a cursor). */
|
|
76
|
+
export interface EntryPage {
|
|
77
|
+
items: Entry[];
|
|
78
|
+
nextCursor?: string;
|
|
79
|
+
}
|
|
80
|
+
/** `POST /data-stores/:id/import` — how many CSV rows the host upserted/appended. */
|
|
81
|
+
export interface ImportResult {
|
|
82
|
+
imported: number;
|
|
83
|
+
}
|
|
84
|
+
/** `POST /data-stores` body. `schema` is the S-2 shape for the chosen `kind`. */
|
|
85
|
+
export interface DataStoreCreateInput {
|
|
86
|
+
kind: DataStoreKind;
|
|
87
|
+
name: string;
|
|
88
|
+
description?: string;
|
|
89
|
+
schema?: Record<string, unknown>;
|
|
90
|
+
}
|
|
91
|
+
/** `PATCH /data-stores/:id` body — every field optional, none of them the kind. */
|
|
92
|
+
export interface DataStorePatch {
|
|
93
|
+
name?: string;
|
|
94
|
+
description?: string;
|
|
95
|
+
schema?: Record<string, unknown>;
|
|
96
|
+
}
|
|
97
|
+
/** The closed set of store kinds, in the order the create dialog offers them. */
|
|
98
|
+
export declare const DATA_STORE_KINDS: readonly ["kv", "doc", "table"];
|
|
99
|
+
/** The closed set of scalar cell types, in the order the columns editor offers them. */
|
|
100
|
+
export declare const SCALAR_TYPES: readonly ["string", "number", "integer", "boolean", "date", "datetime"];
|
|
101
|
+
/** R-7: a CSV upload is at most 5 MB (5 242 880 bytes). The client checks before sending. */
|
|
102
|
+
export declare const CSV_MAX_BYTES = 5242880;
|
|
103
|
+
/**
|
|
104
|
+
* A `kv` store's declared value type, defaulting to `"string"` — S-2's own
|
|
105
|
+
* default, and the only safe reading of a schema the client did not write
|
|
106
|
+
* (a store created before the field existed, or one whose schema is garbage).
|
|
107
|
+
*/
|
|
108
|
+
export declare function kvValueTypeOf(store: DataStore): ScalarType;
|
|
109
|
+
/**
|
|
110
|
+
* A `table` store's schema, or `null` when the store is not a table or its
|
|
111
|
+
* schema has no column array. `null` — not an empty column list — so the grid
|
|
112
|
+
* can tell "not a table" from "a table with nothing declared".
|
|
113
|
+
*/
|
|
114
|
+
export declare function tableSchemaOf(store: DataStore): TableSchema | null;
|
|
115
|
+
/**
|
|
116
|
+
* The filename to save an export under: the host's own `filename="…"` from the
|
|
117
|
+
* `Content-Disposition` header when it sent one, otherwise `<store name>.csv`.
|
|
118
|
+
* A header without that parameter (`attachment` alone, or `null` when a
|
|
119
|
+
* proxy stripped it) falls back rather than producing a nameless file.
|
|
120
|
+
*/
|
|
121
|
+
export declare function csvFilenameOf(contentDisposition: string | null, storeName: string): string;
|
|
122
|
+
/** Why a cell's text could not become a value. */
|
|
123
|
+
export type CellProblem = "required" | "not_a_number" | "not_an_integer" | "not_a_boolean" | "not_a_date" | "not_a_datetime";
|
|
124
|
+
/** The one sentence rendered beside the offending cell, per problem. */
|
|
125
|
+
export declare const CELL_PROBLEM_COPY: Record<CellProblem, string>;
|
|
126
|
+
/**
|
|
127
|
+
* Turn the text an operator typed into the value the wire takes, for a column
|
|
128
|
+
* of `type`.
|
|
129
|
+
*
|
|
130
|
+
* `required` is applied to the EMPTY cell only (R-7): every other rule is the
|
|
131
|
+
* server's own, so a cell this returns `ok` for is a cell the server accepts.
|
|
132
|
+
* `string` is the one type that keeps the text as typed — trimming it would
|
|
133
|
+
* silently edit the operator's value.
|
|
134
|
+
*/
|
|
135
|
+
export declare function parseCell(type: ScalarType, text: string, required: boolean): {
|
|
136
|
+
ok: true;
|
|
137
|
+
value: string | number | boolean | undefined;
|
|
138
|
+
} | {
|
|
139
|
+
ok: false;
|
|
140
|
+
problem: CellProblem;
|
|
141
|
+
message: string;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* The text to put in a cell for an already-typed value.
|
|
145
|
+
*
|
|
146
|
+
* `undefined`/`null` render as the empty cell (never `"undefined"` or `"null"`);
|
|
147
|
+
* a string value for a string-ish column is shown as itself; a finite number
|
|
148
|
+
* and a boolean render as their JSON literals; anything else (an object cell,
|
|
149
|
+
* a `null` inside a document) falls back to its JSON text so the cell shows
|
|
150
|
+
* what the server holds rather than `[object Object]`.
|
|
151
|
+
*/
|
|
152
|
+
export declare function serializeCell(type: ScalarType, value: unknown): string;
|
|
153
|
+
/**
|
|
154
|
+
* Is an already-typed JSON value of `type`? The same rules {@linkcode parseCell}
|
|
155
|
+
* applies to text, applied to a value that came back from the server — the grid
|
|
156
|
+
* uses it to mark a row the server would refuse before the operator presses
|
|
157
|
+
* Save. `required` plays no part here: an absent value is the caller's problem
|
|
158
|
+
* to decide about, not this predicate's.
|
|
159
|
+
*/
|
|
160
|
+
export declare function isCellValue(type: ScalarType, value: unknown): boolean;
|
|
161
|
+
/** What is shown when the server said nothing a human can read. */
|
|
162
|
+
export declare const DATA_STORE_ERROR_FALLBACK = "The request failed.";
|
|
163
|
+
/** `rawRequest`'s `status: 0` — the request never reached the server. */
|
|
164
|
+
export declare const DATA_STORE_NETWORK_ERROR = "Could not reach the server.";
|
|
165
|
+
/** A failure, flattened into the fields the page needs and nothing else. */
|
|
166
|
+
export interface DataStoreErrorLocator {
|
|
167
|
+
/** Always present: the server's own sentence, or one of the two copy constants above. */
|
|
168
|
+
message: string;
|
|
169
|
+
/** The host's machine-readable code (`invalid_value`, `invalid_cursor`, …). */
|
|
170
|
+
code?: string;
|
|
171
|
+
/** The HTTP status; `0` is the transport-failure convention. */
|
|
172
|
+
status?: number;
|
|
173
|
+
/** The request-body field the host blamed. */
|
|
174
|
+
field?: string;
|
|
175
|
+
/** The 0-based CSV data row the host blamed (header excluded). */
|
|
176
|
+
row?: number;
|
|
177
|
+
/** The table column the host blamed. */
|
|
178
|
+
column?: string;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Locate a thrown JSON-call failure: an `ApiError` (whose parsed body lives on
|
|
182
|
+
* `.raw`), a plain `Error`, or anything else at all.
|
|
183
|
+
*
|
|
184
|
+
* The message falls back in that order — the envelope's `message`, the error's
|
|
185
|
+
* own `message`, then {@linkcode DATA_STORE_ERROR_FALLBACK} — so an unfamiliar
|
|
186
|
+
* throw still produces a sentence rather than an empty panel.
|
|
187
|
+
*/
|
|
188
|
+
export declare function locateDataStoreError(e: unknown): DataStoreErrorLocator;
|
|
189
|
+
/**
|
|
190
|
+
* Locate a CSV-call failure from P-RAW's `{status, text}` — the body is still
|
|
191
|
+
* unparsed text because that transport does not know the content type.
|
|
192
|
+
*
|
|
193
|
+
* `status: 0` means the request never produced a response, and gets the
|
|
194
|
+
* transport sentence rather than an attempt to parse an empty body. Otherwise
|
|
195
|
+
* the body is parsed iff it is JSON: an HTML error page from a proxy is
|
|
196
|
+
* `{status, message: fallback}`, not a crash.
|
|
197
|
+
*/
|
|
198
|
+
export declare function locateRawResponseError(res: {
|
|
199
|
+
status: number;
|
|
200
|
+
text: string;
|
|
201
|
+
}): DataStoreErrorLocator;
|
|
202
|
+
/** Where the message is rendered: under one table cell, under one form field, or over the whole form. */
|
|
203
|
+
export declare function errorPlacement(loc: DataStoreErrorLocator): {
|
|
204
|
+
kind: "cell";
|
|
205
|
+
column: string;
|
|
206
|
+
row?: number;
|
|
207
|
+
} | {
|
|
208
|
+
kind: "field";
|
|
209
|
+
field: string;
|
|
210
|
+
} | {
|
|
211
|
+
kind: "form";
|
|
212
|
+
};
|
|
213
|
+
/**
|
|
214
|
+
* The operator's 1-based line number in the CSV they uploaded, from the host's
|
|
215
|
+
* 0-based data-row index: the header row is line 1, so data row 0 is line 2.
|
|
216
|
+
*/
|
|
217
|
+
export declare function csvLineOf(row: number): number;
|
|
218
|
+
/**
|
|
219
|
+
* The draft id of a row that does not exist yet: a NUL-prefixed sentinel, which
|
|
220
|
+
* R-5 forbids a real key from ever being (no control characters in a key), so
|
|
221
|
+
* `id === NEW_ROW_ID` and "this row has no server-side key" are the same fact.
|
|
222
|
+
*/
|
|
223
|
+
export declare const NEW_ROW_ID = "\0new";
|
|
224
|
+
/** Rendered beside a row whose `ifVersion` was stale — never as the server's sentence alone. */
|
|
225
|
+
export declare const VERSION_CONFLICT_COPY = "Changed by someone else since you loaded it.";
|
|
226
|
+
/** A `doc` store holds a JSON object or array; anything else is not a document. */
|
|
227
|
+
export declare const DOC_VALUE_COPY = "Enter a JSON object or array.";
|
|
228
|
+
/** R-7's client-side ceiling copy — the check runs before anything is sent. */
|
|
229
|
+
export declare const CSV_TOO_LARGE_COPY = "The file is larger than 5 MB.";
|
|
230
|
+
/**
|
|
231
|
+
* One row's editable state: the id it is saved under (`entry.key`, or
|
|
232
|
+
* {@linkcode NEW_ROW_ID}), the version the save guards with (`null` for a new
|
|
233
|
+
* row) and the cell TEXT per declared column (never a parsed value — the text
|
|
234
|
+
* is what the operator is editing, and re-serialising it on every keystroke
|
|
235
|
+
* would fight their cursor).
|
|
236
|
+
*/
|
|
237
|
+
export interface RowDraft {
|
|
238
|
+
id: string;
|
|
239
|
+
version: number | null;
|
|
240
|
+
cells: Record<string, string>;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* An entry's value read as a table row: the object the server stored, or `{}`
|
|
244
|
+
* for anything that is not a plain object (a `null`, an array, a scalar from a
|
|
245
|
+
* column set that has since changed).
|
|
246
|
+
*/
|
|
247
|
+
export declare function rowValueOf(entry: Entry): Record<string, unknown>;
|
|
248
|
+
/** The draft an entry starts as: its key, its version, and each declared column's text. */
|
|
249
|
+
export declare function draftFromEntry(entry: Entry, columns: readonly TableColumn[]): RowDraft;
|
|
250
|
+
/**
|
|
251
|
+
* The draft a brand-new row starts as: {@linkcode NEW_ROW_ID}, no version, and
|
|
252
|
+
* each column seeded from its declared `default` (absent default = empty cell).
|
|
253
|
+
*/
|
|
254
|
+
export declare function newRowDraft(columns: readonly TableColumn[]): RowDraft;
|
|
255
|
+
/**
|
|
256
|
+
* Which declared columns the operator actually changed, in DECLARED order.
|
|
257
|
+
*
|
|
258
|
+
* Declared order (not object order) so the answer is stable across browsers and
|
|
259
|
+
* the row's Save button can decide "dirty" with one empty-array check. An
|
|
260
|
+
* untouched draft is `[]`.
|
|
261
|
+
*/
|
|
262
|
+
export declare function dirtyColumns(draft: RowDraft, base: RowDraft, columns: readonly TableColumn[]): string[];
|
|
263
|
+
/**
|
|
264
|
+
* The row body a Save sends, or the per-cell refusals that stop it.
|
|
265
|
+
*
|
|
266
|
+
* Every DECLARED column is parsed through {@linkcode parseCell} with its own
|
|
267
|
+
* `required` flag: an absent value omits the key entirely (R-7's empty-cell
|
|
268
|
+
* rule, so the host's default applies), a `string` cell keeps its text verbatim
|
|
269
|
+
* and every other type is the JSON value the server expects — never the typed
|
|
270
|
+
* text. Failures are keyed by column name so the caller renders them under the
|
|
271
|
+
* offending cell.
|
|
272
|
+
*/
|
|
273
|
+
export declare function buildRowValue(draft: RowDraft, columns: readonly TableColumn[]): {
|
|
274
|
+
ok: true;
|
|
275
|
+
value: Record<string, unknown>;
|
|
276
|
+
} | {
|
|
277
|
+
ok: false;
|
|
278
|
+
errors: Record<string, string>;
|
|
279
|
+
};
|
|
280
|
+
/**
|
|
281
|
+
* The `ttlSeconds` a save must resend so it does not CLEAR an existing expiry
|
|
282
|
+
* (S-1: a PUT without `ttlSeconds` sets `expires_at = NULL`).
|
|
283
|
+
*
|
|
284
|
+
* `undefined` for an entry that never expires, for an unparseable timestamp and
|
|
285
|
+
* for one already in the past — in all three cases sending nothing is correct
|
|
286
|
+
* (and a non-positive TTL is not a TTL the host accepts). Rounded UP, so a save
|
|
287
|
+
* one millisecond before the deadline does not shorten the entry's life.
|
|
288
|
+
*/
|
|
289
|
+
export declare function remainingTtlSeconds(expiresAt: string | null, nowMs: number): number | undefined;
|
|
290
|
+
/**
|
|
291
|
+
* Which request a draft implies: an INSERT (`POST entries`, no `ifVersion`) for
|
|
292
|
+
* a row that does not exist yet, otherwise a PUT under the row's key guarded by
|
|
293
|
+
* the version the operator loaded.
|
|
294
|
+
*
|
|
295
|
+
* `ttlSeconds` is present ONLY when the caller has one: it reaches the wire as
|
|
296
|
+
* a defining key, and an explicit `undefined` would be indistinguishable from
|
|
297
|
+
* "the caller measured nothing".
|
|
298
|
+
*/
|
|
299
|
+
export declare function rowWriteOf(draft: RowDraft, value: Record<string, unknown>, ttlSeconds: number | undefined): {
|
|
300
|
+
kind: "insert";
|
|
301
|
+
value: Record<string, unknown>;
|
|
302
|
+
ttlSeconds?: number;
|
|
303
|
+
} | {
|
|
304
|
+
kind: "put";
|
|
305
|
+
key: string;
|
|
306
|
+
value: Record<string, unknown>;
|
|
307
|
+
ifVersion: number;
|
|
308
|
+
ttlSeconds?: number;
|
|
309
|
+
};
|
|
310
|
+
/**
|
|
311
|
+
* The cell errors a refusal places, or `null` when it belongs somewhere else
|
|
312
|
+
* (the form, a request-body field, a column this table does not declare).
|
|
313
|
+
*
|
|
314
|
+
* `null` is load-bearing: the grid renders `grid-error` exactly when this
|
|
315
|
+
* returns `null`, so "the message shows in one slot" is a property of the
|
|
316
|
+
* answer rather than of the caller's care.
|
|
317
|
+
*/
|
|
318
|
+
export declare function cellErrorsOf(loc: DataStoreErrorLocator, columns: readonly TableColumn[]): Record<string, string> | null;
|
|
319
|
+
/**
|
|
320
|
+
* Is this failure the optimistic-concurrency refusal — and nothing else?
|
|
321
|
+
*
|
|
322
|
+
* `409` alone is not enough: `entry_exists` and `store_exists` share the status
|
|
323
|
+
* and neither is fixed by reloading, so both halves of the locator must agree.
|
|
324
|
+
*/
|
|
325
|
+
export declare function isVersionConflict(loc: DataStoreErrorLocator): boolean;
|
|
326
|
+
/**
|
|
327
|
+
* A `doc` store's value from the editor's text: any JSON object or array.
|
|
328
|
+
*
|
|
329
|
+
* A scalar is refused rather than wrapped — the store's own `doc` shape is an
|
|
330
|
+
* object/array (S-2), and the host would refuse `42` anyway; failing here means
|
|
331
|
+
* the operator sees why without a round trip. `null` parses but is not a
|
|
332
|
+
* document, so it is refused with the same sentence.
|
|
333
|
+
*/
|
|
334
|
+
export declare function parseDocText(text: string): {
|
|
335
|
+
ok: true;
|
|
336
|
+
value: object;
|
|
337
|
+
} | {
|
|
338
|
+
ok: false;
|
|
339
|
+
message: string;
|
|
340
|
+
};
|
|
341
|
+
/**
|
|
342
|
+
* A `kv` store's value from the editor's text.
|
|
343
|
+
*
|
|
344
|
+
* `string` is the one type whose text IS the value, empty string included (an
|
|
345
|
+
* empty `string` entry is a real value, not an absent one), so it never passes
|
|
346
|
+
* through {@linkcode parseCell} — which reads an empty cell as absent. Every
|
|
347
|
+
* other type is parsed exactly as a table cell would be, `required` on, because
|
|
348
|
+
* a kv entry always has a value.
|
|
349
|
+
*/
|
|
350
|
+
export declare function kvValueOf(type: ScalarType, text: string): {
|
|
351
|
+
ok: true;
|
|
352
|
+
value: unknown;
|
|
353
|
+
} | {
|
|
354
|
+
ok: false;
|
|
355
|
+
message: string;
|
|
356
|
+
};
|
|
357
|
+
/**
|
|
358
|
+
* What a CSV import's `RawResponse` says to the operator.
|
|
359
|
+
*
|
|
360
|
+
* The host is the only parser (R-7): a `200` reports how many rows it took, and
|
|
361
|
+
* a refusal is located rather than interpreted — a `row` becomes the operator's
|
|
362
|
+
* own 1-based line (`csvLineOf`), the `column` is named when the host named one,
|
|
363
|
+
* and everything else is the host's sentence verbatim.
|
|
364
|
+
*/
|
|
365
|
+
export declare function csvImportMessage(res: {
|
|
366
|
+
status: number;
|
|
367
|
+
text: string;
|
|
368
|
+
}): {
|
|
369
|
+
ok: boolean;
|
|
370
|
+
message: string;
|
|
371
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ActionParam, ParamOption, ResolveFieldsBody } from './types.ts';
|
|
2
|
+
/** Dynamic-field context a ParamsForm host passes. */
|
|
3
|
+
export interface DynamicContext {
|
|
4
|
+
appId: string;
|
|
5
|
+
actionKey: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
connectionId?: string;
|
|
8
|
+
appName?: string;
|
|
9
|
+
}
|
|
10
|
+
/** Form values split per D-5: resolvable go to `form`, expression/secret/`$`-object keys to `unresolved`. */
|
|
11
|
+
export interface FormSplit {
|
|
12
|
+
form: Record<string, unknown>;
|
|
13
|
+
unresolved: string[];
|
|
14
|
+
}
|
|
15
|
+
/** One planned call: the body minus `connectionId`/`version` (the hook adds them). */
|
|
16
|
+
export type PlannedRequest = Pick<ResolveFieldsBody, "reason" | "form" | "previous" | "changed" | "fields" | "unresolved">;
|
|
17
|
+
/** Outcome of reconciling a stored value against a returned option list. */
|
|
18
|
+
export interface Reconciled {
|
|
19
|
+
action: "keep" | "flag" | "clear";
|
|
20
|
+
/** Hint to show when `action === "flag"`. */
|
|
21
|
+
message?: string;
|
|
22
|
+
}
|
|
23
|
+
/** D-5: expression, secret, or a plain object with own key `$` can't be sent as a literal. */
|
|
24
|
+
export declare function isUnresolvedValue(v: unknown): boolean;
|
|
25
|
+
declare function allowCustomOf(p: ActionParam): boolean;
|
|
26
|
+
/** Params that request form-resolved options (top level + sections only). */
|
|
27
|
+
export declare function dynamicParams(params: ActionParam[]): ActionParam[];
|
|
28
|
+
/**
|
|
29
|
+
* Split flattened `values` (entered, else declared default) into `form` and
|
|
30
|
+
* `unresolved` (expression, secret, or plain object with own key `$`).
|
|
31
|
+
*/
|
|
32
|
+
export declare function splitForm(params: ActionParam[], values: Record<string, unknown>): FormSplit;
|
|
33
|
+
/**
|
|
34
|
+
* Plan the call for `reason`. `init`: every resolveFields field whose
|
|
35
|
+
* `refreshOn` keys are all resolved. `change`: only fields whose `refreshOn`
|
|
36
|
+
* contains `changed[0]` (and whose keys are all resolved). Returns null when no call is due.
|
|
37
|
+
* `previous` (raw pre-commit values) is split the same way and sent as `previous`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function planRequests(params: ActionParam[], values: Record<string, unknown>, reason: "init" | "change", changed?: string[], previous?: Record<string, unknown>): PlannedRequest | null;
|
|
40
|
+
/** Cache key `(app, version, action, connection, field, refreshOn values)`. */
|
|
41
|
+
export declare function cacheKey(ctx: DynamicContext, param: ActionParam, form: Record<string, unknown>): string;
|
|
42
|
+
/** Only `cache: "none"` opts out of the in-memory cache. */
|
|
43
|
+
export declare function isCacheable(param: ActionParam): boolean;
|
|
44
|
+
/** True when two requests' `fields` share a key (the newer aborts the older). */
|
|
45
|
+
export declare function fieldsOverlap(a: readonly string[], b: readonly string[]): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Why a dynamic field is NOT requested (A6), with the hint to show, or null
|
|
48
|
+
* when it is requestable.
|
|
49
|
+
*/
|
|
50
|
+
export declare function noFetchReason(param: ActionParam, params: ActionParam[], values: Record<string, unknown>, ctx: Pick<DynamicContext, "connectionId">): {
|
|
51
|
+
reason: "no-connection" | "unresolved-dependency";
|
|
52
|
+
hint: string;
|
|
53
|
+
} | null;
|
|
54
|
+
/** D-6: keep / flag / clear a stored value given the returned options. */
|
|
55
|
+
export declare function reconcileValue(value: unknown, options: ParamOption[], opts: {
|
|
56
|
+
allowCustom: boolean;
|
|
57
|
+
reason: "init" | "change";
|
|
58
|
+
appLabel: string;
|
|
59
|
+
}): Reconciled;
|
|
60
|
+
export { allowCustomOf };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE `EditorView.theme` spec shared by the three CodeMirror editors
|
|
3
|
+
* (`JsonEditor`, `CodeEditor`, `YamlEditor`) — previously copy-pasted verbatim
|
|
4
|
+
* into each of them.
|
|
5
|
+
*
|
|
6
|
+
* Plain object, **no imports**, so `node --test` asserts it directly. Every
|
|
7
|
+
* colour/spacing value is a `--w6w-*` custom property so the editors inherit
|
|
8
|
+
* the consumer's palette.
|
|
9
|
+
*
|
|
10
|
+
* Focus mirrors `styles/_fields.scss` (`.w6w-field input:focus { outline: none;
|
|
11
|
+
* border-color: var(--w6w-accent) }`) instead of drawing an accent ring. The
|
|
12
|
+
* rule must STAY with an explicit `outline: "none"` — deleting it falls back to
|
|
13
|
+
* CodeMirror's base theme (`outline: 1px dotted #212121` in
|
|
14
|
+
* `@codemirror/view`), which is still an outline.
|
|
15
|
+
*
|
|
16
|
+
* `".cm-scroller"`'s `borderRadius: "7px"` (8px − the 1px `"&"` border) clips
|
|
17
|
+
* the gutters and active line to the rounded border. `"&"` never gets
|
|
18
|
+
* `overflow: hidden`, which would clip lint/hover tooltips mounted inside the
|
|
19
|
+
* editor.
|
|
20
|
+
*
|
|
21
|
+
* `".cm-content"` only sets the vertical longhands: `styles/_fx.scss` owns
|
|
22
|
+
* `padding-right` while the ƒx/copy overlay is present.
|
|
23
|
+
*/
|
|
24
|
+
export declare const EDITOR_THEME_SPEC: Record<string, Record<string, string>>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ActionDef } from './types.ts';
|
|
2
|
+
export interface EventbriteTriggerChoices {
|
|
3
|
+
triggerKey: string;
|
|
4
|
+
options: {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
triggerKey: string;
|
|
8
|
+
}[];
|
|
9
|
+
selected: string[];
|
|
10
|
+
}
|
|
11
|
+
/** Eventbrite's activity trigger registers several events on one webhook. Keep its
|
|
12
|
+
* event catalog in the app manifest; the editor only adapts the existing trigger keys. */
|
|
13
|
+
export declare function eventbriteTriggerChoices(appId: string, triggers: ActionDef[] | null, triggerKey: string, values: Record<string, unknown>): EventbriteTriggerChoices | null;
|