@w6w/embed 0.2.1 → 0.2.19

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 (185) hide show
  1. package/README.md +22 -5
  2. package/dist/ConfirmModal-Pv2-A_3U.js +186 -0
  3. package/dist/ConfirmModal-Pv2-A_3U.js.map +1 -0
  4. package/dist/{CreateFunctionModal-DRsFx-FB.js → CreateFunctionModal-DScxp_LN.js} +25 -25
  5. package/dist/{CreateFunctionModal-DRsFx-FB.js.map → CreateFunctionModal-DScxp_LN.js.map} +1 -1
  6. package/dist/{DocumentFormModal-BExK1V-B.js → DocumentFormModal-Br4s8wmi.js} +5 -5
  7. package/dist/{DocumentFormModal-BExK1V-B.js.map → DocumentFormModal-Br4s8wmi.js.map} +1 -1
  8. package/dist/ImportSpecModal-Cpzp8ndt.js +251 -0
  9. package/dist/ImportSpecModal-Cpzp8ndt.js.map +1 -0
  10. package/dist/ModelRoutesManager-1Ac5wcas.js +345 -0
  11. package/dist/ModelRoutesManager-1Ac5wcas.js.map +1 -0
  12. package/dist/WorkflowEditor-CmhXHRxi.js +1109 -0
  13. package/dist/WorkflowEditor-CmhXHRxi.js.map +1 -0
  14. package/dist/apps-ItBvnWX3.js +92 -0
  15. package/dist/apps-ItBvnWX3.js.map +1 -0
  16. package/dist/{callables-3mFrMVG_.js → callables-tOlflvbl.js} +11 -11
  17. package/dist/{callables-3mFrMVG_.js.map → callables-tOlflvbl.js.map} +1 -1
  18. package/dist/chrome/ConfirmModal.d.ts +4 -1
  19. package/dist/chrome/DangerZone.d.ts +4 -3
  20. package/dist/chrome/ExecutionProfileHeader.d.ts +3 -3
  21. package/dist/chrome/JsonToggle.d.ts +29 -20
  22. package/dist/chrome/Modal.d.ts +3 -1
  23. package/dist/chrome/RightRail.d.ts +6 -1
  24. package/dist/chrome/VersionHistoryModal.d.ts +2 -0
  25. package/dist/chrome/index.d.ts +1 -0
  26. package/dist/chrome/workspace.d.ts +36 -1
  27. package/dist/coerce-input-DFJ4n_wc.js +150 -0
  28. package/dist/coerce-input-DFJ4n_wc.js.map +1 -0
  29. package/dist/connections-CzsCyIxY.js +119 -0
  30. package/dist/connections-CzsCyIxY.js.map +1 -0
  31. package/dist/credentials-Cn92LGhJ.js +171 -0
  32. package/dist/credentials-Cn92LGhJ.js.map +1 -0
  33. package/dist/data-stores-UeQvwVCa.js +170 -0
  34. package/dist/data-stores-UeQvwVCa.js.map +1 -0
  35. package/dist/document-sources-DNmBojx6.js +169 -0
  36. package/dist/document-sources-DNmBojx6.js.map +1 -0
  37. package/dist/draft/use-workflow-draft.d.ts +2 -0
  38. package/dist/draft.mjs +2 -2
  39. package/dist/editor/BindingBanner.d.ts +13 -0
  40. package/dist/editor/CallableEditorFrame.d.ts +7 -0
  41. package/dist/editor/EndpointCards.d.ts +4 -1
  42. package/dist/editor/PublishControl.d.ts +19 -0
  43. package/dist/editor/PublishTooltip.d.ts +7 -0
  44. package/dist/editor/SetupIncompleteBanner.d.ts +12 -0
  45. package/dist/editor/StartingStateModal.d.ts +14 -0
  46. package/dist/editor/TargetSelector.d.ts +15 -0
  47. package/dist/editor/TargetSelector.types.d.ts +2 -0
  48. package/dist/editor/WorkflowSettingsModal.d.ts +6 -1
  49. package/dist/editor/WorkflowVariablesEditor.d.ts +6 -0
  50. package/dist/editor/definition.d.ts +6 -0
  51. package/dist/editor/json-apply.d.ts +29 -0
  52. package/dist/editor/step-problems-feed.d.ts +5 -0
  53. package/dist/editor/types.d.ts +2 -2
  54. package/dist/editor-apps-DkkC7wOQ.js +152 -0
  55. package/dist/editor-apps-DkkC7wOQ.js.map +1 -0
  56. package/dist/editor-tools-BR27RGto.js +1683 -0
  57. package/dist/editor-tools-BR27RGto.js.map +1 -0
  58. package/dist/editor.mjs +1 -1
  59. package/dist/editors.mjs +855 -650
  60. package/dist/editors.mjs.map +1 -1
  61. package/dist/{endpoints-B2ynbZo-.js → endpoints-DSRo1Lc5.js} +113 -107
  62. package/dist/endpoints-DSRo1Lc5.js.map +1 -0
  63. package/dist/fields-DvS8XZFc.js +21 -0
  64. package/dist/fields-DvS8XZFc.js.map +1 -0
  65. package/dist/forms/ModelBudgetsManager.d.ts +9 -0
  66. package/dist/forms/ModelRoutesManager.d.ts +14 -0
  67. package/dist/forms.d.ts +4 -0
  68. package/dist/forms.mjs +611 -212
  69. package/dist/forms.mjs.map +1 -1
  70. package/dist/{rail-settings-XYGToh00.js → import-bindings-EUtxZ9Ti.js} +90 -24
  71. package/dist/import-bindings-EUtxZ9Ti.js.map +1 -0
  72. package/dist/index.mjs +154 -117
  73. package/dist/index.mjs.map +1 -1
  74. package/dist/lib/binding-problems.d.ts +42 -0
  75. package/dist/lib/code-rail.d.ts +4 -2
  76. package/dist/lib/history-query.d.ts +45 -0
  77. package/dist/lib/import-bindings.d.ts +89 -0
  78. package/dist/lib/index.d.ts +4 -0
  79. package/dist/lib/invoke-error.d.ts +1 -0
  80. package/dist/lib/rail-settings.d.ts +1 -1
  81. package/dist/lib/sdk-snippets.d.ts +1 -1
  82. package/dist/lib/setup-incomplete.d.ts +22 -0
  83. package/dist/lib/starting-data.d.ts +31 -0
  84. package/dist/lib/state-panel.d.ts +29 -0
  85. package/dist/lib/target-fields.d.ts +11 -15
  86. package/dist/lib/trigger-preview.d.ts +1 -0
  87. package/dist/lib/workflow-live-run.d.ts +93 -8
  88. package/dist/lib/workflow-nodes.d.ts +5 -0
  89. package/dist/lib/workflow-validity.d.ts +65 -16
  90. package/dist/lib/workflow-variables.d.ts +1 -1
  91. package/dist/lib/workflow-version.d.ts +2 -0
  92. package/dist/lib.mjs +86 -69
  93. package/dist/lists/ConnectionDependents.d.ts +31 -0
  94. package/dist/lists/ConnectionDetail.d.ts +4 -1
  95. package/dist/lists/ConnectionList.d.ts +4 -1
  96. package/dist/lists/CredentialDetail.d.ts +15 -0
  97. package/dist/lists/CredentialList.d.ts +14 -0
  98. package/dist/lists/DataStoreList.d.ts +17 -0
  99. package/dist/lists/DataStoreView.d.ts +19 -0
  100. package/dist/lists/Logs.d.ts +19 -0
  101. package/dist/lists/ModelCatalog.d.ts +12 -0
  102. package/dist/lists/ModelUsage.d.ts +12 -0
  103. package/dist/lists.d.ts +14 -0
  104. package/dist/lists.mjs +1766 -609
  105. package/dist/lists.mjs.map +1 -1
  106. package/dist/models-bAayQPJ_.js +270 -0
  107. package/dist/models-bAayQPJ_.js.map +1 -0
  108. package/dist/{project-context-BiCjv_E3.js → project-context-Tvp-La7A.js} +3 -3
  109. package/dist/{project-context-BiCjv_E3.js.map → project-context-Tvp-La7A.js.map} +1 -1
  110. package/dist/rail/ConnectionsTool.d.ts +2 -0
  111. package/dist/rail/HistoryTool.d.ts +2 -0
  112. package/dist/rail/StartingStateTool.d.ts +2 -0
  113. package/dist/rail/settings-sections.d.ts +4 -1
  114. package/dist/rail.mjs +4 -4
  115. package/dist/repos/agents-studio-agents.d.ts +52 -0
  116. package/dist/repos/agents-studio-assets.d.ts +68 -0
  117. package/dist/repos/connections.d.ts +30 -12
  118. package/dist/repos/constants.d.ts +12 -0
  119. package/dist/repos/credentials.d.ts +83 -0
  120. package/dist/repos/data-stores.d.ts +84 -0
  121. package/dist/repos/endpoints.d.ts +9 -3
  122. package/dist/repos/fields.d.ts +34 -0
  123. package/dist/repos/functions.d.ts +7 -5
  124. package/dist/repos/history.d.ts +9 -0
  125. package/dist/repos/index.d.ts +7 -0
  126. package/dist/repos/models.d.ts +289 -0
  127. package/dist/repos/spec-export.d.ts +3 -3
  128. package/dist/repos/spec-import.d.ts +30 -1
  129. package/dist/repos/step-tests.d.ts +2 -0
  130. package/dist/repos/webhook-listen.d.ts +35 -0
  131. package/dist/repos/workflows.d.ts +105 -2
  132. package/dist/repos.mjs +655 -176
  133. package/dist/repos.mjs.map +1 -1
  134. package/dist/setup-incomplete-BHs3Lpfy.js +199 -0
  135. package/dist/setup-incomplete-BHs3Lpfy.js.map +1 -0
  136. package/dist/{slug-C4ktDPdy.js → slug-BVdgiP_L.js} +64 -60
  137. package/dist/slug-BVdgiP_L.js.map +1 -0
  138. package/dist/{spec-export-Cf3VQSQS.js → spec-export-DGy5ijps.js} +73 -60
  139. package/dist/spec-export-DGy5ijps.js.map +1 -0
  140. package/dist/spec-import-SWOonsNr.js +116 -0
  141. package/dist/spec-import-SWOonsNr.js.map +1 -0
  142. package/dist/{step-tests-CivICmTq.js → step-tests-B4E4W3ly.js} +8 -7
  143. package/dist/step-tests-B4E4W3ly.js.map +1 -0
  144. package/dist/theme-context-E2ZhlXDX.js +6 -0
  145. package/dist/theme-context-E2ZhlXDX.js.map +1 -0
  146. package/dist/theme-context.d.ts +2 -0
  147. package/dist/{use-callable-draft-zHLpcr-b.js → use-callable-draft-DCauHt5o.js} +23 -23
  148. package/dist/{use-callable-draft-zHLpcr-b.js.map → use-callable-draft-DCauHt5o.js.map} +1 -1
  149. package/dist/use-workflow-draft-l3P5KZzw.js +338 -0
  150. package/dist/use-workflow-draft-l3P5KZzw.js.map +1 -0
  151. package/dist/{workflow-blank-DyL3_RUA.js → workflow-blank-DFpGObrn.js} +6 -6
  152. package/dist/{workflow-blank-DyL3_RUA.js.map → workflow-blank-DFpGObrn.js.map} +1 -1
  153. package/dist/workflows-BZN4Hyz1.js +623 -0
  154. package/dist/workflows-BZN4Hyz1.js.map +1 -0
  155. package/package.json +3 -2
  156. package/src/styles.css +155 -7
  157. package/dist/ConfirmModal-RLbZT5_k.js +0 -181
  158. package/dist/ConfirmModal-RLbZT5_k.js.map +0 -1
  159. package/dist/ImportSpecModal-BDQIf6rg.js +0 -136
  160. package/dist/ImportSpecModal-BDQIf6rg.js.map +0 -1
  161. package/dist/WorkflowEditor-DlbVv6Fs.js +0 -854
  162. package/dist/WorkflowEditor-DlbVv6Fs.js.map +0 -1
  163. package/dist/apps-1FNUwbGv.js +0 -77
  164. package/dist/apps-1FNUwbGv.js.map +0 -1
  165. package/dist/coerce-input-BicYr7nc.js +0 -139
  166. package/dist/coerce-input-BicYr7nc.js.map +0 -1
  167. package/dist/connections-CjjYeRqb.js +0 -78
  168. package/dist/connections-CjjYeRqb.js.map +0 -1
  169. package/dist/document-sources-C0grrtdq.js +0 -86
  170. package/dist/document-sources-C0grrtdq.js.map +0 -1
  171. package/dist/editor-apps-BdenSV1o.js +0 -95
  172. package/dist/editor-apps-BdenSV1o.js.map +0 -1
  173. package/dist/editor-tools-RxmY5iyi.js +0 -1279
  174. package/dist/editor-tools-RxmY5iyi.js.map +0 -1
  175. package/dist/endpoints-B2ynbZo-.js.map +0 -1
  176. package/dist/rail-settings-XYGToh00.js.map +0 -1
  177. package/dist/slug-C4ktDPdy.js.map +0 -1
  178. package/dist/spec-export-Cf3VQSQS.js.map +0 -1
  179. package/dist/spec-import-CjmxyZDR.js +0 -465
  180. package/dist/spec-import-CjmxyZDR.js.map +0 -1
  181. package/dist/step-tests-CivICmTq.js.map +0 -1
  182. package/dist/trigger-preview-VPkrryDl.js +0 -120
  183. package/dist/trigger-preview-VPkrryDl.js.map +0 -1
  184. package/dist/use-workflow-draft-DzAyUeA6.js +0 -316
  185. package/dist/use-workflow-draft-DzAyUeA6.js.map +0 -1
