api_binding_ui 1.0.0 → 1.1.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.
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # API Binding Studio (api_binding_ui)
2
2
 
3
- API Binding Studio (`api_binding_ui`) is an isolated, browser-side visual API mapping, simulation, and verification engine designed for enterprise web applications. It enables engineers, business analysts, and QA specialists to visually bind user interface components and action buttons to backend REST/OpenAPI endpoints, inspect live request payloads, and execute interactive end-to-end simulations without modifying production code or sending destructive mutations to live servers.
3
+ API Binding Studio (`api_binding_ui`) is a browser-side visual API mapper with generic offline request validation. Import OpenAPI contracts, propose editable component mappings, inspect request parts and validate their schemas without calling a server. Validation is not an end-to-end API test or proof of authorization/server behavior.
4
+
5
+ Version 1.1.0 adds `buildCatalogFromOpenApi(parsedDocument)`, operation descriptions/tags, location-aware parameters, JSON object conversion, headers, `validateRequest`, `validateBindings` and context-sensitive `verificationSignature`. The workspace uses the generic `ValidationDialog`; legacy note simulation exports remain available separately. See [SKILL.md](./SKILL.md) for the complete host integration and seed examples.
4
6
 
5
7
  ---
6
8
 
@@ -41,31 +43,22 @@ The studio UI relies entirely on design token custom properties:
41
43
 
42
44
  When rendered within an application that declares these variables, the studio immediately inherits the host styling. Standalone fallback values are bundled to ensure rendering fidelity when loaded outside the parent shell.
43
45
 
44
- ### 5. Zero-Network Simulation and Verification Engine (`src/components/SimulationDialog.tsx`)
46
+ ### 5. Zero-Network Request Validation (`src/components/ValidationDialog.tsx`)
45
47
  Before any configuration can be marked as verified or applied:
46
48
  - The engine constructs actual HTTP request payloads (headers, query parameters, path variables, request bodies).
47
49
  - Dynamic value coercion handles arrays (`number[]`, `string[]`), booleans, nested object dot-paths (`customer.billing.id`), and static text overrides.
48
- - An interactive simulation environment executes the mapped submission against sample datasets without initiating actual network fetch operations.
49
- - Verifications validate all required fields, parameter constraints, and record iterators before recording a cryptographic-style fingerprint of the verified configuration.
50
+ - Ajv validates supported JSON Schema request constraints for all configured read/write calls using captured or user-supplied sample inputs.
51
+ - Validation signatures cover configuration, contracts and captured context. They are consistency checks, not cryptographic security or server verification. No fake saved-record retrieval is required.
52
+ - Multiple selected rows can supply array values; scalar row parameters require one row. There is no live request executor or automatic per-row dispatch.
50
53
 
51
54
  ---
52
55
 
53
56
  ## Installation
54
57
 
55
- Add `api_binding_ui` to your application dependencies:
56
-
57
- ```json
58
- {
59
- "dependencies": {
60
- "api_binding_ui": "file:../api_binding_ui"
61
- }
62
- }
63
- ```
64
-
65
- Or via your package manager when using an internal package registry:
58
+ After the 1.1.0 release has been published, install it from npm:
66
59
 
67
60
  ```bash
68
- npm install api_binding_ui
61
+ npm install api_binding_ui@1.1.0
69
62
  # or
70
63
  yarn add api_binding_ui
71
64
  # or
@@ -131,10 +124,12 @@ export function App() {
131
124
 
132
125
  Place `<BindApiButton />` inside your modal dialogs, slide-out drawers, form panels, or screen toolbars.
133
126
 
127
+ Supply a complete `ApiDefinition[]` catalog and a per-window `MappingFile` seed. For an OpenAPI file attached to an AI coding task, generate the static catalog from the attachment; the app does not need to store or parse YAML at runtime. If the host already has a parsed OpenAPI 3.0/3.1 object, it may use `buildCatalogFromOpenApi(parsedOpenApi)`. Neither catalog discovery nor semantic mapping inference happens automatically at runtime. Have the host AI generate high-confidence seeds using OpenAPI names, descriptions, tags and actual components; leave ambiguities editable. A `hook` string identifies a catalog operation; it does not create an executable hook.
128
+
134
129
  #### Example A: Dialog with Data Grid Context
135
130
  ```tsx
