api_binding_ui 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +74 -394
  2. package/SKILL.md +49 -350
  3. package/dist/framework/contract.d.ts +268 -0
  4. package/dist/framework/engine.d.ts +88 -0
  5. package/dist/framework/expr.d.ts +34 -0
  6. package/dist/framework/loadCatalog.d.ts +6 -0
  7. package/dist/framework/names.d.ts +7 -0
  8. package/dist/framework/openapi.d.ts +7 -0
  9. package/dist/framework/runner.d.ts +33 -0
  10. package/dist/framework/schema.d.ts +22 -0
  11. package/dist/framework/store.d.ts +17 -0
  12. package/dist/framework/validate.d.ts +7 -0
  13. package/dist/index-e9twc25y.js +754 -0
  14. package/dist/index-e9twc25y.js.map +16 -0
  15. package/dist/index.d.ts +11 -29
  16. package/dist/index.js +345 -11932
  17. package/dist/index.js.map +14 -0
  18. package/dist/runtime/BindingProvider.d.ts +42 -0
  19. package/dist/runtime/BindingScreen.d.ts +23 -0
  20. package/dist/runtime/hooks.d.ts +22 -0
  21. package/dist/runtime/screenStore.d.ts +7 -0
  22. package/dist/studio/ApiPicker.d.ts +15 -0
  23. package/dist/studio/BindingStudio.d.ts +21 -0
  24. package/dist/studio/BindingWidget.d.ts +9 -0
  25. package/dist/studio/Collapse.d.ts +6 -0
  26. package/dist/studio/ComponentList.d.ts +10 -0
  27. package/dist/studio/FindAnything.d.ts +7 -0
  28. package/dist/studio/Inspector.d.ts +12 -0
  29. package/dist/studio/Navigator.d.ts +17 -0
  30. package/dist/studio/SettingsPanel.d.ts +15 -0
  31. package/dist/studio/Tip.d.ts +23 -0
  32. package/dist/studio/editors/ConsumeEditor.d.ts +4 -0
  33. package/dist/studio/editors/RequestInputs.d.ts +11 -0
  34. package/dist/studio/editors/ScopedEditor.d.ts +3 -0
  35. package/dist/studio/editors/SlotSection.d.ts +3 -0
  36. package/dist/studio/editors/SourceSelect.d.ts +10 -0
  37. package/dist/studio/editors/StepCard.d.ts +12 -0
  38. package/dist/studio/editors/TriggerEditor.d.ts +4 -0
  39. package/dist/studio/editors/types.d.ts +14 -0
  40. package/dist/studio/icons.d.ts +65 -0
  41. package/dist/studio/index.css +2021 -0
  42. package/dist/studio/index.d.ts +3 -0
  43. package/dist/studio/index.js +2806 -0
  44. package/dist/studio/index.js.map +33 -0
  45. package/dist/studio/useBindings.d.ts +20 -0
  46. package/dist/studio/useCatalog.d.ts +15 -0
  47. package/dist/studio/useGlide.d.ts +11 -0
  48. package/dist/studio/useSettings.d.ts +8 -0
  49. package/package.json +20 -14
  50. package/spec/FRAMEWORK.md +271 -0
  51. package/dist/api-binding-ui.css +0 -248
  52. package/dist/components/ApiBindingWorkspace.d.ts +0 -10
  53. package/dist/components/ApiMappings.d.ts +0 -21
  54. package/dist/components/BindApiButton.d.ts +0 -41
  55. package/dist/components/RequestPreview.d.ts +0 -7
  56. package/dist/components/SimulationDialog.d.ts +0 -8
  57. package/dist/components/ValidationDialog.d.ts +0 -8
  58. package/dist/components/WorkspaceContext.d.ts +0 -7
  59. package/dist/components/ui/AppGrid.d.ts +0 -27
  60. package/dist/components/ui/Badge.d.ts +0 -9
  61. package/dist/components/ui/Banner.d.ts +0 -8
  62. package/dist/components/ui/Button.d.ts +0 -31
  63. package/dist/components/ui/Card.d.ts +0 -14
  64. package/dist/components/ui/Dialog.d.ts +0 -61
  65. package/dist/components/ui/Icons.d.ts +0 -21
  66. package/dist/components/ui/Input.d.ts +0 -31
  67. package/dist/core/bindingContext.d.ts +0 -67
  68. package/dist/core/catalog.d.ts +0 -18
  69. package/dist/core/componentId.d.ts +0 -12
  70. package/dist/core/model.d.ts +0 -63
  71. package/dist/core/openapi.d.ts +0 -2
  72. package/dist/core/transport.d.ts +0 -33
  73. package/dist/core/validation.d.ts +0 -2
  74. package/dist/core/valueCoercion.d.ts +0 -17
  75. package/dist/hooks/useAppliedBinding.d.ts +0 -6
  76. package/dist/index.css +0 -248
  77. package/dist/style.css +0 -244
  78. package/dist/types.d.ts +0 -245