package/README.md CHANGED
@@ -35,7 +35,7 @@ page can import it.
35
35
  | `@w6w/embed` | `W6WEmbedProvider`, `useEmbedStatus`, `useEmbedProject`, `EmbedAuthError`. |
36
36
  | `@w6w/embed/editor` | `WorkflowEditor` alone, loaded lazily. |
37
37
  | `@w6w/embed/editors` | The callable editors: `WorkflowEditor`, `FunctionEditor`, `EndpointEditor`, `DocumentEditor`. |
38
- | `@w6w/embed/lists` | The connected lists and detail views: `FunctionList`, `EndpointList`, `WorkflowList`, `ReliabilityBoard`, `ActivitySummary`, `RunHistory`, `DocumentList`, `ServiceDetail`, `ConnectionList`, `ConnectionDetail`. |
38
+ | `@w6w/embed/lists` | The connected lists and detail views: `FunctionList`, `EndpointList`, `WorkflowList`, `ReliabilityBoard`, `ActivitySummary`, `Logs`, `RunHistory`, `DocumentList`, `DataStoreList`, `DataStoreView`, `ServiceDetail`, `ConnectionList`, `ConnectionDetail`. |
39
39
  | `@w6w/embed/forms` | The configuration forms: `CreateFunctionModal`, `CreateEndpointModal`, `VarsManager`, `SecretsManager`. |
40
40
  | `@w6w/embed/rail` | `CallableWorkspace` and `CallableRail`, to place the editor's rail yourself. |
41
41
  | `@w6w/embed/repos` | The data hooks the components read through (`useFunctionsQuery`, `useAppActionsQuery`, ...), on the provider's one cache. |
@@ -122,8 +122,9 @@ never reaches the browser. The recipe is in the guide at `/guides/embed/`.
122
122
  - `project={{ use: "default" }}` uses the account's default project instead of an id you know. It
123
123
  is looked up once per identity (one `GET /projects`, the row with `isDefault`), never the first
124
124
  row of the list. `useEmbedProject()` returns `{ project, status, error? }` with `status` one of
125
- `"resolving" | "ready" | "error"`: while resolving, `project` is `null` and editors stay in
126
- their "project required" state; if the lookup fails or no row is the default, `status` is
125
+ `"resolving" | "ready" | "error"`: while resolving, `project` is `null` and editors refuse to
126
+ save, without showing the "no project selected" notice (that notice appears only when there is
127
+ truly no project); if the lookup fails or no row is the default, `status` is
127
128
  `"error"` and nothing falls back to another project. A plain `project="proj_123"` is `"ready"`
128
129
  at once; omitted, it is `{ project: null, status: "ready" }`.
129
130
  - `identityKey={null}` means nobody is signed in: the provider renders `fallback` (default
@@ -262,7 +263,7 @@ See the [components reference](../../docs/embed/components.md).
262
263
 
263
264
  ## Lists
264
265
 
265
- `@w6w/embed/lists` holds the connected lists (`FunctionList`, `EndpointList`, `WorkflowList`, `ReliabilityBoard`, `ActivitySummary`, `RunHistory`, `DocumentList`, `ServiceDetail`, `ConnectionList`, `ConnectionDetail`). Each reads through the same provider as the editor and
266
+ `@w6w/embed/lists` holds the connected lists (`FunctionList`, `EndpointList`, `WorkflowList`, `ReliabilityBoard`, `ActivitySummary`, `Logs`, `RunHistory`, `DocumentList`, `DataStoreList`, `DataStoreView`, `ServiceDetail`, `ConnectionList`, `ConnectionDetail`). Each reads through the same provider as the editor and
266
267
  writes through it, so a host mounts nothing else.
267
268
 
268
269
  | Component | What it does |
@@ -296,7 +297,9 @@ requests on purpose: "Today" is cut at the viewer's local midnight (`from`, `buc
296
297
  server only groups by `day` or `week`, cutting at midnight in the database's timezone, so one
297
298
  request cannot give a local day. `<RunHistory scope? showKind? filters? onFiltersChange?
298
299
  onOpenInEditor?>` shows the execution history for the provider's project (or the `scope` you pass);
299
- omit `filters` and it keeps them itself, pass them and you own them. See the
300
+ omit `filters` and it keeps them itself, pass them and you own them. `<Logs title?>` is that view
301
+ under a heading (`"Logs"` by default, `null` for none): drop it inside `<W6WEmbedProvider>` for the
302
+ project's recent executions, each opening its detail in place. See the
300
303
  [components reference](../../docs/embed/components.md).
301
304
 
302
305
  `<ServiceDetail appId project? days? backHref? onBack? slots?>` shows one service's reliability
@@ -342,6 +345,20 @@ shares in from a repository show no Edit or Delete. The embed has no repository
342
345
  from" markers; a host that wants them adds them through the list's row slots (`lead`,
343
346
  `sharedActions`, `footer`). Details are in the components reference.
344
347
 
348
+ ## Data stores
349
+
350
+ | Component | Import | What it is |
351
+ | --- | --- | --- |
352
+ | `<DataStoreList>` | `@w6w/embed/lists` | A project's data stores: create and archive. Opening one is the host's `onOpen` / `getHref`. |
353
+ | `<DataStoreView id>` | `@w6w/embed/lists` | One store: a table as an editable grid, a key-value or document store as an entry list with an editor. A table also imports and exports CSV. |
354
+
355
+ Both take `project` (omitted: the provider's project; `null` or `""`: nothing is read and writes
356
+ refuse). Every save sends the version it loaded; if someone else changed the entry first, the row or
357
+ editor shows a Reload prompt instead of overwriting. `<W6WEmbedProvider>` also fills the store
358
+ picker of the `@w6w/store` step in an embedded editor. A scoped or IP-restricted `tsec_` token can
359
+ read stores but not write them, so a view opened with one lists and shows entries and every save
360
+ is refused by the server. Details are in the components reference.
361
+
345
362
  ## Endpoint editor
346
363
 
347
364
  | Component | Import | What it is |