136
131
  import * as React from "react";
137
- import { BindApiButton } from "api_binding_ui";
132
+ import { BindApiButton, type ApiDefinition, type MappingFile } from "api_binding_ui";
138
133
 
139
134
  interface CustomerRecord {
140
135
  customerId: number;
@@ -146,10 +141,14 @@ export function AddNotesModal({
146
141
  open,
147
142
  onClose,
148
143
  selectedCustomers,
144
+ definitions,
145
+ mappingFile,
149
146
  }: {
150
147
  open: boolean;
151
148
  onClose: () => void;
152
149
  selectedCustomers: CustomerRecord[];
150
+ definitions: ApiDefinition[];
151
+ mappingFile: MappingFile;
153
152
  }) {
154
153
  if (!open) return null;
155
154
 
@@ -201,6 +200,8 @@ export function AddNotesModal({
201
200
  </button>
202
201
 
203
202
  <BindApiButton
203
+ definitions={definitions}
204
+ mappingFile={mappingFile}
204
205
  appId="collections"
205
206
  windowId="worklist-add-notes"
206
207
  source="Add Notes Dialog"
@@ -223,9 +224,9 @@ export function AddNotesModal({
223
224
  #### Example B: Standalone Screen or Drawer without a Grid
224
225
  ```tsx
225
226
  import * as React from "react";
226
- import { BindApiButton } from "api_binding_ui";
227
+ import { BindApiButton, type ApiDefinition, type MappingFile } from "api_binding_ui";
227
228
 
228
- export function CreateDisputeDrawer({ isOpen, onClose }: { isOpen: boolean; onClose: () => void }) {
229
+ export function CreateDisputeDrawer({ isOpen, onClose, definitions, mappingFile }: { isOpen: boolean; onClose: () => void; definitions: ApiDefinition[]; mappingFile: MappingFile }) {
229
230
  if (!isOpen) return null;
230
231
 
231
232
  const reasonCodes = [
@@ -256,6 +257,8 @@ export function CreateDisputeDrawer({ isOpen, onClose }: { isOpen: boolean; onCl
256
257
  <button type="submit">Submit Dispute</button>
257
258
 
258
259
  <BindApiButton
260
+ definitions={definitions}
261
+ mappingFile={mappingFile}
259
262
  appId="receivables"
260
263
  windowId="dispute-create"
261
264
  source="Create Dispute"
@@ -279,14 +282,14 @@ export function CreateDisputeDrawer({ isOpen, onClose }: { isOpen: boolean; onCl
279
282
 
280
283
  | Prop | Type | Default | Description |
281
284
  | :--- | :--- | :--- | :--- |
282
- | `appId` | `string` | `"default"` | Identifier of the parent application module. |
285
+ | `appId` | `string` | `"app"` | Identifier of the parent application module. |
283
286
  | `windowId` | `string` | *(Required)* | Stable identifier of the screen, dialog, or form. |
284
287
  | `source` | `string` | *(Required)* | Human-readable title of the current screen or action. |
285
288
  | `parent` | `string` | *(Required)* | Human-readable title of the parent view or grid. |
286
289
  | `grid` | `BindingGrid` | `undefined` | Grid context including `gridId`, `columns`, and `rows` when actions target selected records. |
287
290
  | `parents` | `SnapshotContext[]` | `undefined` | Array of parent context hierarchies for multi-level navigation. |
288
291
  | `kind` | `WindowKind` | Automatic | `"dialog" \| "drawer" \| "screen" \| "action-form"`. Detected automatically if omitted. |
289
- | `trigger` | `WindowTrigger` | `undefined` | Metadata regarding the invocation trigger (button text, hotkey, icon). |
292
+ | `trigger` | `WindowTrigger` | `undefined` | Invocation metadata: `button`, `needsSelection`, `gridId`. |
290
293
  | `options` | `Record<string, BindingOption[]>` | `{}` | Lookup options for select and combobox fields. Supports `{ value, label, subject, description }`. |
291
294
  | `definitions` | `ApiDefinition[]` | `[]` | Registered API endpoints catalog available for mapping. |
292
295
  | `mappingFile` | `MappingFile \| null` | `null` | Pre-existing mapping file to preload. |
@@ -334,6 +337,7 @@ When an engineer or analyst clicks **Apply Binding** inside the Studio, the veri
334
337
  Host components can listen to applied bindings using the `useAppliedBinding` hook:
335
338
 
336
339
  ```tsx
340
+ import * as React from "react";
337
341
  import { useAppliedBinding } from "api_binding_ui";
338
342
 
339
343
  export function AddNotesModal() {
@@ -356,6 +360,8 @@ export function AddNotesModal() {
356
360
 
357
361
  ## Testing and Verification
358
362
 
363
+ `useAppliedBinding` observes stored configuration only; the host retains responsibility for any live execution, response-to-field population and durable persistence. Draft edits take precedence over new seeds. Captured context lives in same-origin browser storage; exclude sensitive fields and keep credentials out of snapshots and fixed values. External schema references must be bundled before import. Cookie parameters, non-JSON bodies, non-object root bodies and unsupported wire serialization produce contract limitations rather than network fallbacks.
364
+
359
365
  Run test suites using the bundled test runner:
360
366
 
361
367
  ```bash
@@ -377,6 +383,10 @@ The build produces:
377
383
  - `dist/api-binding-ui.css`: Compiled style bundle with `--ds-*` design token bridges.
378
384
  - `dist/**/*.d.ts`: TypeScript declaration definitions.
379
385
 
386
+ ## Manual Release
387
+
388
+ The original Bun/PowerShell build scripts are unchanged. Run `bun test`, `bun run build`, then `npm pack --dry-run` and inspect the archive/exports. Publish version 1.1.0 yourself using `npm publish` after reviewing the diff. This project has not been published automatically. The Lovable handoff prompt is a separate local document, not part of the npm package's files list.
389
+
380
390
  ---
381
391
 
382
392
  ## License
package/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: api-binding-ui
3
- description: Instructions for AI agents to integrate API Binding Studio (api_binding_ui) into React application screens, modals, drawers, and forms.
3
+ description: "Use when integrating api_binding_ui into React screens, dialogs, drawers or forms, importing OpenAPI contracts, proposing component mappings, or validating requests offline."
4
4
  ---
5
5
 
6
6
  # API Binding Studio Integration Skill
@@ -21,17 +21,51 @@ Apply this skill whenever any of the following conditions are met:
21
21
 
22
22
  ## 2. Dependency Verification
23
23
 
24
- Verify that `package.json` contains `api_binding_ui`:
24
+ Install the published release using the host's package manager and update its existing lockfile:
25
25
 
26
- ```json
27
- {
28
- "dependencies": {
29
- "api_binding_ui": "file:../api_binding_ui"
30
- }
31
- }
26
+ ```bash
27
+ npm install api_binding_ui
28
+ ```
29
+
30
+ Use the published package from the host project's package manager. Do not use a local filesystem dependency in a deployed project.
31
+
32
+ ### Catalog And Proposed Mappings Are Host Responsibilities
33
+
34
+ The package performs visual mapping and offline request validation, not live API execution or runtime AI inference. Lovable's AI should inspect the host components and attached OpenAPI descriptions/tags, then generate editable per-window `MappingFile` seeds. `proposeConfig` imports those seeds; it does not guess endpoints.
35
+
36
+ For an OpenAPI file attached to an AI coding task, have the AI generate a static typed `ApiDefinition[]` module from that file; do not copy the YAML into the app or add a runtime YAML parser just for binding. `buildCatalogFromOpenApi` is available when a host already has a parsed OpenAPI 3.0/3.1 object, but is not required for a generated static catalog. The catalog should preserve operationId, summary, description, tags, parameter descriptions and request schemas. `definitions` must be passed to every `BindApiButton` through a shared host wrapper; the default is an empty array, not automatic API discovery. `hook` is a catalog identifier, not a callable client.
37
+
38
+ Use the exported `windowIds` and `componentId` helpers instead of deriving keys or action names twice:
39
+
40
+ ```tsx
41
+ import { componentId, windowIds, type MappingFile } from "api_binding_ui";
42
+
43
+ const ids = windowIds({ appId: "collections", gridId: "worklistUIGrid", windowId: "worklist-add-notes" });
44
+ export const mappingFile: MappingFile = {
45
+ key: ids.key,
46
+ app: ids.appId,
47
+ grid: ids.gridId,
48
+ window: ids.windowId,
49
+ name: "Add Notes",
50
+ savedAt: new Date().toISOString(),
51
+ read: [],
52
+ write: [{
53
+ component: componentId({ kind: "button", name: "Submit" }),
54
+ api: "/cls/v1/notes",
55
+ method: "POST",
56
+ params: [
57
+ { param: "noteSubject", in: "body", source: "subject", property: "subject" },
58
+ { param: "noteDescription", in: "body", source: "notes", property: "notes" },
59
+ { param: "noteTypeId", in: "body", source: "notesType", property: "notesType" },
60
+ { param: "customerId", in: "body", source: "worklistUIGrid", property: "worklistUIGrid.customerId" },
61
+ ],
62
+ }],
63
+ };
32
64
  ```
33
65
 
34
- If missing, add it to dependencies or prompt the user to link the local package.
66
+ This example assumes the real button is Submit, option values are numeric note-type IDs and exactly one customer is selected. Use actual host IDs and labels. `noteType` is a separate string property from `noteTypeId`. Never rename API fields to fit a simulator, substitute a customer ID for a note ID, or fabricate lookup APIs. Multiple selected rows feed comma-joined array values; scalar parameters require one row. The package does not dispatch one live request per row.
67
+
68
+ Match APIs using component labels/names, window and parent entity, operationId, summary, description, tags and schema compatibility. POST search operations are reads. Automatically populate only high-confidence mappings; leave missing or ambiguous sources unresolved with a report. Do not invent IDs, credentials or defaults. Fields use their actual names as sources, parents use `<windowId>.<fieldName>`, and literals use the exported `FREE_TEXT_SOURCE` with the literal in `property`. Preserve `in` to distinguish same-name path/body/query/header parameters.
35
69
 
36
70
  ---
37
71
 
@@ -70,6 +104,8 @@ export function ApiBindingRoute() {
70
104
  }
71
105
  ```
72
106
 
107
+ Register this component explicitly in the existing React Router tree with `<Route path="/api-binding/:key" element={<ApiBindingRoute />} />`; the component alone does not register a route. Do not add a second BrowserRouter. For TanStack, follow the host's existing file/code route conventions. Import package CSS once. The studio opens a named same-origin tab inside the host app; verify popup permissions, direct-route refresh and deployment fallback routing.
108
+
73
109
  ---
74
110
 
75
111
  ## 4. Host Form Integration Rules
@@ -130,7 +166,7 @@ If the screen does not operate on a grid (such as a standalone dispute creation
130
166
  ### Pattern A: Modal Dialog Triggered from a Data Grid
131
167
  ```tsx
132
168
  import * as React from "react";
133
- import { BindApiButton } from "api_binding_ui";
169
+ import { BindApiButton, type ApiDefinition, type MappingFile } from "api_binding_ui";
134
170
 
135
171
  interface CustomerRecord {
136
172
  customerId: number;
@@ -141,10 +177,14 @@ export function AddNotesModal({
141
177
  open,
142
178
  onClose,
143
179
  selectedCustomers,
180
+ definitions,
181
+ mappingFile,
144
182
  }: {
145
183
  open: boolean;
146
184
  onClose: () => void;
147
185
  selectedCustomers: CustomerRecord[];
186
+ definitions: ApiDefinition[];
187
+ mappingFile: MappingFile;
148
188
  }) {
149
189
  if (!open) return null;
150
190
 
@@ -190,6 +230,8 @@ export function AddNotesModal({
190
230
  <button type="submit">Submit</button>
191
231
 
192
232
  <BindApiButton
233
+ definitions={definitions}
234
+ mappingFile={mappingFile}
193
235
  appId="collections"
194
236
  windowId="worklist-add-notes"
195
237
  source="Add Notes"
@@ -212,9 +254,9 @@ export function AddNotesModal({
212
254
  ### Pattern B: Standalone Drawer or Form without Grid
213
255
  ```tsx
214
256
  import * as React from "react";
215
- import { BindApiButton } from "api_binding_ui";
257
+ import { BindApiButton, type ApiDefinition, type MappingFile } from "api_binding_ui";
216
258
 
217
- export function DisputeDrawer({ open, onClose }: { open: boolean; onClose: () => void }) {
259
+ export function DisputeDrawer({ open, onClose, definitions, mappingFile }: { open: boolean; onClose: () => void; definitions: ApiDefinition[]; mappingFile: MappingFile }) {
218
260
  if (!open) return null;
219
261
 
220
262
  const disputeReasons = [
@@ -245,6 +287,8 @@ export function DisputeDrawer({ open, onClose }: { open: boolean; onClose: () =>
245
287
  <button type="submit">Submit Dispute</button>
246
288
 
247
289
  <BindApiButton
290
+ definitions={definitions}
291
+ mappingFile={mappingFile}
248
292
  appId="receivables"
249
293
  windowId="disputes-create"
250
294
  source="Create Dispute"
@@ -264,9 +308,10 @@ export function DisputeDrawer({ open, onClose }: { open: boolean; onClose: () =>
264
308
 
265
309
  ## 6. Listening to Applied Configurations
266
310
 
267
- When the user verifies and applies an API binding inside the Studio, the configuration is stored in browser storage. The parent screen can react to this using `useAppliedBinding`:
311
+ When the user validates requests and applies a binding, the configuration is stored in browser storage. `useAppliedBinding` only observes it: it does not submit requests, populate fields from responses, or write repository files. Preserve existing host API clients/runtime behavior. Live execution is a separate integration task.
268
312
 
269
313
  ```tsx
314
+ import * as React from "react";
270
315
  import { useAppliedBinding } from "api_binding_ui";
271
316
 
272
317
  export function ScreenComponent() {
@@ -292,3 +337,14 @@ Before completing an integration task, the AI agent must verify:
292
337
  3. Dropdown choices are forwarded in the `options` record.
293
338
  4. The application router has an active route at `/api-binding/$key` mounting `<ApiBindingWorkspace />`.
294
339
  5. No emojis or informal characters are introduced into the code or documentation.
340
+ 6. Every trigger supplies the contract `definitions` and its own proposed/saved `mappingFile`. Existing browser drafts take precedence over seeds; never erase all browser storage to refresh defaults.
341
+ 7. Portal/custom controls are scoped to their actual owner using `containerRef`, `containerSelector`, `rootElement` or `formId`. Custom widgets expose their real values through `name`/`data-value` or a complete `components` override; `components` and `buttons` replace, not append to, discovery.
342
+ 8. Pass actual dropdown options and live selected rows. Use `notifySelectionUpdate(pageKey, { id: gridId, rows })` when selection changes while the studio is open. Forward `parents`, `kind` and `trigger` through host wrappers.
343
+ 9. Validate all configured read/write requests through the generic Validate dialog, including read-only mappings and non-Submit buttons. Offline validation covers request constraints, not network access, authorization, responses or business success. Legacy `simulateSave`/`SimulationDialog` remain note-specific exports and are not the workspace's validation flow.
344
+ 10. Config, contract and captured source changes require revalidation; existing draft mappings survive the upgrade but old verification tokens do not authorize Apply. Never manually forge applied storage or signatures.
345
+ 11. Do not capture passwords, tokens or secrets in snapshots/options/mappings. Pass an explicit safe component list for sensitive forms and keep authentication in the existing secure client. Browser snapshots, selections and drafts contain captured data and are not shared server-side persistence.
346
+ 12. Run host tests/typecheck/build and browser-check every binding trigger, selected-row updates, standalone forms, similar window names, popup restrictions, existing drafts, metadata and desktop/mobile layout. Confirm that opening, previewing and validating send no API request.
347
+
348
+ ## Migration From api-binding-studio
349
+
350
+ The older wrapper's `apiInfoList`, `onSave` and `grid.id` are not new-button props. Replace them with `definitions`, `mappingFile` and `grid.gridId`. The package renders its own button: do not nest another Button inside it. A browser Apply does not replace a server-side source-file save handler. Preserve or explicitly report legacy file persistence/runtime behavior rather than claiming it was migrated automatically. Prepare the host changes inside the Lovable app only; do not copy this package's studio code.
@@ -5,6 +5,10 @@
5
5
 
6
6
 
7
7
  /* src/styles/workspace.css */
8
+ .binding-workspace, .binding-workspace * {
9
+ box-sizing: border-box;
10
+ }
11
+
8
12
  .binding-workspace, .api-binding, .binding-v2 {
9
13
  display: flex;
10
14
  background: var(--ds-color-background, #fff);
@@ -0,0 +1,8 @@
1
+ import * as React from "react";
2
+ import type { ApiBindingConfig, ApiBindingContext } from "../types";
3
+ export declare function ValidationDialog({ config, context, onClose, onVerified }: {
4
+ config: ApiBindingConfig;
5
+ context: ApiBindingContext;
6
+ onClose: () => void;
7
+ onVerified: (signature: string) => void;
8
+ }): React.JSX.Element;
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { ActionContext, ApiBindingConfig, ApiBindingContext, ApiDefinition, BindingCall, BindingPurpose, ParamMapping, RequestPreviewItem, SampleNote, SimulationInput } from "../types";
6
6
  import { isButtonId } from "./componentId";
7
- export declare const CONFIG_VERSION = 1;
7
+ export declare const CONFIG_VERSION = 2;
8
8
  export declare const draftKey: (key: string) => string;
9
9
  export declare const appliedKey: (key: string) => string;
10
10
  export declare const fingerprint: (config: ApiBindingConfig) => string;
@@ -49,6 +49,12 @@ export declare function simulateSave(config: ApiBindingConfig, context: ApiBindi
49
49
  errors: string[];
50
50
  requests: RequestPreviewItem[];
51
51
  };
52
+ export declare function validateBindings(config: ApiBindingConfig, context: ApiBindingContext, form?: {
53
+ [k: string]: string;
54
+ }): string[];
55
+ export declare function verificationSignature(config: ApiBindingConfig, context: ApiBindingContext, form?: {
56
+ [k: string]: string;
57
+ }): string;
52
58
  export declare function canApply(config: ApiBindingConfig, context: ApiBindingContext, verified: string | null): boolean;
53
59
  export declare function fieldSummary(config: ApiBindingConfig, context: ApiBindingContext, name: string): {
54
60
  from: string;
@@ -0,0 +1,2 @@
1
+ import type { ApiDefinition } from "../types";
2
+ export declare function buildCatalogFromOpenApi(document: unknown): ApiDefinition[];
@@ -0,0 +1,2 @@
1
+ import type { ApiDefinition, RequestParts } from "../types";
2
+ export declare function validateRequest(parts: RequestParts, definition: ApiDefinition): string[];
@@ -11,4 +11,7 @@ export declare function coerceScalar(text: string, base: string): Scalar | undef
11
11
  export declare function coerce(text: string, type: string): Scalar | Scalar[] | undefined;
12
12
  export declare const FREE_TEXT_SOURCE = "freeText";
13
13
  export declare function resolveParam(p: ParamMapping, ctx: ActionContext): string | undefined;
14
+ export declare const parameterKey: (name: string, location?: string) => string;
15
+ export declare function parameterFor(mapping: ParamMapping, spec: ApiParameter[]): ApiParameter | undefined;
16
+ export declare function coerceValue(text: string, spec: ApiParameter): unknown;
14
17
  export declare function buildRequest(mappings: ParamMapping[], ctx: ActionContext, spec: ApiParameter[]): RequestParts;
package/dist/index.css CHANGED
@@ -5,6 +5,10 @@
5
5
 
6
6
 
7
7
  /* src/styles/workspace.css */
8
+ .binding-workspace, .binding-workspace * {
9
+ box-sizing: border-box;
10
+ }
11
+
8
12
  .binding-workspace, .api-binding, .binding-v2 {
9
13
  display: flex;
10
14
  background: var(--ds-color-background, #fff);
package/dist/index.d.ts CHANGED
@@ -3,12 +3,14 @@
3
3
  */
4
4
  import "./styles/index.css";
5
5
  export * from "./types";
6
- export { CONFIG_VERSION, SUBMIT, CANCEL, CUSTOMER_PARAM, draftKey, appliedKey, fingerprint, newCallId, definitionFor, methodsFor, apisOf, fieldId, reconcileCallParams, proposeConfig, reconcileConfig, migrateConfig, callsFor, changeCallTarget, droppedBy, populated, changePurpose, newCall, moveCall, setParamSource, gridPaths, componentLabel, endpointLabel, callIssues, issuesFor, actionContext, snapshotForm, resolutionIssues, previewRequests, isNoteContract, isSimulated, simulatorGaps, simulationErrors, simulationForm, simulateSave, canApply, fieldSummary, isButton, } from "./core/model";
6
+ export { CONFIG_VERSION, SUBMIT, CANCEL, CUSTOMER_PARAM, draftKey, appliedKey, fingerprint, newCallId, definitionFor, methodsFor, apisOf, fieldId, reconcileCallParams, proposeConfig, reconcileConfig, migrateConfig, callsFor, changeCallTarget, droppedBy, populated, changePurpose, newCall, moveCall, setParamSource, gridPaths, componentLabel, endpointLabel, callIssues, issuesFor, actionContext, snapshotForm, resolutionIssues, previewRequests, isNoteContract, isSimulated, simulatorGaps, simulationErrors, simulationForm, simulateSave, canApply, validateBindings, verificationSignature, fieldSummary, isButton, } from "./core/model";
7
7
  export { contextKey, storeBindingContext, readBindingContext, validBindingContext, validContext, openBindingStudio, notifyApplied, notifySelectionUpdate, type OpenStudioOptions, } from "./core/transport";
8
8
  export { friendlyLabel, buildCatalogFromRegistry, type RawBindings, } from "./core/catalog";
9
+ export { buildCatalogFromOpenApi } from "./core/openapi";
10
+ export { validateRequest } from "./core/validation";
9
11
  export { FREE_TEXT_SOURCE, FREE_TEXT_OPTION, storageKey, storeSnapshot, readSnapshot, windowIds, gridPropertyPaths, contextComponents, sourceComponents, discoverFormComponents, discoverButtons, buildSnapshot, } from "./core/bindingContext";
10
12
  export { componentId, isButtonId, parseComponentId, normalizeComponent, type ComponentDescriptor, } from "./core/componentId";
11
- export { baseType, coerceScalar, coerce, resolveParam, buildRequest, type Scalar, } from "./core/valueCoercion";
13
+ export { baseType, coerceScalar, coerce, resolveParam, buildRequest, parameterKey, parameterFor, coerceValue, type Scalar, } from "./core/valueCoercion";
12
14
  export { useAppliedBinding } from "./hooks/useAppliedBinding";
13
15
  export { BindApiButton, type BindApiButtonProps } from "./components/BindApiButton";
14
16
  export { ApiBindingWorkspace, ApiBindingStudio, type ApiBindingWorkspaceProps } from "./components/ApiBindingWorkspace";
@@ -16,6 +18,7 @@ export { WorkspaceComponentsProvider, useWorkspaceComponents } from "./component
16
18
  export { ApiMappings } from "./components/ApiMappings";
17
19
  export { RequestPreview } from "./components/RequestPreview";
18
20
  export { SimulationDialog } from "./components/SimulationDialog";
21
+ export { ValidationDialog } from "./components/ValidationDialog";
19
22
  export { AppGrid, createActionColumn, type AppGridColDef, type AppGridProps } from "./components/ui/AppGrid";
20
23
  export { Button, ButtonBar, ButtonGroup, type ButtonProps } from "./components/ui/Button";
21
24
  export { Badge, type BadgeProps } from "./components/ui/Badge";