@w6w/embed 0.2.0 → 0.2.11

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 (119) hide show
  1. package/dist/{ConfirmModal-RLbZT5_k.js → ConfirmModal-BE-SdX-O.js} +53 -49
  2. package/dist/{ConfirmModal-RLbZT5_k.js.map → ConfirmModal-BE-SdX-O.js.map} +1 -1
  3. package/dist/{CreateFunctionModal-DRsFx-FB.js → CreateFunctionModal-D6CQLpa_.js} +25 -25
  4. package/dist/{CreateFunctionModal-DRsFx-FB.js.map → CreateFunctionModal-D6CQLpa_.js.map} +1 -1
  5. package/dist/{DocumentFormModal-BExK1V-B.js → DocumentFormModal-YauVdolr.js} +5 -5
  6. package/dist/{DocumentFormModal-BExK1V-B.js.map → DocumentFormModal-YauVdolr.js.map} +1 -1
  7. package/dist/{ImportSpecModal-BDQIf6rg.js → ImportSpecModal-B7qd1Km2.js} +3 -3
  8. package/dist/{ImportSpecModal-BDQIf6rg.js.map → ImportSpecModal-B7qd1Km2.js.map} +1 -1
  9. package/dist/ModelRoutesManager-BGESQahw.js +345 -0
  10. package/dist/ModelRoutesManager-BGESQahw.js.map +1 -0
  11. package/dist/WorkflowEditor-CwvmAGp2.js +925 -0
  12. package/dist/WorkflowEditor-CwvmAGp2.js.map +1 -0
  13. package/dist/{apps-1FNUwbGv.js → apps-CboASBKr.js} +14 -14
  14. package/dist/{apps-1FNUwbGv.js.map → apps-CboASBKr.js.map} +1 -1
  15. package/dist/{callables-3mFrMVG_.js → callables-tOlflvbl.js} +11 -11
  16. package/dist/{callables-3mFrMVG_.js.map → callables-tOlflvbl.js.map} +1 -1
  17. package/dist/chrome/ConfirmModal.d.ts +4 -1
  18. package/dist/chrome/workspace.d.ts +4 -0
  19. package/dist/{coerce-input-BicYr7nc.js → coerce-input-DttlcSdO.js} +70 -58
  20. package/dist/coerce-input-DttlcSdO.js.map +1 -0
  21. package/dist/connections-D7cgXhDS.js +119 -0
  22. package/dist/connections-D7cgXhDS.js.map +1 -0
  23. package/dist/credentials-DaQU3Ca_.js +171 -0
  24. package/dist/credentials-DaQU3Ca_.js.map +1 -0
  25. package/dist/document-sources-UCwe8x77.js +91 -0
  26. package/dist/document-sources-UCwe8x77.js.map +1 -0
  27. package/dist/draft.mjs +1 -1
  28. package/dist/editor/BindingBanner.d.ts +13 -0
  29. package/dist/editor/CallableEditorFrame.d.ts +7 -0
  30. package/dist/editor/EndpointCards.d.ts +4 -1
  31. package/dist/editor/PublishControl.d.ts +19 -0
  32. package/dist/editor/TargetSelector.d.ts +15 -0
  33. package/dist/editor/TargetSelector.types.d.ts +2 -0
  34. package/dist/editor/definition.d.ts +2 -0
  35. package/dist/{editor-apps-BdenSV1o.js → editor-apps-BUZWld-m.js} +5 -5
  36. package/dist/{editor-apps-BdenSV1o.js.map → editor-apps-BUZWld-m.js.map} +1 -1
  37. package/dist/{editor-tools-RxmY5iyi.js → editor-tools-B_Lfx3kw.js} +11 -11
  38. package/dist/editor-tools-B_Lfx3kw.js.map +1 -0
  39. package/dist/editor.mjs +1 -1
  40. package/dist/editors.mjs +769 -622
  41. package/dist/editors.mjs.map +1 -1
  42. package/dist/{endpoints-B2ynbZo-.js → endpoints-DSRo1Lc5.js} +113 -107
  43. package/dist/endpoints-DSRo1Lc5.js.map +1 -0
  44. package/dist/fields-DvS8XZFc.js +21 -0
  45. package/dist/fields-DvS8XZFc.js.map +1 -0
  46. package/dist/forms/ModelBudgetsManager.d.ts +9 -0
  47. package/dist/forms/ModelRoutesManager.d.ts +14 -0
  48. package/dist/forms.d.ts +4 -0
  49. package/dist/forms.mjs +611 -212
  50. package/dist/forms.mjs.map +1 -1
  51. package/dist/index.mjs +119 -112
  52. package/dist/index.mjs.map +1 -1
  53. package/dist/lib/binding-problems.d.ts +38 -0
  54. package/dist/lib/code-rail.d.ts +4 -2
  55. package/dist/lib/index.d.ts +1 -0
  56. package/dist/lib/invoke-error.d.ts +1 -0
  57. package/dist/lib/sdk-snippets.d.ts +1 -1
  58. package/dist/lib/target-fields.d.ts +8 -0
  59. package/dist/lib/trigger-preview.d.ts +1 -0
  60. package/dist/lib/workflow-live-run.d.ts +9 -2
  61. package/dist/lib/workflow-nodes.d.ts +5 -0
  62. package/dist/lib/workflow-validity.d.ts +1 -0
  63. package/dist/lib.mjs +72 -70
  64. package/dist/lists/ConnectionDependents.d.ts +31 -0
  65. package/dist/lists/ConnectionDetail.d.ts +4 -1
  66. package/dist/lists/ConnectionList.d.ts +4 -1
  67. package/dist/lists/CredentialDetail.d.ts +15 -0
  68. package/dist/lists/CredentialList.d.ts +14 -0
  69. package/dist/lists/ModelCatalog.d.ts +12 -0
  70. package/dist/lists/ModelUsage.d.ts +12 -0
  71. package/dist/lists.d.ts +8 -0
  72. package/dist/lists.mjs +1322 -604
  73. package/dist/lists.mjs.map +1 -1
  74. package/dist/models-bAayQPJ_.js +270 -0
  75. package/dist/models-bAayQPJ_.js.map +1 -0
  76. package/dist/{project-context-BiCjv_E3.js → project-context-Tvp-La7A.js} +3 -3
  77. package/dist/{project-context-BiCjv_E3.js.map → project-context-Tvp-La7A.js.map} +1 -1
  78. package/dist/rail.mjs +4 -4
  79. package/dist/repos/agents-studio-agents.d.ts +52 -0
  80. package/dist/repos/agents-studio-assets.d.ts +68 -0
  81. package/dist/repos/connections.d.ts +30 -12
  82. package/dist/repos/credentials.d.ts +83 -0
  83. package/dist/repos/endpoints.d.ts +9 -3
  84. package/dist/repos/fields.d.ts +34 -0
  85. package/dist/repos/functions.d.ts +7 -5
  86. package/dist/repos/index.d.ts +5 -0
  87. package/dist/repos/models.d.ts +289 -0
  88. package/dist/repos.mjs +613 -176
  89. package/dist/repos.mjs.map +1 -1
  90. package/dist/{slug-C4ktDPdy.js → slug-BVdgiP_L.js} +64 -60
  91. package/dist/slug-BVdgiP_L.js.map +1 -0
  92. package/dist/{spec-export-Cf3VQSQS.js → spec-export-CBbloO_n.js} +7 -7
  93. package/dist/{spec-export-Cf3VQSQS.js.map → spec-export-CBbloO_n.js.map} +1 -1
  94. package/dist/{spec-import-CjmxyZDR.js → spec-import-CW6R_Wk1.js} +160 -156
  95. package/dist/spec-import-CW6R_Wk1.js.map +1 -0
  96. package/dist/theme-context-E2ZhlXDX.js +6 -0
  97. package/dist/theme-context-E2ZhlXDX.js.map +1 -0
  98. package/dist/theme-context.d.ts +2 -0
  99. package/dist/trigger-preview-DKxfjzUY.js +145 -0
  100. package/dist/trigger-preview-DKxfjzUY.js.map +1 -0
  101. package/dist/{use-callable-draft-zHLpcr-b.js → use-callable-draft-DsALnSfF.js} +22 -22
  102. package/dist/{use-callable-draft-zHLpcr-b.js.map → use-callable-draft-DsALnSfF.js.map} +1 -1
  103. package/dist/{workflow-blank-DyL3_RUA.js → workflow-blank-DFpGObrn.js} +6 -6
  104. package/dist/{workflow-blank-DyL3_RUA.js.map → workflow-blank-DFpGObrn.js.map} +1 -1
  105. package/package.json +1 -1
  106. package/src/styles.css +2 -6
  107. package/dist/WorkflowEditor-DlbVv6Fs.js +0 -854
  108. package/dist/WorkflowEditor-DlbVv6Fs.js.map +0 -1
  109. package/dist/coerce-input-BicYr7nc.js.map +0 -1
  110. package/dist/connections-CjjYeRqb.js +0 -78
  111. package/dist/connections-CjjYeRqb.js.map +0 -1
  112. package/dist/document-sources-C0grrtdq.js +0 -86
  113. package/dist/document-sources-C0grrtdq.js.map +0 -1
  114. package/dist/editor-tools-RxmY5iyi.js.map +0 -1
  115. package/dist/endpoints-B2ynbZo-.js.map +0 -1
  116. package/dist/slug-C4ktDPdy.js.map +0 -1
  117. package/dist/spec-import-CjmxyZDR.js.map +0 -1
  118. package/dist/trigger-preview-VPkrryDl.js +0 -120
  119. package/dist/trigger-preview-VPkrryDl.js.map +0 -1