@@ -0,0 +1,186 @@
1
+ import { jsx as e, jsxs as a, Fragment as f } from "react/jsx-runtime";
2
+ import { b as W, u as E } from "./slug-BVdgiP_L.js";
3
+ import { IconButton as S, Modal as _, CodeBlock as B } from "@w6w/ui";
4
+ import { useRef as L, useEffect as $, useState as N } from "react";
5
+ function x({
6
+ title: i,
7
+ onClose: n,
8
+ children: c,
9
+ wide: p = !1,
10
+ xl: s = !1,
11
+ headerRight: d,
12
+ className: b
13
+ }) {
14
+ const u = L(null);
15
+ return $(() => {
16
+ const o = u.current;
17
+ if (!o) return;
18
+ o.open || o.showModal();
19
+ const g = (l) => {
20
+ l.preventDefault(), n();
21
+ }, h = (l) => {
22
+ if (l.target !== o) return;
23
+ const m = o.getBoundingClientRect();
24
+ (l.clientX < m.left || l.clientX > m.right || l.clientY < m.top || l.clientY > m.bottom) && n();
25
+ };
26
+ return o.addEventListener("cancel", g), o.addEventListener("click", h), () => {
27
+ o.removeEventListener("cancel", g), o.removeEventListener("click", h);
28
+ };
29
+ }, [n]), /* @__PURE__ */ e("div", { className: "modal-backdrop", children: /* @__PURE__ */ a(
30
+ "dialog",
31
+ {
32
+ ref: u,
33
+ className: `modal${p ? " modal-wide" : ""}${s ? " modal-xl" : ""}${b ? ` ${b}` : ""}`,
34
+ "aria-label": i,
35
+ children: [
36
+ d ? /* @__PURE__ */ a("div", { className: "modal-head", children: [
37
+ /* @__PURE__ */ e("h3", { children: i }),
38
+ d
39
+ ] }) : /* @__PURE__ */ e("h3", { children: i }),
40
+ c
41
+ ]
42
+ }
43
+ ) });
44
+ }
45
+ const y = [
46
+ { id: "node", label: "Node", language: "TypeScript", grammar: "typescript", icon: "lang-node" },
47
+ { id: "cli", label: "CLI", language: "Shell", grammar: "bash", icon: "terminal" },
48
+ { id: "python", label: "Python", language: "Python", grammar: "python", icon: "lang-python" },
49
+ { id: "curl", label: "curl", language: "Shell", grammar: "bash", icon: "lang-curl" }
50
+ ];
51
+ function F(i) {
52
+ const n = W(i);
53
+ return n ? y.filter((c) => typeof n[c.id] == "string") : [];
54
+ }
55
+ function R({
56
+ resource: i,
57
+ triggers: n,
58
+ wrap: c = !1,
59
+ maxHeight: p = "420px",
60
+ initialTab: s
61
+ }) {
62
+ var v, C, w;
63
+ const [d, b] = N(s ?? "node"), [u, o] = N(0), g = !!n && n.length > 0, h = g ? n[Math.min(u, n.length - 1)] ?? n[0] : null, l = W(i, h == null ? void 0 : h.fields), m = l ? y.filter((t) => typeof l[t.id] == "string") : [], r = m.some((t) => t.id === d) ? d : ((v = m[0]) == null ? void 0 : v.id) ?? "node", k = (l == null ? void 0 : l[r]) ?? "";
64
+ return l === null ? /* @__PURE__ */ e("p", { className: "muted", children: E(i) }) : /* @__PURE__ */ a(f, { children: [
65
+ g && h && /* @__PURE__ */ a("div", { className: "subpanel", style: { marginTop: 0, paddingTop: 0, borderTop: "none" }, children: [
66
+ /* @__PURE__ */ a("div", { "data-testid": "trigger-panel", children: [
67
+ /* @__PURE__ */ e("div", { className: "code-tabs", children: n.map((t, T) => /* @__PURE__ */ e(
68
+ "button",
69
+ {
70
+ type: "button",
71
+ className: `code-tab${T === u ? " active" : ""}`,
72
+ "data-testid": "trigger-tab",
73
+ onClick: () => o(T),
74
+ children: t.label
75
+ },
76
+ t.id
77
+ )) }),
78
+ h.fields.length === 0 && /* @__PURE__ */ e("p", { className: "muted small", children: "This trigger declares no fields." })
79
+ ] }),
80
+ n.length > 1 && /* @__PURE__ */ a("p", { className: "muted small", "data-testid": "trigger-multi-note", children: [
81
+ "This workflow has ",
82
+ n.length,
83
+ " manual triggers — the same input reaches every one of them identically; there is no per-trigger routing."
84
+ ] })
85
+ ] }),
86
+ /* @__PURE__ */ e("div", { className: "code-tabs", children: m.map((t) => /* @__PURE__ */ e(
87
+ "button",
88
+ {
89
+ type: "button",
90
+ className: `code-tab${r === t.id ? " active" : ""}`,
91
+ onClick: () => b(t.id),
92
+ children: t.label
93
+ },
94
+ t.id
95
+ )) }),
96
+ /* @__PURE__ */ e(
97
+ B,
98
+ {
99
+ code: k,
100
+ language: ((C = y.find((t) => t.id === r)) == null ? void 0 : C.grammar) ?? "plaintext",
101
+ maxHeight: p,
102
+ wrap: c,
103
+ "aria-label": `${((w = y.find((t) => t.id === r)) == null ? void 0 : w.label) ?? r} snippet`,
104
+ copyable: !0
105
+ }
106
+ ),
107
+ /* @__PURE__ */ e("p", { className: "muted small", style: { marginBottom: 0 }, children: r === "node" ? /* @__PURE__ */ a(f, { children: [
108
+ /* @__PURE__ */ e("code", { children: "npm i @w6w/sdk" }),
109
+ " · set ",
110
+ /* @__PURE__ */ e("code", { children: "W6W_BASE_URL" }),
111
+ " and ",
112
+ /* @__PURE__ */ e("code", { children: "W6W_TOKEN" }),
113
+ " · operation ",
114
+ /* @__PURE__ */ e("code", { children: l.operation })
115
+ ] }) : r === "cli" ? /* @__PURE__ */ a(f, { children: [
116
+ /* @__PURE__ */ e("code", { children: "npm i -g @w6w/cli" }),
117
+ " · set ",
118
+ /* @__PURE__ */ e("code", { children: "W6W_BASE_URL" }),
119
+ " and",
120
+ " ",
121
+ /* @__PURE__ */ e("code", { children: "W6W_TOKEN" }),
122
+ " (or pass ",
123
+ /* @__PURE__ */ e("code", { children: "--base-url" }),
124
+ " / ",
125
+ /* @__PURE__ */ e("code", { children: "--token" }),
126
+ ") · operation ",
127
+ /* @__PURE__ */ e("code", { children: l.operation })
128
+ ] }) : r === "python" ? /* @__PURE__ */ a(f, { children: [
129
+ /* @__PURE__ */ e("code", { children: "pip install w6w" }),
130
+ " · set ",
131
+ /* @__PURE__ */ e("code", { children: "W6W_BASE_URL" }),
132
+ " and ",
133
+ /* @__PURE__ */ e("code", { children: "W6W_TOKEN" }),
134
+ " ",
135
+ "· operation ",
136
+ /* @__PURE__ */ e("code", { children: l.operation })
137
+ ] }) : /* @__PURE__ */ a(f, { children: [
138
+ "No client library — any HTTP client will do. Set ",
139
+ /* @__PURE__ */ e("code", { children: "W6W_BASE_URL" }),
140
+ " to your w6w base URL (for an Endpoint, the URL above is the one this page is showing); substitute a w6w token for ",
141
+ /* @__PURE__ */ e("code", { children: "$W6W_TOKEN" }),
142
+ " and send the declared input as the JSON body."
143
+ ] }) })
144
+ ] });
145
+ }
146
+ function I({
147
+ resource: i,
148
+ label: n = "Call from code",
149
+ triggers: c,
150
+ initialTab: p
151
+ }) {
152
+ const [s, d] = N(!1);
153
+ return /* @__PURE__ */ a(f, { children: [
154
+ /* @__PURE__ */ e(S, { icon: "code", label: n, onClick: () => d(!0) }),
155
+ s && /* @__PURE__ */ e(_, { title: "Call from code", size: "wide", onClose: () => d(!1), children: /* @__PURE__ */ e(R, { resource: i, triggers: c, initialTab: p }) })
156
+ ] });
157
+ }
158
+ function K({
159
+ title: i,
160
+ message: n,
161
+ children: c,
162
+ onConfirm: p,
163
+ onClose: s,
164
+ confirmLabel: d = "Confirm",
165
+ cancelLabel: b = "Cancel",
166
+ destructive: u = !0
167
+ }) {
168
+ return /* @__PURE__ */ a(x, { title: i, onClose: s, children: [
169
+ /* @__PURE__ */ a("div", { className: "modal-body", children: [
170
+ /* @__PURE__ */ e("p", { className: "muted small", children: n }),
171
+ c
172
+ ] }),
173
+ /* @__PURE__ */ a("div", { className: "modal-actions", children: [
174
+ /* @__PURE__ */ e("button", { type: "button", className: "btn ghost", onClick: s, children: b }),
175
+ /* @__PURE__ */ e("button", { type: "button", className: u ? "btn danger" : "btn", onClick: p, children: d })
176
+ ] })
177
+ ] });
178
+ }
179
+ export {
180
+ K as C,
181
+ x as M,
182
+ I as a,
183
+ R as b,
184
+ F as s
185
+ };
186
+ //# sourceMappingURL=ConfirmModal-Pv2-A_3U.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmModal-Pv2-A_3U.js","sources":["../src/chrome/Modal.tsx","../src/chrome/CallFromCodeButton.tsx","../src/chrome/ConfirmModal.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\n\ninterface ModalProps {\n title: string;\n onClose: () => void;\n children: React.ReactNode;\n /** Widen the dialog (e.g. for a JSON editor that needs room). */\n wide?: boolean;\n /** Widen further still (e.g. for the plan comparison grid). */\n xl?: boolean;\n /** Trailing control on the title row (e.g. a close `IconButton`). Given,\n * the title and this node share one `.modal-head` row; absent, the title\n * renders as a direct child exactly as before. */\n headerRight?: React.ReactNode;\n /** Extra class on the `<dialog>` (e.g. `modal-json`, the fill-and-scroll JSON layout). */\n className?: string;\n}\n\n/**\n * Small dialog modal. Built on the native <dialog> element so it gets focus\n * trapping, Esc-dismiss, and accessibility semantics for free. A button\n * positioned over the backdrop catches outside-clicks to close.\n */\nexport function Modal({\n title,\n onClose,\n children,\n wide = false,\n xl = false,\n headerRight,\n className,\n}: ModalProps) {\n const ref = useRef<HTMLDialogElement>(null);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n if (!el.open) el.showModal();\n const onCancel = (e: Event) => {\n e.preventDefault();\n onClose();\n };\n // A `showModal()` dialog + its ::backdrop sit in the top layer, above any\n // sibling overlay — so catch outside clicks on the dialog itself: backdrop\n // clicks target the dialog, and land outside its box.\n const onClick = (e: MouseEvent) => {\n if (e.target !== el) return;\n const r = el.getBoundingClientRect();\n const outside =\n e.clientX < r.left || e.clientX > r.right || e.clientY < r.top || e.clientY > r.bottom;\n if (outside) onClose();\n };\n el.addEventListener(\"cancel\", onCancel);\n el.addEventListener(\"click\", onClick);\n return () => {\n el.removeEventListener(\"cancel\", onCancel);\n el.removeEventListener(\"click\", onClick);\n };\n }, [onClose]);\n\n return (\n <div className=\"modal-backdrop\">\n <dialog\n ref={ref}\n className={`modal${wide ? \" modal-wide\" : \"\"}${xl ? \" modal-xl\" : \"\"}${className ? ` ${className}` : \"\"}`}\n aria-label={title}\n >\n {headerRight ? (\n <div className=\"modal-head\">\n <h3>{title}</h3>\n {headerRight}\n </div>\n ) : (\n <h3>{title}</h3>\n )}\n {children}\n </dialog>\n </div>\n );\n}\n","import {\n type SnippetCallable,\n type TriggerPreview,\n buildSnippet,\n unavailableReason,\n} from \"@w6w/embed/lib\";\nimport { CodeBlock, type CodeLanguage, IconButton, type IconName, Modal } from \"@w6w/ui\";\nimport { useState } from \"react\";\n\n/**\n * \"Call from code\" — the button that shows how to reach the thing you are\n * looking at from the Node SDK (`@w6w/sdk`), the CLI (`w6w`), or the Python\n * SDK (`w6w`, PyPI).\n *\n * Mounted on the pages whose resource the wrapper contract actually covers.\n * Everything shown comes from `../lib/sdk-snippets.ts`, which builds against\n * `packages/wrappers/endpoints.json` — this component owns presentation only\n * and never composes an API call of its own.\n *\n * A modal rather than an inline block: the snippet is reference material a\n * reader wants once and then dismisses, and inlining it would push the page's\n * real content (a function's inputs, a workflow's steps) below the fold for\n * everyone who is not currently writing a client.\n */\n\n/**\n * Tabs, in the order the contract lists the wrappers — then `curl`, which is\n * not a wrapper at all and therefore comes last.\n *\n * The strip renders only the tabs the BUILT snippet actually carries\n * (`Snippet.curl` is optional): a Function, Endpoint or Workflow shows all\n * four tabs, while a Connection, Var or Document — which have no fixed\n * single-resource route to curl against — still show exactly the three\n * Node/CLI/Python tabs they show today.\n */\nconst TABS = [\n { id: \"node\", label: \"Node\", language: \"TypeScript\", grammar: \"typescript\", icon: \"lang-node\" },\n { id: \"cli\", label: \"CLI\", language: \"Shell\", grammar: \"bash\", icon: \"terminal\" },\n { id: \"python\", label: \"Python\", language: \"Python\", grammar: \"python\", icon: \"lang-python\" },\n { id: \"curl\", label: \"curl\", language: \"Shell\", grammar: \"bash\", icon: \"lang-curl\" },\n] as const satisfies readonly {\n id: string;\n label: string;\n language: string;\n grammar: CodeLanguage;\n /** The tab's glyph, by name from `@w6w/ui`'s icon set (`icons.tsx`). Every\n * language mark this file used to draw — its own `NodeGlyph`/`CliGlyph`/\n * `PythonGlyph`/`CurlGlyph` — is one of those entries, copied verbatim, so\n * the tab strip and the rail's language picker draw the same four shapes\n * from one place. */\n icon: IconName;\n}[];\n\n/**\n * The tab table, exported so a caller can render its OWN affordance per\n * language without re-deriving the set. `CodeTool`'s rail panel uses it to draw\n * one icon per language and open this component's modal on that language.\n *\n * Exported as the table rather than as a list of ids on purpose: label, grammar\n * and glyph belong to the same row, and a second place that decided \"which\n * languages exist\" would be a second place to forget `curl`.\n */\nexport const SNIPPET_TABS = TABS;\n\ntype TabId = (typeof TABS)[number][\"id\"];\nexport type SnippetTabId = TabId;\n\n/**\n * Which language tabs a resource actually has — the same filter the strip\n * below applies, hoisted so a caller can ask BEFORE rendering.\n *\n * `curl` is emitted only where a public URL exists and was handed in (today: a\n * Function, a Workflow, or an Endpoint that knows its own server-rendered URL),\n * so a var, document or connection yields exactly Node/CLI/Python. Trigger\n * fields are deliberately not a parameter: they change what the snippet SAYS,\n * never which languages it is available in.\n *\n * Empty when the resource has no snippet at all — the caller should then show\n * {@link unavailableReason} rather than an empty row of icons.\n */\nexport function snippetTabsFor(resource: SnippetCallable): readonly (typeof TABS)[number][] {\n const snippet = buildSnippet(resource);\n return snippet ? TABS.filter((t) => typeof snippet[t.id] === \"string\") : [];\n}\n\n/**\n * The headless body — everything that renders the snippet itself: the\n * trigger-tab strip, the language-tab strip, the `CodeBlock`, and the per-tab\n * install-hint paragraph. No button, no `Modal`. Split out (T2.1.2) so\n * `CodeTool.Panel` (`../ui/rail/CodeTool.tsx`) can render this INSIDE the\n * right rail's own already-open panel, without a second trigger button or a\n * Modal-on-top-of-a-panel double-wrap — the rail's strip + panel disclosure\n * IS the trigger; this component only needs to draw what's inside it.\n * `CallFromCodeButton` below is unchanged in outward shape: the same button +\n * `Modal`, now rendering this body inside.\n */\nexport function CallFromCodeBody({\n resource,\n triggers,\n wrap = false,\n maxHeight = \"420px\",\n initialTab,\n}: {\n resource: SnippetCallable;\n /**\n * The workflow's declared manual (`@w6w/trigger`) triggers, one entry per\n * step, in declared order — optional so every other `CallFromCodeBody`\n * caller (function, endpoint, connection, var, document) is unaffected.\n * Both call sites derive this from a workflow definition already in scope\n * (T2.2.1, HITL-2/HITL-4 pinned); nothing here fetches it. The selected\n * trigger's declared fields are passed straight into `buildSnippet` and\n * rendered INSIDE the generated code — required fields as active code with\n * a type-derived placeholder, optional fields commented out (D-3/D-4) — so\n * there is nothing left to duplicate in a panel above it.\n */\n triggers?: TriggerPreview[];\n /**\n * Soft-wrap the code box instead of scrolling it horizontally. Default OFF\n * — see the `CodeBlock` call below for why off is right wherever there is\n * room, and why the right rail is the place where it is not.\n */\n wrap?: boolean;\n /** The code box's max height. Default `\"420px\"`, the modal's size. */\n maxHeight?: string;\n /**\n * Which language to open on. Seeds the selection ONCE, at mount — this is a\n * starting point, not a controlled value, so the strip stays clickable\n * afterwards.\n *\n * That \"once\" is load-bearing for the rail: `CodeTool` mounts this inside a\n * modal that is conditionally rendered, so picking Python, closing, and\n * picking Node re-mounts and re-seeds. A tab this resource does not carry\n * falls back to the first one it does, via `activeTab` below.\n */\n initialTab?: TabId;\n}) {\n const [tab, setTab] = useState<TabId>(initialTab ?? \"node\");\n const [triggerIndex, setTriggerIndex] = useState(0);\n const hasTriggers = !!triggers && triggers.length > 0;\n const selectedTrigger = hasTriggers\n ? (triggers[Math.min(triggerIndex, triggers.length - 1)] ?? triggers[0])\n : null;\n const snippet = buildSnippet(resource, selectedTrigger?.fields);\n // Only the tabs this snippet carries. `curl` is emitted for a Function,\n // Workflow, or an Endpoint that knows its own server-rendered URL — a var,\n // document or connection still renders exactly Node/CLI/Python.\n const tabs = snippet ? TABS.filter((t) => typeof snippet[t.id] === \"string\") : [];\n // Never leave the selection pointing at a tab that is not on the strip — the\n // component is mounted once per page and `tab` outlives a resource change.\n const activeTab: TabId = tabs.some((t) => t.id === tab) ? tab : (tabs[0]?.id ?? \"node\");\n const code = snippet?.[activeTab] ?? \"\";\n\n if (snippet === null) return <p className=\"muted\">{unavailableReason(resource)}</p>;\n\n return (\n <>\n {hasTriggers && selectedTrigger && (\n <div className=\"subpanel\" style={{ marginTop: 0, paddingTop: 0, borderTop: \"none\" }}>\n {/* Reuses `.code-tabs`/`.code-tab` — the modal's own existing\n Node/CLI/Python strip pattern (HITL-2: \"mirroring the\n modal's existing Node/CLI/Python strip\"). Nested INSIDE\n the trigger panel so the language tab-strip assertion\n below (which filters out anything under\n `[data-testid='trigger-panel']`) still sees exactly\n Node/CLI/Python. The selected trigger's fields are no\n longer listed HERE — they are rendered inside the code\n below (required active, optional commented; D-3/D-4),\n so a list here would only duplicate it. */}\n <div data-testid=\"trigger-panel\">\n <div className=\"code-tabs\">\n {triggers.map((t, i) => (\n <button\n key={t.id}\n type=\"button\"\n className={`code-tab${i === triggerIndex ? \" active\" : \"\"}`}\n data-testid=\"trigger-tab\"\n onClick={() => setTriggerIndex(i)}\n >\n {t.label}\n </button>\n ))}\n </div>\n {selectedTrigger.fields.length === 0 && (\n <p className=\"muted small\">This trigger declares no fields.</p>\n )}\n </div>\n {triggers.length > 1 && (\n <p className=\"muted small\" data-testid=\"trigger-multi-note\">\n This workflow has {triggers.length} manual triggers — the same input reaches every one\n of them identically; there is no per-trigger routing.\n </p>\n )}\n </div>\n )}\n\n <div className=\"code-tabs\">\n {tabs.map((t) => (\n <button\n key={t.id}\n type=\"button\"\n className={`code-tab${activeTab === t.id ? \" active\" : \"\"}`}\n onClick={() => setTab(t.id)}\n >\n {t.label}\n </button>\n ))}\n </div>\n\n {/* `wrap` is a CALLER decision, defaulting OFF. Off is right wherever\n there is room: the CLI snippet's `\\`-continued lines are chosen line\n breaks, and soft-wrapping blurs them into the accidental ones, so a\n long Node line scrolls instead.\n It is wrong in the right RAIL, whose panel is ~395px wide — there\n every snippet scrolls horizontally, every time, and a snippet you\n have to drag sideways to read is not a snippet you can read. The\n rail passes `wrap`; the modal (which has the room) does not. The\n copy affordance lives inside the code box itself (`copyable`) — no\n local `CopyButton`, no `.code-tabs-spacer`. */}\n <CodeBlock\n code={code}\n language={TABS.find((t) => t.id === activeTab)?.grammar ?? \"plaintext\"}\n maxHeight={maxHeight}\n wrap={wrap}\n aria-label={`${TABS.find((t) => t.id === activeTab)?.label ?? activeTab} snippet`}\n copyable\n />\n\n {/* One arm per tab, and `python` is now EXPLICIT: it used to be\n the trailing `else`, so a fourth tab would silently have\n inherited \"pip install w6w\". The `curl` arm names no\n `operation` — raw HTTP maps to no wrapper-contract operation,\n and claiming one would be a promise the contract does not\n make. */}\n <p className=\"muted small\" style={{ marginBottom: 0 }}>\n {activeTab === \"node\" ? (\n <>\n <code>npm i @w6w/sdk</code> · set <code>W6W_BASE_URL</code> and <code>W6W_TOKEN</code> ·\n operation <code>{snippet.operation}</code>\n </>\n ) : activeTab === \"cli\" ? (\n <>\n <code>npm i -g @w6w/cli</code> · set <code>W6W_BASE_URL</code> and{\" \"}\n <code>W6W_TOKEN</code> (or pass <code>--base-url</code> / <code>--token</code>) ·\n operation <code>{snippet.operation}</code>\n </>\n ) : activeTab === \"python\" ? (\n <>\n <code>pip install w6w</code> · set <code>W6W_BASE_URL</code> and <code>W6W_TOKEN</code>{\" \"}\n · operation <code>{snippet.operation}</code>\n </>\n ) : (\n <>\n No client library — any HTTP client will do. Set <code>W6W_BASE_URL</code> to your w6w\n base URL (for an Endpoint, the URL above is the one this page is showing); substitute a\n w6w token for <code>$W6W_TOKEN</code> and send the declared input as the JSON body.\n </>\n )}\n </p>\n </>\n );\n}\n\nexport function CallFromCodeButton({\n resource,\n label = \"Call from code\",\n triggers,\n initialTab,\n}: {\n resource: SnippetCallable;\n label?: string;\n /** See {@link CallFromCodeBody}'s own doc — passed straight through. */\n triggers?: TriggerPreview[];\n /** See {@link CallFromCodeBody}'s own doc — passed straight through. */\n initialTab?: TabId;\n}) {\n const [open, setOpen] = useState(false);\n\n return (\n <>\n <IconButton icon=\"code\" label={label} onClick={() => setOpen(true)} />\n\n {open && (\n <Modal title=\"Call from code\" size=\"wide\" onClose={() => setOpen(false)}>\n <CallFromCodeBody resource={resource} triggers={triggers} initialTab={initialTab} />\n </Modal>\n )}\n </>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Modal } from \"./Modal.tsx\";\n\ninterface ConfirmModalProps {\n title: string;\n message: string;\n /** Optional content rendered under the message (e.g. a list of impacted items). */\n children?: ReactNode;\n /** Fired when the user confirms. The caller clears its pending state via onClose. */\n onConfirm: () => void;\n /** Fired on Cancel, Esc, or outside-click — dismisses without confirming. */\n onClose: () => void;\n confirmLabel?: string;\n cancelLabel?: string;\n /** Style the confirm button as destructive (default true — this dialog gates dangerous actions). */\n destructive?: boolean;\n}\n\n/**\n * A reusable confirmation dialog built on our <dialog>-based Modal, so it inherits\n * focus-trap, Esc-dismiss, and outside-click close. Replaces the browser's native\n * confirmation prompt for destructive actions: Confirm fires `onConfirm`;\n * Cancel/Esc/outside-click fires `onClose` only (no confirmation).\n */\nexport function ConfirmModal({\n title,\n message,\n children,\n onConfirm,\n onClose,\n confirmLabel = \"Confirm\",\n cancelLabel = \"Cancel\",\n destructive = true,\n}: ConfirmModalProps) {\n return (\n <Modal title={title} onClose={onClose}>\n <div className=\"modal-body\">\n <p className=\"muted small\">{message}</p>\n {children}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={onClose}>\n {cancelLabel}\n </button>\n <button type=\"button\" className={destructive ? \"btn danger\" : \"btn\"} onClick={onConfirm}>\n {confirmLabel}\n </button>\n </div>\n </Modal>\n );\n}\n"],"names":["Modal","title","onClose","children","wide","xl","headerRight","className","ref","useRef","useEffect","el","onCancel","e","onClick","r","jsx","jsxs","TABS","snippetTabsFor","resource","snippet","buildSnippet","t","CallFromCodeBody","triggers","wrap","maxHeight","initialTab","tab","setTab","useState","triggerIndex","setTriggerIndex","hasTriggers","selectedTrigger","tabs","activeTab","_a","code","unavailableReason","Fragment","i","CodeBlock","_b","_c","CallFromCodeButton","label","open","setOpen","IconButton","ConfirmModal","message","onConfirm","confirmLabel","cancelLabel","destructive"],"mappings":"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"}
@@ -1,19 +1,19 @@
1
1
  import { jsx as n, jsxs as i } from "react/jsx-runtime";