@@ -0,0 +1,88 @@
1
+ /** Matching, proposals and status for bindings. Generic: no kinds, products or field names. */
2
+ import type { OperationConsumeBinding, BindId, Catalog, ComponentDescriptor, ComponentInstance, ContextDeclaration, ContextProvider, Glossary, ScreenEntry, ScreenId, ScreenRegistry, SlotBinding, SlotDescriptor, TransformDefinition } from "./contract";
3
+ import { type Field, type OpView } from "./schema";
4
+ export type { Field, OpView, ReqField } from "./schema";
5
+ export { opViews } from "./schema";
6
+ export { humanize, words } from "./names";
7
+ export interface FrameworkData {
8
+ descriptors: ComponentDescriptor[];
9
+ registry: ScreenRegistry;
10
+ catalog: Catalog;
11
+ transforms?: TransformDefinition[];
12
+ providers?: ContextProvider[];
13
+ glossaries?: Glossary[];
14
+ }
15
+ export interface Source {
16
+ expr: string;
17
+ label: string;
18
+ name?: string;
19
+ type: string;
20
+ group: "item" | "screen" | "context" | "provider";
21
+ fields?: Field[];
22
+ /** Set when the value's shape is not known yet: names the slot that must be connected first. */
23
+ waitsFor?: string;
24
+ }
25
+ export interface Ranked {
26
+ view: OpView;
27
+ score: number;
28
+ reasons: string[];
29
+ }
30
+ export type SlotState = "bound" | "suggested" | "unbound";
31
+ export type BindingIndex = Record<ScreenId, SlotBinding[]>;
32
+ export declare function createEngine(fw: FrameworkData, manifests: BindingIndex): {
33
+ fw: FrameworkData;
34
+ OPV: Map<string, OpView>;
35
+ OPS: OpView[];
36
+ DESC: Map<string, ComponentDescriptor>;
37
+ SCR: Map<string, ScreenEntry>;
38
+ getB: (s: ScreenId, c: BindId, sl: string) => SlotBinding | undefined;
39
+ screen: (id: ScreenId) => ScreenEntry;
40
+ compOf: (s: ScreenId, id: BindId) => ComponentInstance | undefined;
41
+ descOf: (c: ComponentInstance) => ComponentDescriptor | undefined;
42
+ bindable: (d: ComponentDescriptor | undefined) => SlotDescriptor[];
43
+ typeFit: (target: string, source: string) => {
44
+ ok: boolean;
45
+ transform?: string;
46
+ };
47
+ shapeOf: (s: ScreenId, comp: ComponentInstance, slot: SlotDescriptor) => {
48
+ many: boolean;
49
+ fields?: Field[];
50
+ type?: string;
51
+ via?: string;
52
+ };
53
+ contextShape: (ctx: ContextDeclaration) => {
54
+ many: boolean;
55
+ fields: Field[];
56
+ };
57
+ scopeFields: (s: ScreenId, comp: ComponentInstance, slot: SlotDescriptor) => Field[] | null;
58
+ sources: (s: ScreenId, opts?: {
59
+ item?: Field[];
60
+ }) => Source[];
61
+ triggerSources: (s: ScreenId, item?: Field[]) => Source[];
62
+ bestSource: (targetName: string, targetType: string, srcs: Source[]) => {
63
+ expr: string;
64
+ score: number;
65
+ source: Source;
66
+ };
67
+ rankSources: (targetName: string, targetType: string, srcs: Source[], min?: number) => {
68
+ expr: string;
69
+ score: number;
70
+ source: Source;
71
+ }[];
72
+ proposeRequest: (v: OpView, srcs: Source[]) => Record<string, string>;
73
+ proposeMap: (slotFields: Field[], itemFields: Field[]) => Record<string, string>;
74
+ rank: (s: ScreenId, comp: ComponentInstance, slot: SlotDescriptor) => Ranked[];
75
+ slotState: (s: ScreenId, c: BindId, sl: string) => SlotState;
76
+ compState: (s: ScreenId, comp: ComponentInstance) => SlotState | "partial";
77
+ tally: (screens: ScreenEntry[]) => {
78
+ bound: number;
79
+ suggested: number;
80
+ unbound: number;
81
+ total: number;
82
+ };
83
+ manyContext: (s: ScreenId) => ContextDeclaration | undefined;
84
+ fieldsAt: (v: OpView, select: string) => Field[];
85
+ proposeConsume: (s: ScreenId, comp: ComponentInstance, slot: SlotDescriptor, opId: string, strict?: boolean) => OperationConsumeBinding | null;
86
+ siblingFills: (s: ScreenId, comp: ComponentInstance, slot: SlotDescriptor, opId: string) => OperationConsumeBinding[];
87
+ };
88
+ export type Engine = ReturnType<typeof createEngine>;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Expression evaluator (FRAMEWORK.md §7). One grammar for every source:
3
+ *
4
+ * <bindId>.<slot>[.path] a produce slot on this screen
5
+ * $item[.path] the current item (scoped slot or forEach)
6
+ * $context.<id>[.path] a value the screen received
7
+ * $steps.<stepId>[.path] an earlier call step's result ({ response })
8
+ * $<provider>[.path] a registered context provider
9
+ * <expr>[*].<path> every item of a list
10
+ * <expr> | name(args) a registered transform
11
+ *
12
+ * Nothing outside this grammar is evaluated; unknown heads resolve to undefined.
13
+ */
14
+ export type Transforms = Record<string, (value: unknown, ...args: unknown[]) => unknown>;
15
+ export interface Scope {
16
+ /** Current value of a produce slot on the screen. */
17
+ slot: (bindId: string, slotId: string) => unknown;
18
+ item?: unknown;
19
+ context?: Record<string, unknown>;
20
+ providers?: Record<string, unknown>;
21
+ steps?: Record<string, unknown>;
22
+ transforms?: Transforms;
23
+ }
24
+ interface Parsed {
25
+ head: string[];
26
+ path: string[];
27
+ pipes: Array<{
28
+ name: string;
29
+ args: unknown[];
30
+ }>;
31
+ }
32
+ export declare function parse(expr: string): Parsed;
33
+ export declare function evaluate(expr: string, scope: Scope): unknown;
34
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { Catalog } from "./contract";
2
+ export declare class CatalogLoadError extends Error {
3
+ readonly url: string;
4
+ constructor(message: string, url: string);
5
+ }
6
+ export declare function loadCatalog(url: string, init?: RequestInit): Promise<Catalog>;
@@ -0,0 +1,7 @@
1
+ /** Identifiers to words, for matching and labels. */
2
+ import type { Glossary } from "./contract";
3
+ export declare const sing: (w: string) => string;
4
+ export declare function synonymIndex(glossaries: Glossary[]): Record<string, string[]>;
5
+ export declare function words(text: string): string[];
6
+ /** Turns an identifier into words people read: "noteTypeId" → "Note type id". */
7
+ export declare function humanize(id: string): string;
@@ -0,0 +1,7 @@
1
+ /** OpenAPI 3.0–3.2 → Catalog. */
2
+ import type { Catalog } from "./contract";
3
+ /** FNV-1a, enough to detect catalog drift. */
4
+ export declare function hashString(s: string): string;
5
+ export declare function catalogFromOpenApi(input: unknown, source?: {
6
+ url?: string;
7
+ }): Catalog;
@@ -0,0 +1,33 @@
1
+ /** Builds requests, reads responses and runs trigger steps. */
2
+ import type { CatalogOperation, OperationConsumeBinding, Step } from "./contract";
3
+ import { type Scope } from "./expr";
4
+ export interface HttpRequest {
5
+ method: string;
6
+ /** Path with parameters filled in, e.g. "/cls/v1/notes/42". */
7
+ path: string;
8
+ query: Record<string, string>;
9
+ headers: Record<string, string>;
10
+ body?: unknown;
11
+ }
12
+ /** Sends a request. Supplied by the host (base URL, auth, errors). */
13
+ export type Fetcher = (request: HttpRequest, operation: CatalogOperation) => Promise<unknown>;
14
+ export declare class BindingError extends Error {
15
+ readonly detail?: unknown | undefined;
16
+ constructor(message: string, detail?: unknown | undefined);
17
+ }
18
+ export declare function buildRequest(op: CatalogOperation, request: Record<string, string>, scope: Scope): HttpRequest;
19
+ /** Identical requests share a key, and so one fetch. */
20
+ export declare const requestKey: (r: HttpRequest) => string;
21
+ /** "$", "$.a.b" or "$.a.items[*]" applied to a response. */
22
+ export declare function select(response: unknown, selector: string): unknown;
23
+ /** Applies a consume binding's `map` to each item; without a map the items pass through untouched. */
24
+ export declare function mapItems(data: unknown, binding: OperationConsumeBinding, scope: Scope): unknown;
25
+ export declare function runConsume(binding: OperationConsumeBinding, op: CatalogOperation, scope: Scope, fetcher: Fetcher): Promise<unknown>;
26
+ export interface StepOutcome {
27
+ step: string;
28
+ ok: boolean;
29
+ response?: unknown;
30
+ error?: unknown;
31
+ }
32
+ /** Runs call steps in order. `forEach` runs a call once per item; `onError: "stop"` ends the run at the first failure. */
33
+ export declare function runSteps(steps: Step[], operations: Map<string, CatalogOperation>, scope: Scope, fetcher: Fetcher): Promise<StepOutcome[]>;
@@ -0,0 +1,22 @@
1
+ /** JSON Schema helpers and per-operation views. */
2
+ import type { Catalog, CatalogOperation, JsonSchema } from "./contract";
3
+ export type Field = [name: string, type: string];
4
+ export type ReqField = [pointer: string, type: string, required: boolean];
5
+ export interface OpView {
6
+ op: CatalogOperation;
7
+ req: ReqField[];
8
+ lists: Array<{
9
+ select: string;
10
+ fields: Field[];
11
+ }>;
12
+ one: Field[] | null;
13
+ scalars: Field[];
14
+ }
15
+ type S = Record<string, any>;
16
+ export declare const obj: (s: JsonSchema | undefined) => S;
17
+ export declare function flat(s: JsonSchema | undefined): S;
18
+ export declare function typeName(s: JsonSchema | undefined): string;
19
+ export declare const isObject: (s: JsonSchema | undefined) => boolean;
20
+ export declare const propsOf: (s: JsonSchema | undefined) => Field[];
21
+ export declare function opViews(catalog: Catalog): Map<string, OpView>;
22
+ export {};
@@ -0,0 +1,17 @@
1
+ /** Manifest persistence and edit helpers. */
2
+ import type { BindingManifest, PersistenceAdapter, ScreenId, SlotBinding } from "./contract";
3
+ import type { BindingIndex, FrameworkData } from "./engine";
4
+ export declare function localStorageAdapter(prefix?: string): PersistenceAdapter;
5
+ export declare function memoryAdapter(seed?: BindingManifest[]): PersistenceAdapter;
6
+ export declare function toManifest(fw: FrameworkData, screen: ScreenId, bindings: SlotBinding[]): BindingManifest;
7
+ /** Unsaved screens with an edit counter; a screen is cleared only by a save that covers its latest edit. */
8
+ export type Pending = Map<ScreenId, number>;
9
+ export declare function markDirty(pending: Pending, screen: ScreenId): void;
10
+ /** Saves every pending screen from `idx`. Returns the screens whose save failed (they stay pending). */
11
+ export declare function savePending(adapter: PersistenceAdapter, fw: FrameworkData, idx: BindingIndex, pending: Pending): Promise<ScreenId[]>;
12
+ export declare function loadAll(adapter: PersistenceAdapter, screens: ScreenId[]): Promise<BindingIndex>;
13
+ /** Pure edit helpers: return a new index. */
14
+ export declare function putBinding(idx: BindingIndex, screen: ScreenId, b: SlotBinding): BindingIndex;
15
+ export declare function dropBinding(idx: BindingIndex, screen: ScreenId, component: string, slot: string): BindingIndex;
16
+ /** Parses imported manifests (one or a list). Throws on the first invalid entry. */
17
+ export declare function parseManifests(text: string): BindingManifest[];
@@ -0,0 +1,7 @@
1
+ import type { ScreenRegistry, ValidationIssue } from "./contract";
2
+ import type { Engine, FrameworkData } from "./engine";
3
+ export declare function validateRegistry(fw: FrameworkData): {
4
+ registry: ScreenRegistry;
5
+ issues: ValidationIssue[];
6
+ };
7
+ export declare function validateBindings(engine: Engine): ValidationIssue[];