@@ -1,41 +1,41 @@
1
1
  import { jsx as e, jsxs as i, Fragment as u } from "react/jsx-runtime";
2
- import { b as W, u as E } from "./slug-C4ktDPdy.js";
2
+ import { b as W, u as E } from "./slug-BVdgiP_L.js";
3
3
  import { IconButton as S, Modal as _, CodeBlock as B } from "@w6w/ui";
4
4
  import { useRef as L, useEffect as x, useState as N } from "react";
5
5
  function R({
6
- title: o,
6
+ title: d,
7
7
  onClose: n,
8
8
  children: r,
9
- wide: s = !1,
10
- xl: m = !1,
9
+ wide: m = !1,
10
+ xl: s = !1,
11
11
  headerRight: c
12
12
  }) {
13
13
  const p = L(null);
14
14
  return x(() => {
15
- const d = p.current;
16
- if (!d) return;
17
- d.open || d.showModal();
18
- const f = (t) => {
19
- t.preventDefault(), n();
20
- }, b = (t) => {
21
- if (t.target !== d) return;
22
- const a = d.getBoundingClientRect();
23
- (t.clientX < a.left || t.clientX > a.right || t.clientY < a.top || t.clientY > a.bottom) && n();
15
+ const a = p.current;
16
+ if (!a) return;
17
+ a.open || a.showModal();
18
+ const f = (o) => {
19
+ o.preventDefault(), n();
20
+ }, b = (o) => {
21
+ if (o.target !== a) return;
22
+ const t = a.getBoundingClientRect();
23
+ (o.clientX < t.left || o.clientX > t.right || o.clientY < t.top || o.clientY > t.bottom) && n();
24
24
  };
25
- return d.addEventListener("cancel", f), d.addEventListener("click", b), () => {
26
- d.removeEventListener("cancel", f), d.removeEventListener("click", b);
25
+ return a.addEventListener("cancel", f), a.addEventListener("click", b), () => {
26
+ a.removeEventListener("cancel", f), a.removeEventListener("click", b);
27
27
  };
28
28
  }, [n]), /* @__PURE__ */ e("div", { className: "modal-backdrop", children: /* @__PURE__ */ i(
29
29
  "dialog",
30
30
  {
31
31
  ref: p,
32
- className: `modal${s ? " modal-wide" : ""}${m ? " modal-xl" : ""}`,
33
- "aria-label": o,
32
+ className: `modal${m ? " modal-wide" : ""}${s ? " modal-xl" : ""}`,
33
+ "aria-label": d,
34
34
  children: [
35
35
  c ? /* @__PURE__ */ i("div", { className: "modal-head", children: [
36
- /* @__PURE__ */ e("h3", { children: o }),
36
+ /* @__PURE__ */ e("h3", { children: d }),
37
37
  c
38
- ] }) : /* @__PURE__ */ e("h3", { children: o }),
38
+ ] }) : /* @__PURE__ */ e("h3", { children: d }),
39
39
  r
40
40
  ]
41
41
  }
@@ -47,34 +47,34 @@ const y = [
47
47
  { id: "python", label: "Python", language: "Python", grammar: "python", icon: "lang-python" },
48
48
  { id: "curl", label: "curl", language: "Shell", grammar: "bash", icon: "lang-curl" }
49
49
  ];
50
- function F(o) {
51
- const n = W(o);
50
+ function F(d) {
51
+ const n = W(d);
52
52
  return n ? y.filter((r) => typeof n[r.id] == "string") : [];
53
53
  }
54
54
  function M({
55
- resource: o,
55
+ resource: d,
56
56
  triggers: n,
57
57
  wrap: r = !1,
58
- maxHeight: s = "420px",
59
- initialTab: m
58
+ maxHeight: m = "420px",
59
+ initialTab: s
60
60
  }) {
61
61
  var v, C, w;
62
- const [c, p] = N(m ?? "node"), [d, f] = N(0), b = !!n && n.length > 0, t = b ? n[Math.min(d, n.length - 1)] ?? n[0] : null, a = W(o, t == null ? void 0 : t.fields), g = a ? y.filter((l) => typeof a[l.id] == "string") : [], h = g.some((l) => l.id === c) ? c : ((v = g[0]) == null ? void 0 : v.id) ?? "node", k = (a == null ? void 0 : a[h]) ?? "";
63
- return a === null ? /* @__PURE__ */ e("p", { className: "muted", children: E(o) }) : /* @__PURE__ */ i(u, { children: [
64
- b && t && /* @__PURE__ */ i("div", { className: "subpanel", style: { marginTop: 0, paddingTop: 0, borderTop: "none" }, children: [
62
+ const [c, p] = N(s ?? "node"), [a, f] = N(0), b = !!n && n.length > 0, o = b ? n[Math.min(a, n.length - 1)] ?? n[0] : null, t = W(d, o == null ? void 0 : o.fields), g = t ? y.filter((l) => typeof t[l.id] == "string") : [], h = g.some((l) => l.id === c) ? c : ((v = g[0]) == null ? void 0 : v.id) ?? "node", k = (t == null ? void 0 : t[h]) ?? "";
63
+ return t === null ? /* @__PURE__ */ e("p", { className: "muted", children: E(d) }) : /* @__PURE__ */ i(u, { children: [
64
+ b && o && /* @__PURE__ */ i("div", { className: "subpanel", style: { marginTop: 0, paddingTop: 0, borderTop: "none" }, children: [
65
65
  /* @__PURE__ */ i("div", { "data-testid": "trigger-panel", children: [
66
66
  /* @__PURE__ */ e("div", { className: "code-tabs", children: n.map((l, T) => /* @__PURE__ */ e(
67
67
  "button",
68
68
  {
69
69
  type: "button",
70
- className: `code-tab${T === d ? " active" : ""}`,
70
+ className: `code-tab${T === a ? " active" : ""}`,
71
71
  "data-testid": "trigger-tab",
72
72
  onClick: () => f(T),
73
73
  children: l.label
74
74
  },
75
75
  l.id
76
76
  )) }),
77
- t.fields.length === 0 && /* @__PURE__ */ e("p", { className: "muted small", children: "This trigger declares no fields." })
77
+ o.fields.length === 0 && /* @__PURE__ */ e("p", { className: "muted small", children: "This trigger declares no fields." })
78
78
  ] }),
79
79
  n.length > 1 && /* @__PURE__ */ i("p", { className: "muted small", "data-testid": "trigger-multi-note", children: [
80
80
  "This workflow has ",
@@ -97,7 +97,7 @@ function M({
97
97
  {
98
98
  code: k,
99
99
  language: ((C = y.find((l) => l.id === h)) == null ? void 0 : C.grammar) ?? "plaintext",
100
- maxHeight: s,
100
+ maxHeight: m,
101
101
  wrap: r,
102
102
  "aria-label": `${((w = y.find((l) => l.id === h)) == null ? void 0 : w.label) ?? h} snippet`,
103
103
  copyable: !0
@@ -110,7 +110,7 @@ function M({
110
110
  " and ",
111
111
  /* @__PURE__ */ e("code", { children: "W6W_TOKEN" }),
112
112
  " · operation ",
113
- /* @__PURE__ */ e("code", { children: a.operation })
113
+ /* @__PURE__ */ e("code", { children: t.operation })
114
114
  ] }) : h === "cli" ? /* @__PURE__ */ i(u, { children: [
115
115
  /* @__PURE__ */ e("code", { children: "npm i -g @w6w/cli" }),
116
116
  " · set ",
@@ -123,7 +123,7 @@ function M({
123
123
  " / ",
124
124
  /* @__PURE__ */ e("code", { children: "--token" }),
125
125
  ") · operation ",
126
- /* @__PURE__ */ e("code", { children: a.operation })
126
+ /* @__PURE__ */ e("code", { children: t.operation })
127
127
  ] }) : h === "python" ? /* @__PURE__ */ i(u, { children: [
128
128
  /* @__PURE__ */ e("code", { children: "pip install w6w" }),
129
129
  " · set ",
@@ -132,7 +132,7 @@ function M({
132
132
  /* @__PURE__ */ e("code", { children: "W6W_TOKEN" }),
133
133
  " ",
134
134
  "· operation ",
135
- /* @__PURE__ */ e("code", { children: a.operation })
135
+ /* @__PURE__ */ e("code", { children: t.operation })
136
136
  ] }) : /* @__PURE__ */ i(u, { children: [
137
137
  "No client library — any HTTP client will do. Set ",
138
138
  /* @__PURE__ */ e("code", { children: "W6W_BASE_URL" }),
@@ -143,39 +143,43 @@ function M({
143
143
  ] });
144
144
  }
145
145
  function I({
146
- resource: o,
146
+ resource: d,
147
147
  label: n = "Call from code",
148
148
  triggers: r,
149
- initialTab: s
149
+ initialTab: m
150
150
  }) {
151
- const [m, c] = N(!1);
151
+ const [s, c] = N(!1);
152
152
  return /* @__PURE__ */ i(u, { children: [
153
153
  /* @__PURE__ */ e(S, { icon: "code", label: n, onClick: () => c(!0) }),
154
- m && /* @__PURE__ */ e(_, { title: "Call from code", size: "wide", onClose: () => c(!1), children: /* @__PURE__ */ e(M, { resource: o, triggers: r, initialTab: s }) })
154
+ s && /* @__PURE__ */ e(_, { title: "Call from code", size: "wide", onClose: () => c(!1), children: /* @__PURE__ */ e(M, { resource: d, triggers: r, initialTab: m }) })
155
155
  ] });
156
156
  }
157
157
  function K({
158
- title: o,
158
+ title: d,
159
159
  message: n,
160
- onConfirm: r,
160
+ children: r,
161
+ onConfirm: m,
161
162
  onClose: s,
162
- confirmLabel: m = "Confirm",
163
- cancelLabel: c = "Cancel",
164
- destructive: p = !0
163
+ confirmLabel: c = "Confirm",
164
+ cancelLabel: p = "Cancel",
165
+ destructive: a = !0
165
166
  }) {
166
- return /* @__PURE__ */ i(R, { title: o, onClose: s, children: [
167
- /* @__PURE__ */ e("div", { className: "modal-body", children: /* @__PURE__ */ e("p", { className: "muted small", children: n }) }),
167
+ return /* @__PURE__ */ i(R, { title: d, onClose: s, children: [
168
+ /* @__PURE__ */ i("div", { className: "modal-body", children: [
169
+ /* @__PURE__ */ e("p", { className: "muted small", children: n }),
170
+ r
171
+ ] }),
168
172
  /* @__PURE__ */ i("div", { className: "modal-actions", children: [
169
- /* @__PURE__ */ e("button", { type: "button", className: "btn ghost", onClick: s, children: c }),
170
- /* @__PURE__ */ e("button", { type: "button", className: p ? "btn danger" : "btn", onClick: r, children: m })
173
+ /* @__PURE__ */ e("button", { type: "button", className: "btn ghost", onClick: s, children: p }),
174
+ /* @__PURE__ */ e("button", { type: "button", className: a ? "btn danger" : "btn", onClick: m, children: c })
171
175
  ] })
172
176
  ] });
173
177
  }
174
178
  export {
175
- I as C,
179
+ K as C,
176
180
  R as M,
177
- K as a,
181
+ I as a,
178
182
  M as b,
179
183
  F as s
180
184
  };
181
- //# sourceMappingURL=ConfirmModal-RLbZT5_k.js.map
185
+ //# sourceMappingURL=ConfirmModal-BE-SdX-O.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmModal-RLbZT5_k.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}\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}: 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\" : \"\"}`}\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 { Modal } from \"./Modal.tsx\";\n\ninterface ConfirmModalProps {\n title: string;\n message: string;\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 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 </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","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
+ {"version":3,"file":"ConfirmModal-BE-SdX-O.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}\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}: 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\" : \"\"}`}\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","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-BE-SdX-O.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-D6CQLpa_.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-D6CQLpa_.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-BE-SdX-O.js";
6
+ import { u as K, a as O } from "./spec-import-CW6R_Wk1.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-YauVdolr.js.map