2
2
  import { ApiError as I } from "@w6w/sdk";
3
3
  import { useEnterSubmit as K } from "@w6w/ui";
4
- import { useState as o } from "react";
5
- import { M } from "./ConfirmModal-RLbZT5_k.js";
6
- import { n as F, r as D, z as O, E as T, t as P, A as B, F as L } from "./endpoints-B2ynbZo-.js";
7
- import { i as x, s as A } from "./slug-C4ktDPdy.js";
4
+ import { useState as d } from "react";
5
+ import { M } from "./ConfirmModal-Pv2-A_3U.js";
6
+ import { n as F, u as D, a as O, E as T, b as P, c as B, F as L } from "./endpoints-DSRo1Lc5.js";
7
+ import { i as x, s as A } from "./slug-BVdgiP_L.js";
8
8
  function R(e) {
9
9
  var C, v, k;
10
- const a = !!e.initial, [l, c] = o(((C = e.initial) == null ? void 0 : C.displayName) ?? ""), [s, h] = o(((v = e.initial) == null ? void 0 : v.key) ?? ""), [r, E] = o(((k = e.initial) == null ? void 0 : k.description) ?? ""), [y, N] = o(null), u = O(), S = !a && s !== "" && (e.takenKeys ?? []).includes(s), f = x(s) && !u.isPending;
10
+ const a = !!e.initial, [l, o] = d(((C = e.initial) == null ? void 0 : C.displayName) ?? ""), [s, h] = d(((v = e.initial) == null ? void 0 : v.key) ?? ""), [r, E] = d(((k = e.initial) == null ? void 0 : k.description) ?? ""), [y, N] = d(null), u = O(), S = !a && s !== "" && (e.takenKeys ?? []).includes(s), b = x(s) && !u.isPending;
11
11
  function w() {
12
12
  if (s) return;
13
13
  const t = A(l);
14
14
  t && h(t);
15
15
  }
16
- function b() {
16
+ function f() {
17
17
  var t;
18
18
  if (N(null), a) {
19
19
  (t = e.onSaved) == null || t.call(e, { displayName: l.trim(), description: r }), e.onClose();
@@ -31,15 +31,15 @@ function R(e) {
31
31
  // finishes it in the editor that opens next.
32
32
  },
33
33
  {
34
- onSuccess: (d) => {
34
+ onSuccess: (c) => {
35
35
  var g;
36
- return (g = e.onCreated) == null ? void 0 : g.call(e, d.endpoint.id);
36
+ return (g = e.onCreated) == null ? void 0 : g.call(e, c.endpoint.id);
37
37
  },
38
- onError: (d) => N(d instanceof I ? d.message : String(d))
38
+ onError: (c) => N(c instanceof I ? c.message : String(c))
39
39
  }
40
40
  );
41
41
  }
42
- const m = K(b, { enabled: f });
42
+ const m = K(f, { enabled: b });
43
43
  return /* @__PURE__ */ i(M, { title: a ? "Edit identity" : "New endpoint", onClose: e.onClose, children: [
44
44
  /* @__PURE__ */ i("div", { className: "modal-body", children: [
45
45
  /* @__PURE__ */ i("div", { className: "row field-row", children: [
@@ -50,7 +50,7 @@ function R(e) {
50
50
  {
51
51
  type: "text",
52
52
  value: l,
53
- onChange: (t) => c(t.target.value),
53
+ onChange: (t) => o(t.target.value),
54
54
  onBlur: w,
55
55
  placeholder: "Notify Customer",
56
56
  autoFocus: !0,
@@ -92,17 +92,17 @@ function R(e) {
92
92
  ] }),
93
93
  /* @__PURE__ */ i("div", { className: "modal-actions", children: [
94
94
  /* @__PURE__ */ n("button", { type: "button", className: "btn ghost", onClick: e.onClose, children: "Cancel" }),
95
- /* @__PURE__ */ n("button", { type: "button", className: "btn", disabled: !f, onClick: b, children: u.isPending ? "Creating…" : a ? "Save" : "Create" })
95
+ /* @__PURE__ */ n("button", { type: "button", className: "btn", disabled: !b, onClick: f, children: u.isPending ? "Creating…" : a ? "Save" : "Create" })
96
96
  ] })
97
97
  ] });
98
98
  }
99
99
  function H(e) {
100
- const [a] = o(() => F("endpoint")), l = D(e.takenKeys === void 0);
100
+ const [a] = d(() => F("endpoint")), l = D(e.takenKeys === void 0);
101
101
  return /* @__PURE__ */ n("div", { className: "w6w-embed-root", children: /* @__PURE__ */ n(
102
102
  R,
103
103
  {
104
104
  newId: a,
105
- takenKeys: e.takenKeys ?? (l.data ?? []).map((c) => c.key),
105
+ takenKeys: e.takenKeys ?? (l.data ?? []).map((o) => o.key),
106
106
  onClose: e.onClose,
107
107
  onCreated: e.onCreated
108
108
  }
@@ -110,13 +110,13 @@ function H(e) {
110
110
  }
111
111
  function V(e) {
112
112
  var C, v, k;
113
- const a = !!e.initial, [l, c] = o(((C = e.initial) == null ? void 0 : C.displayName) ?? ""), [s, h] = o(((v = e.initial) == null ? void 0 : v.key) ?? ""), [r, E] = o(((k = e.initial) == null ? void 0 : k.description) ?? ""), [y, N] = o(null), u = B(), S = !a && s !== "" && (e.takenKeys ?? []).includes(s), f = x(s) && !u.isPending;
113
+ const a = !!e.initial, [l, o] = d(((C = e.initial) == null ? void 0 : C.displayName) ?? ""), [s, h] = d(((v = e.initial) == null ? void 0 : v.key) ?? ""), [r, E] = d(((k = e.initial) == null ? void 0 : k.description) ?? ""), [y, N] = d(null), u = B(), S = !a && s !== "" && (e.takenKeys ?? []).includes(s), b = x(s) && !u.isPending;
114
114
  function w() {
115
115
  if (s) return;
116
116
  const t = A(l);
117
117
  t && h(t);
118
118
  }
119
- function b() {
119
+ function f() {
120
120
  var t;
121
121
  if (N(null), a) {
122
122
  (t = e.onSaved) == null || t.call(e, { displayName: l.trim(), description: r }), e.onClose();
@@ -135,15 +135,15 @@ function V(e) {
135
135
  // finishes it in the editor that opens next.
136
136
  },
137
137
  {
138
- onSuccess: (d) => {
138
+ onSuccess: (c) => {
139
139
  var g;
140
- return (g = e.onCreated) == null ? void 0 : g.call(e, d.id);
140
+ return (g = e.onCreated) == null ? void 0 : g.call(e, c.id);
141
141
  },
142
- onError: (d) => N(d instanceof I ? d.message : String(d))
142
+ onError: (c) => N(c instanceof I ? c.message : String(c))
143
143
  }
144
144
  );
145
145
  }
146
- const m = K(b, { enabled: f });
146
+ const m = K(f, { enabled: b });
147
147
  return /* @__PURE__ */ i(M, { title: a ? "Edit identity" : "New function", onClose: e.onClose, children: [
148
148
  /* @__PURE__ */ i("div", { className: "modal-body", children: [
149
149
  /* @__PURE__ */ i("div", { className: "row field-row", children: [
@@ -154,7 +154,7 @@ function V(e) {
154
154
  {
155
155
  type: "text",
156
156
  value: l,
157
- onChange: (t) => c(t.target.value),
157
+ onChange: (t) => o(t.target.value),
158
158
  onBlur: w,
159
159
  placeholder: "Send Email",
160
160
  autoFocus: !0,
@@ -196,17 +196,17 @@ function V(e) {
196
196
  ] }),
197
197
  /* @__PURE__ */ i("div", { className: "modal-actions", children: [
198
198
  /* @__PURE__ */ n("button", { type: "button", className: "btn ghost", onClick: e.onClose, children: "Cancel" }),
199
- /* @__PURE__ */ n("button", { type: "button", className: "btn", disabled: !f, onClick: b, children: u.isPending ? "Creating…" : a ? "Save" : "Create" })
199
+ /* @__PURE__ */ n("button", { type: "button", className: "btn", disabled: !b, onClick: f, children: u.isPending ? "Creating…" : a ? "Save" : "Create" })
200
200
  ] })
201
201
  ] });
202
202
  }
203
203
  function J(e) {
204
- const [a] = o(() => F("function")), l = P(e.takenKeys === void 0);
204
+ const [a] = d(() => F("function")), l = P(e.takenKeys === void 0);
205
205
  return /* @__PURE__ */ n("div", { className: "w6w-embed-root", children: /* @__PURE__ */ n(
206
206
  V,
207
207
  {
208
208
  newId: a,
209
- takenKeys: e.takenKeys ?? (l.data ?? []).map((c) => c.key),
209
+ takenKeys: e.takenKeys ?? (l.data ?? []).map((o) => o.key),
210
210
  onClose: e.onClose,
211
211
  onCreated: e.onCreated
212
212
  }
@@ -218,4 +218,4 @@ export {
218
218
  V as F,
219
219
  J as a
220
220
  };
221
- //# sourceMappingURL=CreateFunctionModal-DRsFx-FB.js.map
221
+ //# sourceMappingURL=CreateFunctionModal-DScxp_LN.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CreateFunctionModal-DRsFx-FB.js","sources":["../src/forms/CreateEndpointModal.tsx","../src/forms/CreateFunctionModal.tsx"],"sourcesContent":["import { ApiError } from \"@w6w/sdk\";\nimport { useEnterSubmit } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport { newCallableId } from \"../lib/callable-descriptors.ts\";\nimport { isEndpointKey, slugify } from \"../lib/slug.ts\";\nimport {\n ENDPOINT_MANIFEST_VERSION,\n useEndpointsQuery,\n useSaveEndpointMutation,\n} from \"../repos/endpoints.ts\";\n\n/**\n * Identity modal shared by the Endpoints list (\"+ New endpoint\" — create\n * mode) and the editor's read-only info block (\"edit\" icon-button — edit\n * mode). `isEdit = !!props.initial`, mirroring `VarModal` and `FunctionIdentityModal`.\n *\n * **Create mode POSTs for real, right here — before any editor exists.**\n * That is this node's whole point: the row is created against the server\n * before the operator can put target/input work into a plain `useState` that\n * used to die on a missing var, a lost tab, or anything else short of a\n * completed Save. Submit is disabled unless the key clears\n * {@link isEndpointKey}; `takenKeys` (from the list's own `GET /endpoints`)\n * is an ADVISORY pre-check only — the account-scoped unique index is the\n * arbiter, and any refusal (409 `endpoint_key_conflict`, 409\n * `key_immutable`, 400 `invalid_endpoint`) renders `ApiError.message`\n * verbatim and leaves the modal open with what was typed intact.\n *\n * **Edit mode writes NOTHING.** `POST /endpoints` is a whole-definition\n * upsert, so an identity-only PATCH here would silently wipe the target and\n * input the editor already has saved — precisely the data loss this whole\n * node exists to stop. The patched fields go back through `onSaved`; the\n * editor's own `onSave()` stays the one path that ever persists them.\n */\nexport function EndpointIdentityModal(props: {\n /** Edit mode when present; create mode when absent. Mirrors VarModal's `isEdit = !!props.initial`. */\n initial?: { key: string; displayName: string; description: string };\n /** Create mode only: the caller-minted `ep_…` id the POST carries. */\n newId?: string;\n /** Create mode only: keys already taken in this account — advisory pre-check. */\n takenKeys?: readonly string[];\n onClose: () => void;\n /** Create mode: the id the SERVER returned (`saved.endpoint.id`). */\n onCreated?: (id: string) => void;\n /** Edit mode: the patched identity fields. The modal itself writes NOTHING. */\n onSaved?: (next: { displayName: string; description: string }) => void;\n}) {\n const isEdit = !!props.initial;\n const [displayName, setDisplayName] = useState(props.initial?.displayName ?? \"\");\n const [key, setKey] = useState(props.initial?.key ?? \"\");\n const [description, setDescription] = useState(props.initial?.description ?? \"\");\n const [error, setError] = useState<string | null>(null);\n\n const saveMut = useSaveEndpointMutation();\n\n const keyTaken = !isEdit && key !== \"\" && (props.takenKeys ?? []).includes(key);\n const canSubmit = isEndpointKey(key) && !saveMut.isPending;\n\n function onNameBlur() {\n // The intake's own gate: \"on `name` blur, if the key is still empty, use\n // the name to generate it.\" — `!key`, not SignupPage's richer\n // `slugManual` latch (that richer behavior was not asked for here).\n if (key) return;\n const candidate = slugify(displayName);\n if (!candidate) return;\n setKey(candidate);\n }\n\n function submit() {\n setError(null);\n if (isEdit) {\n props.onSaved?.({ displayName: displayName.trim(), description });\n props.onClose();\n return;\n }\n saveMut.mutate(\n {\n manifestVersion: ENDPOINT_MANIFEST_VERSION,\n id: props.newId,\n key,\n displayName: displayName.trim(),\n description,\n // Deliberately NO `target` — this is the draft state (HITL-8): the\n // row is created, holds its `(account, key)` slot, and the operator\n // finishes it in the editor that opens next.\n },\n {\n onSuccess: (saved) => props.onCreated?.(saved.endpoint.id),\n onError: (e) => setError(e instanceof ApiError ? e.message : String(e)),\n },\n );\n }\n\n const enterSubmit = useEnterSubmit(submit, { enabled: canSubmit });\n\n return (\n <Modal title={isEdit ? \"Edit identity\" : \"New endpoint\"} onClose={props.onClose}>\n <div className=\"modal-body\">\n <div className=\"row field-row\">\n <label className=\"field\">\n <span>Name</span>\n <input\n type=\"text\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n onBlur={onNameBlur}\n placeholder=\"Notify Customer\"\n autoFocus\n {...enterSubmit}\n />\n </label>\n <label className=\"field\">\n <span>Key</span>\n <input\n type=\"text\"\n value={key}\n disabled={isEdit}\n onChange={(e) => setKey(e.target.value)}\n placeholder=\"notify-customer\"\n {...enterSubmit}\n />\n {!isEdit && (\n <span className=\"hint\">\n Lowercase, kebab-case, 3–39 characters. A public URL path segment — immutable after\n the first save.\n </span>\n )}\n {keyTaken && (\n <span className=\"hint\" data-testid=\"endpoint-key-taken\">\n Already in use in this account — the server has the final say.\n </span>\n )}\n </label>\n </div>\n\n <label className=\"field\">\n <span>Description</span>\n <input\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional\"\n {...enterSubmit}\n />\n </label>\n\n {error && <div className=\"result error\">{error}</div>}\n </div>\n\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Cancel\n </button>\n <button type=\"button\" className=\"btn\" disabled={!canSubmit} onClick={submit}>\n {saveMut.isPending ? \"Creating…\" : isEdit ? \"Save\" : \"Create\"}\n </button>\n </div>\n </Modal>\n );\n}\n\n/**\n * Creates an Endpoint: the identity modal in create mode, in its own `.w6w-embed-root`. The id is\n * minted once per mount. Without `takenKeys` the modal reads the account's keys itself\n * (`GET /endpoints`) for the advisory \"already in use\" hint; the server stays the arbiter.\n */\nexport function CreateEndpointModal(props: {\n onClose: () => void;\n /** The id the SERVER returned for the new Endpoint. */\n onCreated: (id: string) => void;\n /** Keys already taken in this account. Omitted: read from the Endpoints list. */\n takenKeys?: readonly string[];\n}) {\n const [newId] = useState(() => newCallableId(\"endpoint\"));\n const keys = useEndpointsQuery(props.takenKeys === undefined);\n return (\n <div className=\"w6w-embed-root\">\n <EndpointIdentityModal\n newId={newId}\n takenKeys={props.takenKeys ?? (keys.data ?? []).map((row) => row.key)}\n onClose={props.onClose}\n onCreated={props.onCreated}\n />\n </div>\n );\n}\n","import { ApiError } from \"@w6w/sdk\";\nimport { useEnterSubmit } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport { newCallableId } from \"../lib/callable-descriptors.ts\";\nimport { isEndpointKey, slugify } from \"../lib/slug.ts\";\nimport {\n FUNCTION_MANIFEST_VERSION,\n useFunctionsQuery,\n useSaveFunctionMutation,\n} from \"../repos/functions.ts\";\n\n/**\n * Identity modal shared by the Functions list (\"+ New function\" — create\n * mode) and the editor's read-only info block (\"edit\" icon-button — edit\n * mode). `isEdit = !!props.initial`, mirroring `VarModal` and\n * `EndpointIdentityModal`.\n *\n * **Create mode POSTs for real, right here — before any editor exists.**\n * That is this node's whole point: the row is created against the server\n * before the operator can put impl/input work into a plain `useState` that\n * used to die on a missing var, a lost tab, or anything else short of a\n * completed Save. Submit is disabled unless the key clears\n * {@link isEndpointKey} (reused — pin 2: the grammar is identical, so no\n * `isFunctionKey`); `takenKeys` (from the list's own `GET /functions`) is an\n * ADVISORY pre-check only — the account-scoped unique index is the arbiter,\n * and any refusal renders `ApiError.message` verbatim and leaves the modal\n * open with what was typed intact.\n *\n * **Edit mode writes NOTHING.** `POST /functions` is a whole-definition\n * upsert, so an identity-only PATCH here would silently wipe the impl and\n * inputs the editor already has saved — precisely the data loss this whole\n * node exists to stop. The patched fields go back through `onSaved`; the\n * editor's own `onSave()` stays the one path that ever persists them.\n */\nexport function FunctionIdentityModal(props: {\n /** Edit mode when present; create mode when absent. Mirrors VarModal's `isEdit = !!props.initial`. */\n initial?: { key: string; displayName: string; description: string };\n /** Create mode only: the caller-minted `fn_…` id the POST carries. */\n newId?: string;\n /** Create mode only: keys already taken in this account — advisory pre-check. */\n takenKeys?: readonly string[];\n onClose: () => void;\n /** Create mode: the id the SERVER returned (`saved.function.id`). */\n onCreated?: (id: string) => void;\n /** Edit mode: the patched identity fields. The modal itself writes NOTHING. */\n onSaved?: (next: { displayName: string; description: string }) => void;\n}) {\n const isEdit = !!props.initial;\n const [displayName, setDisplayName] = useState(props.initial?.displayName ?? \"\");\n const [key, setKey] = useState(props.initial?.key ?? \"\");\n const [description, setDescription] = useState(props.initial?.description ?? \"\");\n const [error, setError] = useState<string | null>(null);\n\n const saveMut = useSaveFunctionMutation();\n\n const keyTaken = !isEdit && key !== \"\" && (props.takenKeys ?? []).includes(key);\n // Pin 2: reuse `isEndpointKey` — the grammar is identical (kebab-case,\n // 3–39 chars, no `--` or trailing `-`), so a second `isFunctionKey` would\n // drift. Import it under its own name and note why right here.\n const canSubmit = isEndpointKey(key) && !saveMut.isPending;\n\n function onNameBlur() {\n // The intake's own gate: \"on `name` blur, if the key is still empty, use\n // the name to generate it.\" — `!key`, not SignupPage's richer\n // `slugManual` latch (that richer behavior was not asked for here).\n if (key) return;\n const candidate = slugify(displayName);\n if (!candidate) return;\n setKey(candidate);\n }\n\n function submit() {\n setError(null);\n if (isEdit) {\n props.onSaved?.({ displayName: displayName.trim(), description });\n props.onClose();\n return;\n }\n saveMut.mutate(\n {\n manifestVersion: FUNCTION_MANIFEST_VERSION,\n id: props.newId,\n key,\n displayName: displayName.trim(),\n description,\n inputs: [],\n // Deliberately NO `impl` — this is the draft state: the row is\n // created, holds its `(account, key)` slot, and the operator\n // finishes it in the editor that opens next.\n },\n {\n onSuccess: (saved: { id: string; key: string }) => props.onCreated?.(saved.id),\n onError: (e) => setError(e instanceof ApiError ? e.message : String(e)),\n },\n );\n }\n\n const enterSubmit = useEnterSubmit(submit, { enabled: canSubmit });\n\n return (\n <Modal title={isEdit ? \"Edit identity\" : \"New function\"} onClose={props.onClose}>\n <div className=\"modal-body\">\n <div className=\"row field-row\">\n <label className=\"field\">\n <span>Name</span>\n <input\n type=\"text\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n onBlur={onNameBlur}\n placeholder=\"Send Email\"\n autoFocus\n {...enterSubmit}\n />\n </label>\n <label className=\"field\">\n <span>Key</span>\n <input\n type=\"text\"\n value={key}\n disabled={isEdit}\n onChange={(e) => setKey(e.target.value)}\n placeholder=\"send-email\"\n {...enterSubmit}\n />\n {!isEdit && (\n <span className=\"hint\">\n Lowercase, kebab-case, 3–39 characters. A public URL path segment — immutable after\n the first save.\n </span>\n )}\n {keyTaken && (\n <span className=\"hint\" data-testid=\"function-key-taken\">\n Already in use in this account — the server has the final say.\n </span>\n )}\n </label>\n </div>\n\n <label className=\"field\">\n <span>Description</span>\n <input\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional\"\n {...enterSubmit}\n />\n </label>\n\n {error && <div className=\"result error\">{error}</div>}\n </div>\n\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Cancel\n </button>\n <button type=\"button\" className=\"btn\" disabled={!canSubmit} onClick={submit}>\n {saveMut.isPending ? \"Creating…\" : isEdit ? \"Save\" : \"Create\"}\n </button>\n </div>\n </Modal>\n );\n}\n\n/**\n * Creates a Function: the identity modal in create mode, in its own `.w6w-embed-root`. The id is\n * minted once per mount. Without `takenKeys` the modal reads the account's keys itself\n * (`GET /functions`) for the advisory \"already in use\" hint; the server stays the arbiter.\n */\nexport function CreateFunctionModal(props: {\n onClose: () => void;\n /** The id the SERVER returned for the new Function. */\n onCreated: (id: string) => void;\n /** Keys already taken in this account. Omitted: read from the Functions list. */\n takenKeys?: readonly string[];\n}) {\n const [newId] = useState(() => newCallableId(\"function\"));\n const keys = useFunctionsQuery(props.takenKeys === undefined);\n return (\n <div className=\"w6w-embed-root\">\n <FunctionIdentityModal\n newId={newId}\n takenKeys={props.takenKeys ?? (keys.data ?? []).map((row) => row.key)}\n onClose={props.onClose}\n onCreated={props.onCreated}\n />\n </div>\n );\n}\n"],"names":["EndpointIdentityModal","props","isEdit","displayName","setDisplayName","useState","_a","key","setKey","_b","description","setDescription","_c","error","setError","saveMut","useSaveEndpointMutation","keyTaken","canSubmit","isEndpointKey","onNameBlur","candidate","slugify","submit","ENDPOINT_MANIFEST_VERSION","saved","e","ApiError","enterSubmit","useEnterSubmit","jsxs","Modal","jsx","CreateEndpointModal","newId","newCallableId","keys","useEndpointsQuery","row","FunctionIdentityModal","useSaveFunctionMutation","FUNCTION_MANIFEST_VERSION","CreateFunctionModal","useFunctionsQuery"],"mappings":"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"}
1
+ {"version":3,"file":"CreateFunctionModal-DScxp_LN.js","sources":["../src/forms/CreateEndpointModal.tsx","../src/forms/CreateFunctionModal.tsx"],"sourcesContent":["import { ApiError } from \"@w6w/sdk\";\nimport { useEnterSubmit } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport { newCallableId } from \"../lib/callable-descriptors.ts\";\nimport { isEndpointKey, slugify } from \"../lib/slug.ts\";\nimport {\n ENDPOINT_MANIFEST_VERSION,\n useEndpointsQuery,\n useSaveEndpointMutation,\n} from \"../repos/endpoints.ts\";\n\n/**\n * Identity modal shared by the Endpoints list (\"+ New endpoint\" — create\n * mode) and the editor's read-only info block (\"edit\" icon-button — edit\n * mode). `isEdit = !!props.initial`, mirroring `VarModal` and `FunctionIdentityModal`.\n *\n * **Create mode POSTs for real, right here — before any editor exists.**\n * That is this node's whole point: the row is created against the server\n * before the operator can put target/input work into a plain `useState` that\n * used to die on a missing var, a lost tab, or anything else short of a\n * completed Save. Submit is disabled unless the key clears\n * {@link isEndpointKey}; `takenKeys` (from the list's own `GET /endpoints`)\n * is an ADVISORY pre-check only — the account-scoped unique index is the\n * arbiter, and any refusal (409 `endpoint_key_conflict`, 409\n * `key_immutable`, 400 `invalid_endpoint`) renders `ApiError.message`\n * verbatim and leaves the modal open with what was typed intact.\n *\n * **Edit mode writes NOTHING.** `POST /endpoints` is a whole-definition\n * upsert, so an identity-only PATCH here would silently wipe the target and\n * input the editor already has saved — precisely the data loss this whole\n * node exists to stop. The patched fields go back through `onSaved`; the\n * editor's own `onSave()` stays the one path that ever persists them.\n */\nexport function EndpointIdentityModal(props: {\n /** Edit mode when present; create mode when absent. Mirrors VarModal's `isEdit = !!props.initial`. */\n initial?: { key: string; displayName: string; description: string };\n /** Create mode only: the caller-minted `ep_…` id the POST carries. */\n newId?: string;\n /** Create mode only: keys already taken in this account — advisory pre-check. */\n takenKeys?: readonly string[];\n onClose: () => void;\n /** Create mode: the id the SERVER returned (`saved.endpoint.id`). */\n onCreated?: (id: string) => void;\n /** Edit mode: the patched identity fields. The modal itself writes NOTHING. */\n onSaved?: (next: { displayName: string; description: string }) => void;\n}) {\n const isEdit = !!props.initial;\n const [displayName, setDisplayName] = useState(props.initial?.displayName ?? \"\");\n const [key, setKey] = useState(props.initial?.key ?? \"\");\n const [description, setDescription] = useState(props.initial?.description ?? \"\");\n const [error, setError] = useState<string | null>(null);\n\n const saveMut = useSaveEndpointMutation();\n\n const keyTaken = !isEdit && key !== \"\" && (props.takenKeys ?? []).includes(key);\n const canSubmit = isEndpointKey(key) && !saveMut.isPending;\n\n function onNameBlur() {\n // The intake's own gate: \"on `name` blur, if the key is still empty, use\n // the name to generate it.\" — `!key`, not SignupPage's richer\n // `slugManual` latch (that richer behavior was not asked for here).\n if (key) return;\n const candidate = slugify(displayName);\n if (!candidate) return;\n setKey(candidate);\n }\n\n function submit() {\n setError(null);\n if (isEdit) {\n props.onSaved?.({ displayName: displayName.trim(), description });\n props.onClose();\n return;\n }\n saveMut.mutate(\n {\n manifestVersion: ENDPOINT_MANIFEST_VERSION,\n id: props.newId,\n key,\n displayName: displayName.trim(),\n description,\n // Deliberately NO `target` — this is the draft state (HITL-8): the\n // row is created, holds its `(account, key)` slot, and the operator\n // finishes it in the editor that opens next.\n },\n {\n onSuccess: (saved) => props.onCreated?.(saved.endpoint.id),\n onError: (e) => setError(e instanceof ApiError ? e.message : String(e)),\n },\n );\n }\n\n const enterSubmit = useEnterSubmit(submit, { enabled: canSubmit });\n\n return (\n <Modal title={isEdit ? \"Edit identity\" : \"New endpoint\"} onClose={props.onClose}>\n <div className=\"modal-body\">\n <div className=\"row field-row\">\n <label className=\"field\">\n <span>Name</span>\n <input\n type=\"text\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n onBlur={onNameBlur}\n placeholder=\"Notify Customer\"\n autoFocus\n {...enterSubmit}\n />\n </label>\n <label className=\"field\">\n <span>Key</span>\n <input\n type=\"text\"\n value={key}\n disabled={isEdit}\n onChange={(e) => setKey(e.target.value)}\n placeholder=\"notify-customer\"\n {...enterSubmit}\n />\n {!isEdit && (\n <span className=\"hint\">\n Lowercase, kebab-case, 3–39 characters. A public URL path segment — immutable after\n the first save.\n </span>\n )}\n {keyTaken && (\n <span className=\"hint\" data-testid=\"endpoint-key-taken\">\n Already in use in this account — the server has the final say.\n </span>\n )}\n </label>\n </div>\n\n <label className=\"field\">\n <span>Description</span>\n <input\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional\"\n {...enterSubmit}\n />\n </label>\n\n {error && <div className=\"result error\">{error}</div>}\n </div>\n\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Cancel\n </button>\n <button type=\"button\" className=\"btn\" disabled={!canSubmit} onClick={submit}>\n {saveMut.isPending ? \"Creating…\" : isEdit ? \"Save\" : \"Create\"}\n </button>\n </div>\n </Modal>\n );\n}\n\n/**\n * Creates an Endpoint: the identity modal in create mode, in its own `.w6w-embed-root`. The id is\n * minted once per mount. Without `takenKeys` the modal reads the account's keys itself\n * (`GET /endpoints`) for the advisory \"already in use\" hint; the server stays the arbiter.\n */\nexport function CreateEndpointModal(props: {\n onClose: () => void;\n /** The id the SERVER returned for the new Endpoint. */\n onCreated: (id: string) => void;\n /** Keys already taken in this account. Omitted: read from the Endpoints list. */\n takenKeys?: readonly string[];\n}) {\n const [newId] = useState(() => newCallableId(\"endpoint\"));\n const keys = useEndpointsQuery(props.takenKeys === undefined);\n return (\n <div className=\"w6w-embed-root\">\n <EndpointIdentityModal\n newId={newId}\n takenKeys={props.takenKeys ?? (keys.data ?? []).map((row) => row.key)}\n onClose={props.onClose}\n onCreated={props.onCreated}\n />\n </div>\n );\n}\n","import { ApiError } from \"@w6w/sdk\";\nimport { useEnterSubmit } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport { newCallableId } from \"../lib/callable-descriptors.ts\";\nimport { isEndpointKey, slugify } from \"../lib/slug.ts\";\nimport {\n FUNCTION_MANIFEST_VERSION,\n useFunctionsQuery,\n useSaveFunctionMutation,\n} from \"../repos/functions.ts\";\n\n/**\n * Identity modal shared by the Functions list (\"+ New function\" — create\n * mode) and the editor's read-only info block (\"edit\" icon-button — edit\n * mode). `isEdit = !!props.initial`, mirroring `VarModal` and\n * `EndpointIdentityModal`.\n *\n * **Create mode POSTs for real, right here — before any editor exists.**\n * That is this node's whole point: the row is created against the server\n * before the operator can put impl/input work into a plain `useState` that\n * used to die on a missing var, a lost tab, or anything else short of a\n * completed Save. Submit is disabled unless the key clears\n * {@link isEndpointKey} (reused — pin 2: the grammar is identical, so no\n * `isFunctionKey`); `takenKeys` (from the list's own `GET /functions`) is an\n * ADVISORY pre-check only — the account-scoped unique index is the arbiter,\n * and any refusal renders `ApiError.message` verbatim and leaves the modal\n * open with what was typed intact.\n *\n * **Edit mode writes NOTHING.** `POST /functions` is a whole-definition\n * upsert, so an identity-only PATCH here would silently wipe the impl and\n * inputs the editor already has saved — precisely the data loss this whole\n * node exists to stop. The patched fields go back through `onSaved`; the\n * editor's own `onSave()` stays the one path that ever persists them.\n */\nexport function FunctionIdentityModal(props: {\n /** Edit mode when present; create mode when absent. Mirrors VarModal's `isEdit = !!props.initial`. */\n initial?: { key: string; displayName: string; description: string };\n /** Create mode only: the caller-minted `fn_…` id the POST carries. */\n newId?: string;\n /** Create mode only: keys already taken in this account — advisory pre-check. */\n takenKeys?: readonly string[];\n onClose: () => void;\n /** Create mode: the id the SERVER returned (`saved.function.id`). */\n onCreated?: (id: string) => void;\n /** Edit mode: the patched identity fields. The modal itself writes NOTHING. */\n onSaved?: (next: { displayName: string; description: string }) => void;\n}) {\n const isEdit = !!props.initial;\n const [displayName, setDisplayName] = useState(props.initial?.displayName ?? \"\");\n const [key, setKey] = useState(props.initial?.key ?? \"\");\n const [description, setDescription] = useState(props.initial?.description ?? \"\");\n const [error, setError] = useState<string | null>(null);\n\n const saveMut = useSaveFunctionMutation();\n\n const keyTaken = !isEdit && key !== \"\" && (props.takenKeys ?? []).includes(key);\n // Pin 2: reuse `isEndpointKey` — the grammar is identical (kebab-case,\n // 3–39 chars, no `--` or trailing `-`), so a second `isFunctionKey` would\n // drift. Import it under its own name and note why right here.\n const canSubmit = isEndpointKey(key) && !saveMut.isPending;\n\n function onNameBlur() {\n // The intake's own gate: \"on `name` blur, if the key is still empty, use\n // the name to generate it.\" — `!key`, not SignupPage's richer\n // `slugManual` latch (that richer behavior was not asked for here).\n if (key) return;\n const candidate = slugify(displayName);\n if (!candidate) return;\n setKey(candidate);\n }\n\n function submit() {\n setError(null);\n if (isEdit) {\n props.onSaved?.({ displayName: displayName.trim(), description });\n props.onClose();\n return;\n }\n saveMut.mutate(\n {\n manifestVersion: FUNCTION_MANIFEST_VERSION,\n id: props.newId,\n key,\n displayName: displayName.trim(),\n description,\n inputs: [],\n // Deliberately NO `impl` — this is the draft state: the row is\n // created, holds its `(account, key)` slot, and the operator\n // finishes it in the editor that opens next.\n },\n {\n onSuccess: (saved: { id: string; key: string }) => props.onCreated?.(saved.id),\n onError: (e) => setError(e instanceof ApiError ? e.message : String(e)),\n },\n );\n }\n\n const enterSubmit = useEnterSubmit(submit, { enabled: canSubmit });\n\n return (\n <Modal title={isEdit ? \"Edit identity\" : \"New function\"} onClose={props.onClose}>\n <div className=\"modal-body\">\n <div className=\"row field-row\">\n <label className=\"field\">\n <span>Name</span>\n <input\n type=\"text\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n onBlur={onNameBlur}\n placeholder=\"Send Email\"\n autoFocus\n {...enterSubmit}\n />\n </label>\n <label className=\"field\">\n <span>Key</span>\n <input\n type=\"text\"\n value={key}\n disabled={isEdit}\n onChange={(e) => setKey(e.target.value)}\n placeholder=\"send-email\"\n {...enterSubmit}\n />\n {!isEdit && (\n <span className=\"hint\">\n Lowercase, kebab-case, 3–39 characters. A public URL path segment — immutable after\n the first save.\n </span>\n )}\n {keyTaken && (\n <span className=\"hint\" data-testid=\"function-key-taken\">\n Already in use in this account — the server has the final say.\n </span>\n )}\n </label>\n </div>\n\n <label className=\"field\">\n <span>Description</span>\n <input\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional\"\n {...enterSubmit}\n />\n </label>\n\n {error && <div className=\"result error\">{error}</div>}\n </div>\n\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Cancel\n </button>\n <button type=\"button\" className=\"btn\" disabled={!canSubmit} onClick={submit}>\n {saveMut.isPending ? \"Creating…\" : isEdit ? \"Save\" : \"Create\"}\n </button>\n </div>\n </Modal>\n );\n}\n\n/**\n * Creates a Function: the identity modal in create mode, in its own `.w6w-embed-root`. The id is\n * minted once per mount. Without `takenKeys` the modal reads the account's keys itself\n * (`GET /functions`) for the advisory \"already in use\" hint; the server stays the arbiter.\n */\nexport function CreateFunctionModal(props: {\n onClose: () => void;\n /** The id the SERVER returned for the new Function. */\n onCreated: (id: string) => void;\n /** Keys already taken in this account. Omitted: read from the Functions list. */\n takenKeys?: readonly string[];\n}) {\n const [newId] = useState(() => newCallableId(\"function\"));\n const keys = useFunctionsQuery(props.takenKeys === undefined);\n return (\n <div className=\"w6w-embed-root\">\n <FunctionIdentityModal\n newId={newId}\n takenKeys={props.takenKeys ?? (keys.data ?? []).map((row) => row.key)}\n onClose={props.onClose}\n onCreated={props.onCreated}\n />\n </div>\n );\n}\n"],"names":["EndpointIdentityModal","props","isEdit","displayName","setDisplayName","useState","_a","key","setKey","_b","description","setDescription","_c","error","setError","saveMut","useSaveEndpointMutation","keyTaken","canSubmit","isEndpointKey","onNameBlur","candidate","slugify","submit","ENDPOINT_MANIFEST_VERSION","saved","e","ApiError","enterSubmit","useEnterSubmit","jsxs","Modal","jsx","CreateEndpointModal","newId","newCallableId","keys","useEndpointsQuery","row","FunctionIdentityModal","useSaveFunctionMutation","FUNCTION_MANIFEST_VERSION","CreateFunctionModal","useFunctionsQuery"],"mappings":"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"}
@@ -2,10 +2,10 @@ import { jsxs as a, jsx as t } from "react/jsx-runtime";
2
2
  import { ApiError as k } from "@w6w/sdk";
3
3
  import { useEnterSubmit as x, JsonEditor as D, YamlEditor as A, CodeEditor as F } from "@w6w/ui";
4
4
  import { useState as o } from "react";
5
- import { M as w } from "./ConfirmModal-RLbZT5_k.js";
6
- import { G as K, W as O } from "./spec-import-CjmxyZDR.js";
5
+ import { M as w } from "./ConfirmModal-Pv2-A_3U.js";
6
+ import { u as K, a as O } from "./spec-import-SWOonsNr.js";
7
7
  const P = ["text", "markdown", "yaml", "html", "json"];
8
- function W(e) {
8
+ function $(e) {
9
9
  var y, N, j, p;
10
10
  const r = !!e.initial, [c, S] = o(((y = e.initial) == null ? void 0 : y.key) ?? ""), [i, E] = o(((N = e.initial) == null ? void 0 : N.format) ?? "text"), [l, s] = o(((j = e.initial) == null ? void 0 : j.content) ?? ""), [d, M] = o(((p = e.initial) == null ? void 0 : p.description) ?? ""), [v, m] = o(null), b = K(), g = O(), u = b.isPending || g.isPending;
11
11
  function C() {
@@ -84,6 +84,6 @@ function W(e) {
84
84
  );
85
85
  }
86
86
  export {
87
- W as D
87
+ $ as D
88
88
  };
89
- //# sourceMappingURL=DocumentFormModal-BExK1V-B.js.map
89
+ //# sourceMappingURL=DocumentFormModal-Br4s8wmi.js.map