@skopon-cool/form-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +82 -0
  2. package/dist/adapter/a2uiAdapter.d.ts +21 -0
  3. package/dist/adapter/a2uiAdapter.d.ts.map +1 -0
  4. package/dist/adapter/extractSurfaceValues.d.ts +8 -0
  5. package/dist/adapter/extractSurfaceValues.d.ts.map +1 -0
  6. package/dist/adapter/formFileAccept.d.ts +17 -0
  7. package/dist/adapter/formFileAccept.d.ts.map +1 -0
  8. package/dist/adapter/formFilePlaceholderIcon.d.ts +5 -0
  9. package/dist/adapter/formFilePlaceholderIcon.d.ts.map +1 -0
  10. package/dist/adapter/formMedia.d.ts +7 -0
  11. package/dist/adapter/formMedia.d.ts.map +1 -0
  12. package/dist/adapter/formSchema.d.ts +6 -0
  13. package/dist/adapter/formSchema.d.ts.map +1 -0
  14. package/dist/adapter/id.d.ts +4 -0
  15. package/dist/adapter/id.d.ts.map +1 -0
  16. package/dist/adapter/resolveSurface.d.ts +6 -0
  17. package/dist/adapter/resolveSurface.d.ts.map +1 -0
  18. package/dist/catalog/a2uiCustomCatalog.d.ts +10 -0
  19. package/dist/catalog/a2uiCustomCatalog.d.ts.map +1 -0
  20. package/dist/catalog/a2uiPreviewContext.d.ts +11 -0
  21. package/dist/catalog/a2uiPreviewContext.d.ts.map +1 -0
  22. package/dist/catalog/useSkoponBoundField.d.ts +10 -0
  23. package/dist/catalog/useSkoponBoundField.d.ts.map +1 -0
  24. package/dist/client/formClient.d.ts +22 -0
  25. package/dist/client/formClient.d.ts.map +1 -0
  26. package/dist/components/AskUserFormCard.d.ts +13 -0
  27. package/dist/components/AskUserFormCard.d.ts.map +1 -0
  28. package/dist/components/CurlSubmitBlock.d.ts +10 -0
  29. package/dist/components/CurlSubmitBlock.d.ts.map +1 -0
  30. package/dist/components/SkoponA2uiStreamRenderer.d.ts +11 -0
  31. package/dist/components/SkoponA2uiStreamRenderer.d.ts.map +1 -0
  32. package/dist/components/SkoponFormRenderer.d.ts +16 -0
  33. package/dist/components/SkoponFormRenderer.d.ts.map +1 -0
  34. package/dist/form-sdk.css +1 -0
  35. package/dist/icons/FilePlaceholderIcon.d.ts +10 -0
  36. package/dist/icons/FilePlaceholderIcon.d.ts.map +1 -0
  37. package/dist/index.d.ts +20 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +1332 -0
  40. package/dist/submit/buildCurlStatement.d.ts +2 -0
  41. package/dist/submit/buildCurlStatement.d.ts.map +1 -0
  42. package/dist/submit/intersectPayloadWithForm.d.ts +17 -0
  43. package/dist/submit/intersectPayloadWithForm.d.ts.map +1 -0
  44. package/dist/submit/submitFormJson.d.ts +12 -0
  45. package/dist/submit/submitFormJson.d.ts.map +1 -0
  46. package/dist/types/index.d.ts +76 -0
  47. package/dist/types/index.d.ts.map +1 -0
  48. package/package.json +53 -0
  49. package/src/adapter/a2uiAdapter.test.ts +150 -0
  50. package/src/adapter/a2uiAdapter.ts +490 -0
  51. package/src/adapter/extractSurfaceValues.ts +25 -0
  52. package/src/adapter/formFileAccept.ts +198 -0
  53. package/src/adapter/formFilePlaceholderIcon.ts +33 -0
  54. package/src/adapter/formMedia.ts +50 -0
  55. package/src/adapter/formSchema.ts +139 -0
  56. package/src/adapter/id.ts +24 -0
  57. package/src/adapter/resolveSurface.ts +66 -0
  58. package/src/catalog/a2uiCustomCatalog.tsx +548 -0
  59. package/src/catalog/a2uiPreviewContext.tsx +26 -0
  60. package/src/catalog/useSkoponBoundField.ts +57 -0
  61. package/src/client/formClient.ts +72 -0
  62. package/src/components/AskUserFormCard.tsx +155 -0
  63. package/src/components/CurlSubmitBlock.tsx +60 -0
  64. package/src/components/SkoponA2uiStreamRenderer.tsx +70 -0
  65. package/src/components/SkoponFormRenderer.tsx +100 -0
  66. package/src/icons/FilePlaceholderIcon.tsx +40 -0
  67. package/src/index.ts +67 -0
  68. package/src/styles/a2ui-preview.css +345 -0
  69. package/src/styles/index.css +190 -0
  70. package/src/submit/buildCurlStatement.ts +13 -0
  71. package/src/submit/intersectPayloadWithForm.ts +54 -0
  72. package/src/submit/submit.test.ts +63 -0
  73. package/src/submit/submitFormJson.ts +50 -0
  74. package/src/types/index.ts +139 -0
package/dist/index.js ADDED
@@ -0,0 +1,1332 @@
1
+ import { jsx as u, jsxs as b, Fragment as ae } from "react/jsx-runtime";
2
+ import { createContext as Fe, useContext as we, useCallback as N, useSyncExternalStore as Oe, forwardRef as De, useEffect as C, useRef as M, useMemo as k, useImperativeHandle as je, useState as w } from "react";
3
+ import { Catalog as Ve, MessageProcessor as le } from "@a2ui/web_core/v0_9";
4
+ import { injectBasicCatalogStyles as ce } from "@a2ui/web_core/v0_9/basic_catalog";
5
+ import { createBinderlessComponentImplementation as S, basicCatalog as O, A2uiSurface as se } from "@a2ui/react/v0_9";
6
+ import { injectStyles as ue } from "@a2ui/react/styles";
7
+ import { z as m } from "zod";
8
+ import { Typography as J, Select as H, Checkbox as ze, Radio as Le, Switch as Re, TimePicker as Ue, DatePicker as Be, Upload as ee, Tooltip as Y, Tag as te, Button as pe, Spin as Ne } from "antd";
9
+ import ne from "dayjs";
10
+ import { FileTextOutlined as $e, FileExcelOutlined as He, FileOutlined as me, PictureOutlined as Ye, SoundOutlined as Ge, VideoCameraOutlined as Xe } from "@ant-design/icons";
11
+ const bn = "v0.9", Ke = [
12
+ "huge",
13
+ "large",
14
+ "medium",
15
+ "small",
16
+ "icon"
17
+ ];
18
+ function G(e) {
19
+ return e === "image" || e === "video" || e === "audio";
20
+ }
21
+ function qe(e) {
22
+ return e === "heading" || e === "paragraph";
23
+ }
24
+ function re(e) {
25
+ return !qe(e) && !G(e);
26
+ }
27
+ function Je() {
28
+ if (typeof crypto < "u" && typeof crypto.randomUUID == "function")
29
+ return crypto.randomUUID();
30
+ if (typeof crypto < "u" && typeof crypto.getRandomValues == "function") {
31
+ const e = new Uint8Array(16);
32
+ crypto.getRandomValues(e), e[6] = e[6] & 15 | 64, e[8] = e[8] & 63 | 128;
33
+ const t = Array.from(e, (n) => n.toString(16).padStart(2, "0")).join("");
34
+ return `${t.slice(0, 8)}-${t.slice(8, 12)}-${t.slice(12, 16)}-${t.slice(16, 20)}-${t.slice(20)}`;
35
+ }
36
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (e) => {
37
+ const t = Math.random() * 16 | 0;
38
+ return (e === "x" ? t : t & 3 | 8).toString(16);
39
+ });
40
+ }
41
+ function P(e) {
42
+ const t = Je().replace(/-/g, "").slice(0, 8);
43
+ return `${e}${t}`;
44
+ }
45
+ function I(e) {
46
+ return typeof e == "string" && Ke.includes(e) ? e : "medium";
47
+ }
48
+ function We(e, t) {
49
+ var o;
50
+ const n = Math.max(1, t);
51
+ let r = [];
52
+ return Array.isArray(e.mediaUrls) ? r = e.mediaUrls.map((a) => String(a).trim()) : (o = e.mediaUrl) != null && o.trim() && (r = [e.mediaUrl.trim()]), r.length === 0 ? [""] : r.slice(0, n);
53
+ }
54
+ function Ze(e) {
55
+ var t;
56
+ return Array.isArray(e.mediaUrls) ? e.mediaUrls.map((n) => n.trim()).filter(Boolean) : (t = e.mediaUrl) != null && t.trim() ? [e.mediaUrl.trim()] : [];
57
+ }
58
+ function Qe(e) {
59
+ return `form-media-size-${I(e)}`;
60
+ }
61
+ function et(e) {
62
+ return `form-media-preview form-media-list ${Qe(e)}`;
63
+ }
64
+ const de = [
65
+ { value: "image/*", label: "图片" },
66
+ { value: "video/*", label: "视频" },
67
+ { value: "audio/*", label: "音频" },
68
+ { value: "application/pdf", label: "PDF" },
69
+ { value: "office/word", label: "Word" },
70
+ { value: "office/excel", label: "Excel" },
71
+ { value: "office/ppt", label: "PPT" },
72
+ { value: "text/plain", label: "纯文本" },
73
+ { value: "application/zip", label: "ZIP 压缩包" },
74
+ { value: "application/x-rar-compressed", label: "RAR 压缩包" }
75
+ ], tt = {
76
+ "image/*": ["image/*"],
77
+ "video/*": ["video/*"],
78
+ "audio/*": ["audio/*"],
79
+ "application/pdf": ["application/pdf"],
80
+ "office/word": [
81
+ "application/msword",
82
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
83
+ ],
84
+ "office/excel": [
85
+ "application/vnd.ms-excel",
86
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
87
+ ],
88
+ "office/ppt": [
89
+ "application/vnd.ms-powerpoint",
90
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation"
91
+ ],
92
+ "text/plain": ["text/plain"],
93
+ "application/zip": ["application/zip"],
94
+ "application/x-rar-compressed": ["application/x-rar-compressed"]
95
+ }, nt = {
96
+ "image/*": [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"],
97
+ "video/*": [".mp4", ".mov", ".avi", ".webm"],
98
+ "audio/*": [".mp3", ".wav", ".ogg", ".m4a"],
99
+ "application/pdf": [".pdf"],
100
+ "office/word": [".doc", ".docx"],
101
+ "office/excel": [".xls", ".xlsx"],
102
+ "office/ppt": [".ppt", ".pptx"],
103
+ "text/plain": [".txt"],
104
+ "application/zip": [".zip", ".7z"],
105
+ "application/x-rar-compressed": [".rar"]
106
+ }, rt = {
107
+ "application/msword": "office/word",
108
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "office/word",
109
+ "application/vnd.ms-excel": "office/excel",
110
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "office/excel",
111
+ "application/vnd.ms-powerpoint": "office/ppt",
112
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation": "office/ppt"
113
+ }, fe = [
114
+ { value: ".jpg", label: ".jpg" },
115
+ { value: ".jpeg", label: ".jpeg" },
116
+ { value: ".png", label: ".png" },
117
+ { value: ".gif", label: ".gif" },
118
+ { value: ".webp", label: ".webp" },
119
+ { value: ".svg", label: ".svg" },
120
+ { value: ".mp4", label: ".mp4" },
121
+ { value: ".mov", label: ".mov" },
122
+ { value: ".avi", label: ".avi" },
123
+ { value: ".webm", label: ".webm" },
124
+ { value: ".mp3", label: ".mp3" },
125
+ { value: ".wav", label: ".wav" },
126
+ { value: ".ogg", label: ".ogg" },
127
+ { value: ".m4a", label: ".m4a" },
128
+ { value: ".pdf", label: ".pdf" },
129
+ { value: ".doc", label: ".doc" },
130
+ { value: ".docx", label: ".docx" },
131
+ { value: ".xls", label: ".xls" },
132
+ { value: ".xlsx", label: ".xlsx" },
133
+ { value: ".ppt", label: ".ppt" },
134
+ { value: ".pptx", label: ".pptx" },
135
+ { value: ".txt", label: ".txt" },
136
+ { value: ".zip", label: ".zip" },
137
+ { value: ".rar", label: ".rar" },
138
+ { value: ".7z", label: ".7z" }
139
+ ], ot = Object.fromEntries(
140
+ de.map((e) => [e.value, e.label])
141
+ ), it = Object.fromEntries(
142
+ fe.map((e) => [e.value, e.label])
143
+ ), at = new Set(de.map((e) => e.value));
144
+ function lt(e) {
145
+ const t = e.trim();
146
+ return t ? at.has(t) ? t : rt[t] ?? null : null;
147
+ }
148
+ function ct(e) {
149
+ return Array.isArray(e) ? e.map((t) => {
150
+ const n = t.trim().toLowerCase();
151
+ return n ? n.startsWith(".") ? n : `.${n}` : "";
152
+ }).filter(Boolean) : [];
153
+ }
154
+ function L(e) {
155
+ if (!Array.isArray(e)) return [];
156
+ const t = [], n = /* @__PURE__ */ new Set();
157
+ for (const r of e) {
158
+ const o = lt(r);
159
+ o && !n.has(o) && (n.add(o), t.push(o));
160
+ }
161
+ return t;
162
+ }
163
+ function st(e) {
164
+ const t = L(e), n = [];
165
+ for (const r of t)
166
+ n.push(...tt[r] ?? [r]);
167
+ return n;
168
+ }
169
+ function ut(e) {
170
+ const t = L(e);
171
+ if (t.length === 0) return [];
172
+ const n = /* @__PURE__ */ new Set();
173
+ for (const r of t)
174
+ for (const o of nt[r] ?? [])
175
+ n.add(o);
176
+ return fe.filter((r) => n.has(r.value));
177
+ }
178
+ function W(e, t) {
179
+ const n = new Set(
180
+ ut(e).map((r) => r.value)
181
+ );
182
+ return ct(t).filter((r) => n.has(r));
183
+ }
184
+ function pt(e, t) {
185
+ const n = st(e), r = W(e, t), o = [...n, ...r];
186
+ return o.length > 0 ? o.join(",") : void 0;
187
+ }
188
+ function mt(e, t) {
189
+ const n = L(e), r = W(
190
+ n,
191
+ t
192
+ ), o = [
193
+ ...n.map((a) => ot[a] ?? a),
194
+ ...r.map((a) => it[a] ?? a)
195
+ ];
196
+ return o.length === 0 ? null : o.join("、");
197
+ }
198
+ const dt = [
199
+ "video",
200
+ "audio",
201
+ "image",
202
+ "file",
203
+ "spreadsheet",
204
+ "document"
205
+ ], ft = new Set(dt);
206
+ function ht(e) {
207
+ return e && ft.has(e) ? e : "file";
208
+ }
209
+ const vt = 10;
210
+ function oe(e, t = 1) {
211
+ const n = typeof e == "number" ? e : Number(e);
212
+ return Number.isFinite(n) ? Math.max(0, Math.floor(n)) : t;
213
+ }
214
+ function yt(e, t) {
215
+ if (t !== void 0)
216
+ return e === "toggle" ? t === !0 : e === "multiselect" || e === "checkbox" ? Array.isArray(t) ? t.map(String) : typeof t == "string" && t ? [t] : [] : typeof t == "boolean" ? t ? "true" : "false" : Array.isArray(t) ? t.map(String) : String(t);
217
+ }
218
+ function bt(e) {
219
+ var r, o;
220
+ const t = L(e.fileAcceptTypes), n = e.type;
221
+ return {
222
+ id: ((r = e.id) == null ? void 0 : r.trim()) || P("block-"),
223
+ type: n,
224
+ name: ((o = e.name) == null ? void 0 : o.trim()) || void 0,
225
+ label: e.label ?? "",
226
+ placeholder: e.placeholder ?? "",
227
+ help: e.help ?? "",
228
+ required: e.required === !0,
229
+ mediaUrls: G(n) ? We(e, vt) : void 0,
230
+ mediaSize: G(n) ? I(e.mediaSize) : void 0,
231
+ fileAcceptTypes: t,
232
+ fileAcceptExtensions: W(
233
+ t,
234
+ e.fileAcceptExtensions
235
+ ),
236
+ filePlaceholderIcon: ht(e.filePlaceholderIcon),
237
+ fileMinCount: n === "file" ? oe(e.fileMinCount, 1) : void 0,
238
+ fileMaxCount: n === "file" ? oe(e.fileMaxCount, 1) : void 0,
239
+ defaultValue: yt(n, e.defaultValue),
240
+ options: Array.isArray(e.options) ? e.options.map((a, i) => {
241
+ var l, c;
242
+ return {
243
+ value: ((l = a.value) == null ? void 0 : l.trim()) || `option_${i + 1}`,
244
+ label: ((c = a.label) == null ? void 0 : c.trim()) || `选项 ${i + 1}`
245
+ };
246
+ }) : void 0
247
+ };
248
+ }
249
+ function D(e) {
250
+ return {
251
+ title: e.title ?? "",
252
+ description: e.description ?? "",
253
+ blocks: e.blocks,
254
+ jsonSchema: e.jsonSchema ?? {}
255
+ };
256
+ }
257
+ function he(e) {
258
+ if (!e || !Array.isArray(e.blocks))
259
+ return D({ title: "", description: "", blocks: [], jsonSchema: {} });
260
+ const t = e.blocks.map(bt);
261
+ return D({
262
+ title: typeof e.title == "string" ? e.title : "",
263
+ description: typeof e.description == "string" ? e.description : "",
264
+ blocks: t,
265
+ jsonSchema: {}
266
+ });
267
+ }
268
+ const j = "root", X = "__title__", K = "__desc__", ve = "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$";
269
+ function gt(e) {
270
+ return `/${e}`;
271
+ }
272
+ function xt(e) {
273
+ return e && typeof e == "object" && "path" in e ? String(e.path ?? "").replace(/^\//, "") : "";
274
+ }
275
+ function y(e) {
276
+ if (typeof e == "string") return e;
277
+ }
278
+ function St(e) {
279
+ const t = e.id || P("a2-"), n = e.type === "video" ? "video" : e.type === "audio" ? "audio" : "image";
280
+ return {
281
+ id: t,
282
+ component: "SkoponMedia",
283
+ mediaType: n,
284
+ urls: Ze(e),
285
+ mediaSize: I(e.mediaSize),
286
+ label: e.label ?? "",
287
+ help: e.help ?? "",
288
+ placeholder: e.placeholder ?? ""
289
+ };
290
+ }
291
+ function At(e) {
292
+ if (Array.isArray(e.urls))
293
+ return e.urls.map((n) => String(n).trim()).filter(Boolean);
294
+ const t = y(e.url);
295
+ return t != null && t.trim() ? [t.trim()] : [];
296
+ }
297
+ function F(e, t, n) {
298
+ const r = typeof e.id == "string" ? e.id : P("block-"), o = At(e), a = y(e.label) ?? y(e.description) ?? n, i = y(e.help), l = y(e.placeholder), c = I(e.mediaSize);
299
+ return {
300
+ id: r,
301
+ type: t,
302
+ label: a,
303
+ ...i ? { help: i } : {},
304
+ ...l ? { placeholder: l } : {},
305
+ mediaSize: c,
306
+ mediaUrls: o.length > 0 ? o : [""]
307
+ };
308
+ }
309
+ function kt(e) {
310
+ switch (e.type) {
311
+ case "toggle":
312
+ return typeof e.defaultValue == "boolean" ? e.defaultValue : !1;
313
+ case "multiselect":
314
+ case "checkbox":
315
+ case "select":
316
+ case "radio":
317
+ return Array.isArray(e.defaultValue) ? e.defaultValue : typeof e.defaultValue == "string" && e.defaultValue ? [e.defaultValue] : [];
318
+ default:
319
+ return typeof e.defaultValue == "string" ? e.defaultValue : "";
320
+ }
321
+ }
322
+ function Tt(e) {
323
+ var l;
324
+ const t = e.id || P("a2-"), n = e.label ?? "", r = ((l = e.name) == null ? void 0 : l.trim()) || "", o = r ? gt(r) : void 0, a = (e.options ?? []).map((c) => ({ label: c.label, value: c.value })), i = (c) => r ? { node: c, dataKey: r, dataValue: kt(e) } : { node: c };
325
+ switch (e.type) {
326
+ case "heading":
327
+ return { node: { id: t, component: "Text", text: n, variant: "h3" } };
328
+ case "paragraph":
329
+ return { node: { id: t, component: "Text", text: n, variant: "body" } };
330
+ case "text":
331
+ case "tel":
332
+ case "url":
333
+ return i({ id: t, component: "TextField", label: n, variant: "shortText", value: { path: o } });
334
+ case "email":
335
+ return i({
336
+ id: t,
337
+ component: "TextField",
338
+ label: n,
339
+ variant: "shortText",
340
+ validationRegexp: ve,
341
+ value: { path: o }
342
+ });
343
+ case "textarea":
344
+ return i({ id: t, component: "TextField", label: n, variant: "longText", value: { path: o } });
345
+ case "number":
346
+ return i({ id: t, component: "TextField", label: n, variant: "number", value: { path: o } });
347
+ case "select":
348
+ return i({
349
+ id: t,
350
+ component: "SkoponSelect",
351
+ label: n,
352
+ mode: "single",
353
+ placeholder: e.placeholder ?? "",
354
+ options: a,
355
+ value: { path: o }
356
+ });
357
+ case "radio":
358
+ return i({
359
+ id: t,
360
+ component: "ChoicePicker",
361
+ label: n,
362
+ variant: "mutuallyExclusive",
363
+ skoponPickerType: "radio",
364
+ options: a,
365
+ value: { path: o }
366
+ });
367
+ case "multiselect":
368
+ return i({
369
+ id: t,
370
+ component: "SkoponSelect",
371
+ label: n,
372
+ mode: "multiple",
373
+ placeholder: e.placeholder ?? "",
374
+ options: a,
375
+ value: { path: o }
376
+ });
377
+ case "checkbox":
378
+ return i({
379
+ id: t,
380
+ component: "ChoicePicker",
381
+ label: n,
382
+ variant: "multipleSelection",
383
+ skoponPickerType: "checkbox",
384
+ options: a,
385
+ value: { path: o }
386
+ });
387
+ case "toggle":
388
+ return i({ id: t, component: "CheckBox", label: n, value: { path: o } });
389
+ case "datetime":
390
+ return i({
391
+ id: t,
392
+ component: "DateTimeInput",
393
+ label: n,
394
+ enableDate: !0,
395
+ enableTime: !0,
396
+ placeholder: e.placeholder ?? "",
397
+ value: { path: o }
398
+ });
399
+ case "time":
400
+ return i({
401
+ id: t,
402
+ component: "DateTimeInput",
403
+ label: n,
404
+ enableTime: !0,
405
+ placeholder: e.placeholder ?? "",
406
+ value: { path: o }
407
+ });
408
+ case "image":
409
+ case "video":
410
+ case "audio":
411
+ return { node: St(e) };
412
+ case "file":
413
+ return i({
414
+ id: t,
415
+ component: "FileUpload",
416
+ label: n,
417
+ accept: (e.fileAcceptExtensions ?? []).join(","),
418
+ fileAcceptTypes: e.fileAcceptTypes ?? [],
419
+ filePlaceholderIcon: e.filePlaceholderIcon ?? "document",
420
+ minCount: e.fileMinCount ?? 0,
421
+ maxCount: e.fileMaxCount ?? 1,
422
+ value: { path: o }
423
+ });
424
+ default:
425
+ return { node: null };
426
+ }
427
+ }
428
+ function q(e) {
429
+ if (!e || !Array.isArray(e.components) || e.components.length === 0) return !0;
430
+ const t = e.components.find((r) => r.id === j);
431
+ if (!t) return e.components.length === 0;
432
+ const n = t.children;
433
+ return !Array.isArray(n) || n.length === 0;
434
+ }
435
+ function ye(e, t) {
436
+ const n = [], r = [], o = {}, a = (t == null ? void 0 : t.includeHeader) !== !1, i = (e.title ?? "").trim(), l = (e.description ?? "").trim();
437
+ a && i && (n.push({ id: X, component: "Text", text: i, variant: "h2" }), r.push(X)), a && l && (n.push({ id: K, component: "Text", text: l, variant: "body" }), r.push(K));
438
+ for (const p of e.blocks ?? []) {
439
+ const { node: d, dataKey: f, dataValue: h } = Tt(p);
440
+ d && (n.push(d), r.push(d.id), f && (o[f] = h));
441
+ }
442
+ n.unshift({ id: j, component: "Column", children: r });
443
+ const c = { root: j, components: n, dataModel: o }, s = t == null ? void 0 : t.styleId;
444
+ return s !== void 0 && (c.surfaceProperties = { styleId: s ?? null }), c;
445
+ }
446
+ function Ct(e) {
447
+ const t = /* @__PURE__ */ new Map();
448
+ for (const n of e.components ?? [])
449
+ n && typeof n.id == "string" && t.set(n.id, n);
450
+ return t;
451
+ }
452
+ function $(e) {
453
+ const t = e.options;
454
+ return Array.isArray(t) ? t.map((n) => {
455
+ if (!n || typeof n != "object") return null;
456
+ const r = n;
457
+ return {
458
+ value: String(r.value ?? r.label ?? ""),
459
+ label: String(r.label ?? r.value ?? "")
460
+ };
461
+ }).filter((n) => !!n) : [];
462
+ }
463
+ function Mt(e) {
464
+ const t = typeof e.id == "string" ? e.id : P("block-"), n = String(e.component ?? ""), r = y(e.label) ?? y(e.text) ?? "", o = xt(e.value), a = (i) => ({ id: t, type: i, label: r });
465
+ switch (n) {
466
+ case "Text": {
467
+ const i = String(e.variant ?? "body"), l = /^h[1-6]$/i.test(i) || i === "title" || i === "subtitle";
468
+ return { id: t, type: l ? "heading" : "paragraph", label: r };
469
+ }
470
+ case "TextField": {
471
+ const i = String(e.variant ?? "shortText");
472
+ let l = "text";
473
+ return i === "longText" ? l = "textarea" : i === "number" ? l = "number" : y(e.validationRegexp) === ve && (l = "email"), { ...a(l), name: o };
474
+ }
475
+ case "CheckBox":
476
+ return { ...a("toggle"), name: o };
477
+ case "SkoponSelect": {
478
+ const l = String(e.mode ?? "single") === "multiple" ? "multiselect" : "select", c = {
479
+ ...a(l),
480
+ name: o,
481
+ options: $(e)
482
+ }, s = y(e.placeholder);
483
+ return s && (c.placeholder = s), c;
484
+ }
485
+ case "ChoicePicker": {
486
+ const i = y(e.skoponPickerType);
487
+ if (i === "select" || i === "multiselect" || i === "radio" || i === "checkbox") {
488
+ const s = {
489
+ ...a(i),
490
+ name: o,
491
+ options: $(e)
492
+ }, p = y(e.placeholder);
493
+ return p && (s.placeholder = p), s;
494
+ }
495
+ const c = String(e.variant ?? "mutuallyExclusive") === "multipleSelection" ? "checkbox" : "radio";
496
+ return { ...a(c), name: o, options: $(e) };
497
+ }
498
+ case "DateTimeInput": {
499
+ const i = e.enableDate === !0, l = e.enableTime === !0, s = { ...a(!i && l ? "time" : "datetime"), name: o }, p = y(e.placeholder);
500
+ return p && (s.placeholder = p), s;
501
+ }
502
+ case "SkoponMedia": {
503
+ const i = String(e.mediaType ?? "image");
504
+ return F(e, i === "video" ? "video" : i === "audio" ? "audio" : "image", r);
505
+ }
506
+ case "Image":
507
+ return F(e, "image", r);
508
+ case "Video":
509
+ return F(e, "video", r);
510
+ case "AudioPlayer":
511
+ return F(e, "audio", r);
512
+ case "FileUpload": {
513
+ const i = y(e.accept) ?? "", l = { ...a("file"), name: o };
514
+ return i && (l.fileAcceptExtensions = i.split(",").map((c) => c.trim()).filter(Boolean)), Array.isArray(e.fileAcceptTypes) && (l.fileAcceptTypes = e.fileAcceptTypes.map(String)), typeof e.filePlaceholderIcon == "string" && (l.filePlaceholderIcon = e.filePlaceholderIcon), typeof e.minCount == "number" && (l.fileMinCount = e.minCount), typeof e.maxCount == "number" && (l.fileMaxCount = e.maxCount), l;
515
+ }
516
+ default:
517
+ return null;
518
+ }
519
+ }
520
+ function be(e, t, n, r) {
521
+ if (n.has(e)) return;
522
+ n.add(e);
523
+ const o = t.get(e);
524
+ if (!o) return;
525
+ const a = String(o.component ?? "");
526
+ if ((a === "Column" || a === "Row") && Array.isArray(o.children)) {
527
+ for (const i of o.children)
528
+ typeof i == "string" && be(i, t, n, r);
529
+ return;
530
+ }
531
+ r.push(o);
532
+ }
533
+ function Pt(e) {
534
+ if (!e || !Array.isArray(e.components))
535
+ return D({ title: "", description: "", blocks: [], jsonSchema: {} });
536
+ const t = Ct(e), n = [];
537
+ be(e.root ?? j, t, /* @__PURE__ */ new Set(), n);
538
+ let r = "", o = "";
539
+ const a = [];
540
+ for (const i of n) {
541
+ if (i.id === X) {
542
+ r = y(i.text) ?? r;
543
+ continue;
544
+ }
545
+ if (i.id === K) {
546
+ o = y(i.text) ?? o;
547
+ continue;
548
+ }
549
+ const l = Mt(i);
550
+ l && a.push(l);
551
+ }
552
+ return D({ title: r, description: o, blocks: a, jsonSchema: {} });
553
+ }
554
+ function It(e, t) {
555
+ const { surfaceId: n, catalogId: r } = t, o = [
556
+ { version: "v0.9", createSurface: { surfaceId: n, catalogId: r } },
557
+ {
558
+ version: "v0.9",
559
+ updateComponents: { surfaceId: n, components: e.components }
560
+ }
561
+ ];
562
+ return e.dataModel && Object.keys(e.dataModel).length > 0 && o.push({
563
+ version: "v0.9",
564
+ updateDataModel: { surfaceId: n, path: "/", value: e.dataModel }
565
+ }), o;
566
+ }
567
+ function ge(e) {
568
+ return !!e && typeof e == "object" && !Array.isArray(e) && Array.isArray(e.components);
569
+ }
570
+ function Et(e, t) {
571
+ if (!e || typeof e != "object") return null;
572
+ const n = e, r = ge(n.a2ui) ? n.a2ui : void 0;
573
+ if (r && !q(r)) return r;
574
+ const o = Array.isArray(n.blocks) ? n.blocks : [];
575
+ if (o.length === 0) return null;
576
+ const a = he({
577
+ title: typeof n.title == "string" ? n.title : "",
578
+ description: typeof n.description == "string" ? n.description : "",
579
+ blocks: o
580
+ }), i = ye(a, t);
581
+ return q(i) ? null : i;
582
+ }
583
+ function _t(e, t, n) {
584
+ return ye(
585
+ {
586
+ title: e.title,
587
+ description: e.description,
588
+ blocks: t
589
+ },
590
+ n
591
+ );
592
+ }
593
+ function Ft(e) {
594
+ if (!e || typeof e != "object" || Array.isArray(e))
595
+ return;
596
+ const t = e;
597
+ return !(Array.isArray(t.blocks) && t.blocks.length > 0) && ge(t.a2ui) ? Pt(t.a2ui) : he({
598
+ title: typeof t.title == "string" ? t.title : "",
599
+ description: typeof t.description == "string" ? t.description : "",
600
+ blocks: Array.isArray(t.blocks) ? t.blocks : []
601
+ });
602
+ }
603
+ function wt(e, t, n) {
604
+ const r = e.model.surfacesMap.get(t);
605
+ if (!r) return {};
606
+ const o = {};
607
+ for (const a of n) {
608
+ const i = a.trim();
609
+ i && (o[i] = r.dataModel.get(`/${i}`));
610
+ }
611
+ return o;
612
+ }
613
+ function Ot(e) {
614
+ return e.replace(/'/g, "'\\''");
615
+ }
616
+ function xe(e, t) {
617
+ const n = (t ?? "").trim() || "<callback_url>", r = JSON.stringify(e ?? {}, null, 2);
618
+ return [
619
+ `curl -X POST '${n}' \\`,
620
+ " -H 'Content-Type: application/json' \\",
621
+ ` -d '${Ot(r)}'`
622
+ ].join(`
623
+ `);
624
+ }
625
+ function Dt(e) {
626
+ return !e || typeof e != "object" || Array.isArray(e) ? [] : Object.keys(e);
627
+ }
628
+ function jt(e, t) {
629
+ const n = Dt(e), r = e ?? {}, o = (t == null ? void 0 : t.blocks) ?? [], a = new Set(
630
+ o.filter((c) => {
631
+ var s;
632
+ return re(c.type) && ((s = c.name) == null ? void 0 : s.trim());
633
+ }).map((c) => c.name.trim())
634
+ ), i = o.filter(
635
+ (c) => {
636
+ var s;
637
+ return re(c.type) && ((s = c.name) == null ? void 0 : s.trim()) && n.includes(c.name.trim());
638
+ }
639
+ ), l = {};
640
+ for (const c of n)
641
+ a.has(c) || (l[c] = r[c]);
642
+ return { matchedBlocks: i, remainderPayload: l };
643
+ }
644
+ async function Vt(e, t, n) {
645
+ const r = e.trim();
646
+ if (!r)
647
+ throw new Error("callback_url 为空");
648
+ const a = await ((n == null ? void 0 : n.fetch) ?? fetch)(r, {
649
+ method: "POST",
650
+ headers: {
651
+ "Content-Type": "application/json",
652
+ ...(n == null ? void 0 : n.headers) ?? {}
653
+ },
654
+ body: JSON.stringify(t ?? {})
655
+ });
656
+ let i;
657
+ if ((a.headers.get("content-type") ?? "").includes("application/json"))
658
+ try {
659
+ i = await a.json();
660
+ } catch {
661
+ i = void 0;
662
+ }
663
+ else
664
+ try {
665
+ i = await a.text();
666
+ } catch {
667
+ i = void 0;
668
+ }
669
+ return { ok: a.ok, status: a.status, body: i };
670
+ }
671
+ async function Se(e) {
672
+ await navigator.clipboard.writeText(e);
673
+ }
674
+ async function zt(e) {
675
+ const t = await e.json();
676
+ if (!e.ok || t.success === !1)
677
+ throw new Error(t.message || `请求失败 (${e.status})`);
678
+ return t.data;
679
+ }
680
+ function gn(e = {}) {
681
+ const t = (e.baseUrl ?? "/api/v1").replace(/\/$/, ""), n = e.detailPath ?? "/dev/form/detail", r = e.fetch ?? fetch;
682
+ async function o(a) {
683
+ var d;
684
+ const i = new URLSearchParams();
685
+ if (a.formId !== void 0)
686
+ i.set("form_id", String(a.formId));
687
+ else if (a.formUniqueId)
688
+ i.set("form_unique_id", a.formUniqueId);
689
+ else
690
+ throw new Error("form_id 或 form_unique_id 至少传一个");
691
+ const l = await ((d = e.getHeaders) == null ? void 0 : d.call(e)) ?? {}, c = await r(`${t}${n}?${i.toString()}`, {
692
+ method: "GET",
693
+ headers: l
694
+ }), s = await zt(c), p = Ft(s.form_definition);
695
+ return {
696
+ formUniqueId: s.form_unique_id,
697
+ formId: s.form_id,
698
+ disabled: s.disabled === 1,
699
+ formDefinition: p,
700
+ a2ui: Et(s.form_definition) ?? void 0
701
+ };
702
+ }
703
+ return { fetchDetail: o };
704
+ }
705
+ const Lt = {
706
+ video: Xe,
707
+ audio: Ge,
708
+ image: Ye,
709
+ file: me,
710
+ spreadsheet: He,
711
+ document: $e
712
+ };
713
+ function Rt({
714
+ type: e,
715
+ size: t = 40,
716
+ className: n
717
+ }) {
718
+ const r = Lt[e] ?? me;
719
+ return /* @__PURE__ */ u(
720
+ r,
721
+ {
722
+ className: n ?? "skopon-form-file-placeholder-icon",
723
+ style: { fontSize: t, color: "var(--color-primary, #1677ff)" },
724
+ "aria-hidden": !0
725
+ }
726
+ );
727
+ }
728
+ const Ae = Fe({ interactive: !0 });
729
+ function ke({
730
+ interactive: e,
731
+ children: t
732
+ }) {
733
+ return /* @__PURE__ */ u(Ae.Provider, { value: { interactive: e }, children: t });
734
+ }
735
+ function E() {
736
+ return we(Ae);
737
+ }
738
+ function Ut(e) {
739
+ return e && typeof e == "object" && "path" in e && String(e.path ?? "").trim() || null;
740
+ }
741
+ function _(e, t = "value") {
742
+ const r = e.componentModel.properties[t], o = Ut(r), a = N(
743
+ (s) => {
744
+ if (!o || r === void 0) return () => {
745
+ };
746
+ const p = e.dataContext.subscribeDynamicValue(r, () => s());
747
+ return () => p.unsubscribe();
748
+ },
749
+ [e, r, o]
750
+ ), i = N(() => {
751
+ if (!(!o || r === void 0))
752
+ return e.dataContext.resolveDynamicValue(r);
753
+ }, [e, r, o]), l = o ? Oe(a, i, i) : void 0, c = N(
754
+ (s) => {
755
+ !o || !r || typeof r != "object" || !("path" in r) || e.dataContext.set(String(r.path), s);
756
+ },
757
+ [e, r, o]
758
+ );
759
+ return { value: l, setValue: c, hasBinding: !!o };
760
+ }
761
+ function V(e) {
762
+ if (typeof e == "string") return e || void 0;
763
+ if (typeof e == "number") return String(e);
764
+ }
765
+ function z(e) {
766
+ return Array.isArray(e) ? e.map(String) : typeof e == "string" && e ? [e] : [];
767
+ }
768
+ const Te = "skopon-form-v0_9", Bt = /* @__PURE__ */ new Set([
769
+ "SkoponMedia",
770
+ "SkoponSelect",
771
+ "Image",
772
+ "Video",
773
+ "AudioPlayer",
774
+ "ChoicePicker",
775
+ "CheckBox",
776
+ "DateTimeInput",
777
+ "FileUpload"
778
+ ]);
779
+ function R(e) {
780
+ const t = [...O.components.values()].find((n) => n.name === e);
781
+ if (!t) throw new Error(`Missing basic catalog component: ${e}`);
782
+ return t.schema;
783
+ }
784
+ function v(e) {
785
+ return typeof e == "string" ? e : "";
786
+ }
787
+ function Ce(e) {
788
+ return Array.isArray(e) ? e.map((t) => {
789
+ if (!t || typeof t != "object") return null;
790
+ const n = t, r = String(n.value ?? n.label ?? ""), o = String(n.label ?? n.value ?? "");
791
+ return { value: r, label: o };
792
+ }).filter((t) => !!t) : [];
793
+ }
794
+ function U({
795
+ mediaType: e,
796
+ urls: t,
797
+ mediaSize: n,
798
+ label: r,
799
+ help: o,
800
+ placeholder: a
801
+ }) {
802
+ const i = r == null ? void 0 : r.trim(), l = o == null ? void 0 : o.trim(), c = et(n), s = (a == null ? void 0 : a.trim()) || (e === "image" ? "未设置图片 URL" : e === "video" ? "未设置视频 URL" : "未设置音频 URL");
803
+ return /* @__PURE__ */ b("div", { className: "form-block-preview", children: [
804
+ i ? /* @__PURE__ */ u("div", { className: "form-block-preview-label", children: i }) : null,
805
+ t.length === 0 ? /* @__PURE__ */ u("div", { className: "form-media-preview form-media-preview--empty", children: s }) : /* @__PURE__ */ u("div", { className: c, children: t.map((p, d) => e === "image" ? /* @__PURE__ */ u(
806
+ "img",
807
+ {
808
+ src: p,
809
+ alt: i || "图片",
810
+ className: "form-media-item"
811
+ },
812
+ `media-${d}`
813
+ ) : e === "video" ? /* @__PURE__ */ u(
814
+ "video",
815
+ {
816
+ src: p,
817
+ controls: !0,
818
+ className: "form-media-item"
819
+ },
820
+ `media-${d}`
821
+ ) : /* @__PURE__ */ u(
822
+ "audio",
823
+ {
824
+ src: p,
825
+ controls: !0,
826
+ className: "form-media-item form-media-item--audio"
827
+ },
828
+ `media-${d}`
829
+ )) }),
830
+ l ? /* @__PURE__ */ u(J.Text, { type: "secondary", className: "form-block-preview-help", children: l }) : null
831
+ ] });
832
+ }
833
+ function B(e, t) {
834
+ const n = Array.isArray(e.urls) ? e.urls.map((r) => String(r).trim()).filter(Boolean) : v(e.url).trim() ? [v(e.url).trim()] : [];
835
+ return {
836
+ mediaType: t,
837
+ urls: n,
838
+ mediaSize: I(e.mediaSize),
839
+ label: v(e.label) || v(e.description),
840
+ help: v(e.help),
841
+ placeholder: v(e.placeholder)
842
+ };
843
+ }
844
+ const Nt = {
845
+ name: "SkoponMedia",
846
+ schema: m.object({
847
+ mediaType: m.any().optional(),
848
+ urls: m.any().optional(),
849
+ mediaSize: m.any().optional(),
850
+ label: m.any().optional(),
851
+ help: m.any().optional(),
852
+ placeholder: m.any().optional()
853
+ }).passthrough()
854
+ }, $t = S(Nt, ({ context: e }) => {
855
+ const t = e.componentModel.properties, n = v(t.mediaType);
856
+ return /* @__PURE__ */ u(U, { ...B(t, n === "video" ? "video" : n === "audio" ? "audio" : "image") });
857
+ }), Ht = S(
858
+ { name: "Image", schema: R("Image") },
859
+ ({ context: e }) => /* @__PURE__ */ u(U, { ...B(e.componentModel.properties, "image") })
860
+ ), Yt = S(
861
+ { name: "Video", schema: R("Video") },
862
+ ({ context: e }) => /* @__PURE__ */ u(U, { ...B(e.componentModel.properties, "video") })
863
+ ), Gt = S(
864
+ { name: "AudioPlayer", schema: R("AudioPlayer") },
865
+ ({ context: e }) => /* @__PURE__ */ u(U, { ...B(e.componentModel.properties, "audio") })
866
+ ), Xt = {
867
+ name: "SkoponSelect",
868
+ schema: m.object({
869
+ label: m.any().optional(),
870
+ mode: m.any().optional(),
871
+ placeholder: m.any().optional(),
872
+ options: m.any().optional(),
873
+ value: m.any().optional()
874
+ }).passthrough()
875
+ };
876
+ function Kt({ context: e }) {
877
+ const { interactive: t } = E(), { value: n, setValue: r } = _(e), o = e.componentModel.properties, a = v(o.label), i = v(o.placeholder), l = Ce(o.options), c = v(o.mode) === "multiple";
878
+ return /* @__PURE__ */ b("div", { className: "form-block-preview", children: [
879
+ a ? /* @__PURE__ */ u("div", { className: "form-block-preview-label", children: a }) : null,
880
+ /* @__PURE__ */ u(
881
+ H,
882
+ {
883
+ mode: c ? "multiple" : void 0,
884
+ disabled: !t,
885
+ allowClear: !0,
886
+ className: "form-block-preview-control",
887
+ style: { width: "100%" },
888
+ placeholder: i || (c ? "请选择多项" : "请选择"),
889
+ options: l,
890
+ value: c ? z(n) : V(n),
891
+ onChange: (s) => r(c ? s ?? [] : s ?? "")
892
+ }
893
+ )
894
+ ] });
895
+ }
896
+ const qt = S(
897
+ Xt,
898
+ Kt
899
+ );
900
+ function Jt({ context: e }) {
901
+ const { interactive: t } = E(), { value: n, setValue: r } = _(e), o = e.componentModel.properties, a = v(o.label), i = v(o.variant) || "mutuallyExclusive", l = v(o.skoponPickerType), c = v(o.placeholder), s = Ce(o.options), d = l === "select" || l === "multiselect" || l === "radio" || l === "checkbox" ? l : i === "multipleSelection" ? "checkbox" : "radio";
902
+ return /* @__PURE__ */ b("div", { className: "form-block-preview", children: [
903
+ a ? /* @__PURE__ */ u("div", { className: "form-block-preview-label", children: a }) : null,
904
+ d === "select" ? /* @__PURE__ */ u(
905
+ H,
906
+ {
907
+ disabled: !t,
908
+ allowClear: !0,
909
+ className: "form-block-preview-control",
910
+ style: { width: "100%" },
911
+ placeholder: c || "请选择",
912
+ options: s,
913
+ value: V(n),
914
+ onChange: (f) => r(f ?? "")
915
+ }
916
+ ) : d === "multiselect" ? /* @__PURE__ */ u(
917
+ H,
918
+ {
919
+ mode: "multiple",
920
+ disabled: !t,
921
+ allowClear: !0,
922
+ className: "form-block-preview-control",
923
+ style: { width: "100%" },
924
+ placeholder: c || "请选择多项",
925
+ options: s,
926
+ value: z(n),
927
+ onChange: (f) => r(f ?? [])
928
+ }
929
+ ) : d === "checkbox" ? /* @__PURE__ */ u(
930
+ ze.Group,
931
+ {
932
+ disabled: !t,
933
+ className: "form-block-preview-control",
934
+ options: s,
935
+ value: z(n),
936
+ onChange: (f) => r(f)
937
+ }
938
+ ) : /* @__PURE__ */ u(
939
+ Le.Group,
940
+ {
941
+ disabled: !t,
942
+ className: "form-block-preview-control",
943
+ options: s,
944
+ value: V(n),
945
+ onChange: (f) => r(f.target.value)
946
+ }
947
+ )
948
+ ] });
949
+ }
950
+ const Wt = S(
951
+ {
952
+ name: "ChoicePicker",
953
+ schema: m.object({
954
+ label: m.any().optional(),
955
+ variant: m.any().optional(),
956
+ options: m.any().optional(),
957
+ value: m.any().optional(),
958
+ skoponPickerType: m.any().optional(),
959
+ placeholder: m.any().optional()
960
+ }).passthrough()
961
+ },
962
+ Jt
963
+ );
964
+ function Zt({ context: e }) {
965
+ const { interactive: t } = E(), { value: n, setValue: r } = _(e), o = e.componentModel.properties, a = v(o.label);
966
+ return /* @__PURE__ */ b("div", { className: "form-block-preview", children: [
967
+ a ? /* @__PURE__ */ u("div", { className: "form-block-preview-label", children: a }) : null,
968
+ /* @__PURE__ */ u(
969
+ Re,
970
+ {
971
+ disabled: !t,
972
+ className: "form-block-preview-control",
973
+ checked: n === !0,
974
+ onChange: (i) => r(i)
975
+ }
976
+ )
977
+ ] });
978
+ }
979
+ const Qt = S(
980
+ { name: "CheckBox", schema: R("CheckBox") },
981
+ Zt
982
+ );
983
+ function en(e, t, n) {
984
+ const r = V(e);
985
+ if (!r) return;
986
+ if (!t && n) {
987
+ const a = ne(r, "HH:mm", !0);
988
+ return a.isValid() ? a : void 0;
989
+ }
990
+ const o = ne(r);
991
+ return o.isValid() ? o : void 0;
992
+ }
993
+ function tn({ context: e }) {
994
+ const { interactive: t } = E(), { value: n, setValue: r } = _(e), o = e.componentModel.properties, a = v(o.label), i = v(o.placeholder), l = o.enableDate === !0, c = o.enableTime === !0, s = en(n, l, c), p = (d) => {
995
+ if (!d) {
996
+ r("");
997
+ return;
998
+ }
999
+ if (!l && c) {
1000
+ r(d.format("HH:mm"));
1001
+ return;
1002
+ }
1003
+ if (l && c) {
1004
+ r(d.format("YYYY-MM-DDTHH:mm"));
1005
+ return;
1006
+ }
1007
+ r(d.format("YYYY-MM-DD"));
1008
+ };
1009
+ return /* @__PURE__ */ b("div", { className: "form-block-preview", children: [
1010
+ a ? /* @__PURE__ */ u("div", { className: "form-block-preview-label", children: a }) : null,
1011
+ !l && c ? /* @__PURE__ */ u(
1012
+ Ue,
1013
+ {
1014
+ disabled: !t,
1015
+ className: "form-block-preview-control",
1016
+ style: { width: "100%" },
1017
+ placeholder: i || "选择时间",
1018
+ value: s,
1019
+ onChange: p
1020
+ }
1021
+ ) : /* @__PURE__ */ u(
1022
+ Be,
1023
+ {
1024
+ showTime: l && c,
1025
+ disabled: !t,
1026
+ className: "form-block-preview-control",
1027
+ style: { width: "100%" },
1028
+ placeholder: i || (l && c ? "选择日期时间" : "选择日期"),
1029
+ value: s,
1030
+ onChange: p
1031
+ }
1032
+ )
1033
+ ] });
1034
+ }
1035
+ const nn = S(
1036
+ {
1037
+ name: "DateTimeInput",
1038
+ schema: m.object({
1039
+ label: m.any().optional(),
1040
+ enableDate: m.any().optional(),
1041
+ enableTime: m.any().optional(),
1042
+ placeholder: m.any().optional(),
1043
+ value: m.any().optional(),
1044
+ min: m.any().optional(),
1045
+ max: m.any().optional()
1046
+ }).passthrough()
1047
+ },
1048
+ tn
1049
+ ), rn = {
1050
+ name: "FileUpload",
1051
+ schema: m.object({
1052
+ label: m.any().optional(),
1053
+ accept: m.any().optional(),
1054
+ fileAcceptTypes: m.any().optional(),
1055
+ filePlaceholderIcon: m.any().optional(),
1056
+ minCount: m.any().optional(),
1057
+ maxCount: m.any().optional(),
1058
+ value: m.any().optional()
1059
+ }).passthrough()
1060
+ };
1061
+ function on({ context: e }) {
1062
+ const { interactive: t } = E(), { value: n, setValue: r } = _(e), o = e.componentModel.properties, a = v(o.label), i = v(o.accept), l = Array.isArray(o.fileAcceptTypes) ? o.fileAcceptTypes.map(String) : void 0, c = i ? i.split(",").map((h) => h.trim()).filter(Boolean) : void 0, s = mt(l, c), p = typeof o.filePlaceholderIcon == "string" && ["video", "audio", "image", "file", "spreadsheet", "document"].includes(
1063
+ o.filePlaceholderIcon
1064
+ ) ? o.filePlaceholderIcon : "document", d = typeof o.maxCount == "number" ? o.maxCount : 1, f = z(n);
1065
+ return /* @__PURE__ */ b("div", { className: "form-block-preview", children: [
1066
+ a ? /* @__PURE__ */ u("div", { className: "form-block-preview-label", children: a }) : null,
1067
+ /* @__PURE__ */ b(
1068
+ ee.Dragger,
1069
+ {
1070
+ disabled: !t,
1071
+ accept: pt(l, c),
1072
+ className: "form-file-upload-preview",
1073
+ showUploadList: t && f.length > 0,
1074
+ fileList: t ? f.map((h, A) => ({
1075
+ uid: `${A}-${h}`,
1076
+ name: h,
1077
+ status: "done"
1078
+ })) : [],
1079
+ beforeUpload: (h) => {
1080
+ if (!t) return ee.LIST_IGNORE;
1081
+ const A = [...f, h.name].slice(0, Math.max(1, d));
1082
+ return r(A), !1;
1083
+ },
1084
+ onRemove: (h) => {
1085
+ r(f.filter((A) => A !== h.name));
1086
+ },
1087
+ children: [
1088
+ /* @__PURE__ */ u("p", { className: "form-file-upload-preview-icon", children: /* @__PURE__ */ u(Rt, { type: p, size: 40 }) }),
1089
+ /* @__PURE__ */ u("p", { className: "form-file-upload-preview-text", children: "点击或拖拽文件到此处上传" })
1090
+ ]
1091
+ }
1092
+ ),
1093
+ /* @__PURE__ */ b(J.Text, { type: "secondary", className: "form-block-preview-help", children: [
1094
+ "允许:",
1095
+ s ?? "全部类型"
1096
+ ] })
1097
+ ] });
1098
+ }
1099
+ const an = S(
1100
+ rn,
1101
+ on
1102
+ );
1103
+ function Me() {
1104
+ const t = [
1105
+ ...[...O.components.values()].filter(
1106
+ (r) => !Bt.has(r.name)
1107
+ ),
1108
+ $t,
1109
+ qt,
1110
+ Ht,
1111
+ Yt,
1112
+ Gt,
1113
+ Wt,
1114
+ Qt,
1115
+ nn,
1116
+ an
1117
+ ], n = [...O.functions.values()];
1118
+ return new Ve(Te, t, n, O.themeSchema);
1119
+ }
1120
+ const ln = De(
1121
+ function({
1122
+ doc: t,
1123
+ surfaceId: n = "skopon-form",
1124
+ emptyHint: r = null,
1125
+ interactive: o = !0,
1126
+ fieldNames: a = []
1127
+ }, i) {
1128
+ C(() => {
1129
+ ue(), ce();
1130
+ }, []);
1131
+ const l = M(null), c = M(a);
1132
+ c.current = a;
1133
+ const s = k(() => {
1134
+ if (q(t))
1135
+ return l.current = null, [];
1136
+ try {
1137
+ const p = new le([Me()]), d = It(t, {
1138
+ surfaceId: n,
1139
+ catalogId: Te
1140
+ });
1141
+ return p.processMessages(d), l.current = p, Array.from(p.model.surfacesMap.values());
1142
+ } catch (p) {
1143
+ return console.error("[SkoponFormRenderer] 渲染 A2UI surface 失败", p), l.current = null, [];
1144
+ }
1145
+ }, [t, n]);
1146
+ return je(
1147
+ i,
1148
+ () => ({
1149
+ getValues(p) {
1150
+ const d = l.current;
1151
+ if (!d) return {};
1152
+ const f = (p ?? c.current).map((h) => h.trim()).filter(Boolean);
1153
+ return wt(d, n, f);
1154
+ }
1155
+ }),
1156
+ [n]
1157
+ ), s.length === 0 ? /* @__PURE__ */ u(ae, { children: r }) : /* @__PURE__ */ u(ke, { interactive: o, children: /* @__PURE__ */ u("div", { className: "a2ui-surface a2ui-container", children: s.map((p) => /* @__PURE__ */ u(se, { surface: p }, p.id)) }) });
1158
+ }
1159
+ );
1160
+ function xn({
1161
+ messages: e,
1162
+ surfaceId: t = "skopon-form-stream",
1163
+ emptyHint: n = null,
1164
+ interactive: r = !0
1165
+ }) {
1166
+ C(() => {
1167
+ ue(), ce();
1168
+ }, []);
1169
+ const o = M(null), a = M(0), i = k(() => {
1170
+ const s = new le([Me()]);
1171
+ return o.current = s, a.current = 0, s;
1172
+ }, [t]), [l, c] = w(() => Array.from(i.model.surfacesMap.values()));
1173
+ return C(() => {
1174
+ const s = () => c(Array.from(i.model.surfacesMap.values())), p = i.onSurfaceCreated(s), d = i.onSurfaceDeleted(s);
1175
+ return () => {
1176
+ p.unsubscribe(), d.unsubscribe();
1177
+ };
1178
+ }, [i]), C(() => {
1179
+ if (!Array.isArray(e) || e.length === 0) return;
1180
+ const s = e.slice(a.current);
1181
+ s.length !== 0 && (i.processMessages(s), a.current = e.length, c(Array.from(i.model.surfacesMap.values())));
1182
+ }, [e, i]), l.length === 0 ? /* @__PURE__ */ u(ae, { children: n }) : /* @__PURE__ */ u(ke, { interactive: r, children: /* @__PURE__ */ u("div", { className: "a2ui-surface a2ui-container", children: l.map((s) => /* @__PURE__ */ u(se, { surface: s }, s.id)) }) });
1183
+ }
1184
+ function ie({
1185
+ payload: e,
1186
+ callbackUrl: t,
1187
+ title: n,
1188
+ unpublishedFormId: r,
1189
+ incompleteFormId: o,
1190
+ onNotify: a
1191
+ }) {
1192
+ const i = k(
1193
+ () => xe(e, t),
1194
+ [e, t]
1195
+ );
1196
+ async function l() {
1197
+ try {
1198
+ await Se(i), a == null || a("success", "已复制到剪贴板");
1199
+ } catch {
1200
+ a == null || a("error", "复制失败");
1201
+ }
1202
+ }
1203
+ return /* @__PURE__ */ b("div", { className: "ask-user-curl-card", children: [
1204
+ /* @__PURE__ */ b("div", { className: "ask-user-curl-card-header", children: [
1205
+ /* @__PURE__ */ b("div", { className: "ask-user-curl-card-header-title", children: [
1206
+ /* @__PURE__ */ u(J.Text, { type: "secondary", children: n ?? "curl 命令" }),
1207
+ r ? /* @__PURE__ */ u(Y, { title: r, children: /* @__PURE__ */ u(te, { className: "ask-user-curl-unpublished-tag", children: "卡片 ID 未发布" }) }) : null,
1208
+ o ? /* @__PURE__ */ u(Y, { title: o, children: /* @__PURE__ */ u(te, { className: "ask-user-curl-incomplete-tag", children: "卡片 ID 待补足" }) }) : null
1209
+ ] }),
1210
+ /* @__PURE__ */ u(pe, { size: "small", type: "text", onClick: () => void l(), children: "复制" })
1211
+ ] }),
1212
+ /* @__PURE__ */ u("pre", { className: "skopon-form-curl-json", children: i })
1213
+ ] });
1214
+ }
1215
+ function Sn({
1216
+ payload: e,
1217
+ formUniqueId: t,
1218
+ callbackUrl: n,
1219
+ submitMode: r = "curl",
1220
+ fetchFormDetail: o,
1221
+ onNotify: a
1222
+ }) {
1223
+ const [i, l] = w(null), [c, s] = w(!1), [p, d] = w(!0), f = M(null);
1224
+ C(() => {
1225
+ let g = !1;
1226
+ return d(!0), s(!1), o({ formUniqueId: t }).then((x) => {
1227
+ g || (s(!!x.disabled), l(x.disabled ? null : x.formDefinition ?? null));
1228
+ }).catch(() => {
1229
+ g || (s(!1), l(null));
1230
+ }).finally(() => {
1231
+ g || d(!1);
1232
+ }), () => {
1233
+ g = !0;
1234
+ };
1235
+ }, [t, o]);
1236
+ const { matchedBlocks: h, remainderPayload: A } = k(
1237
+ () => jt(e, i ?? void 0),
1238
+ [e, i]
1239
+ ), Z = k(
1240
+ () => h.map((g) => {
1241
+ var x;
1242
+ return (x = g.name) == null ? void 0 : x.trim();
1243
+ }).filter((g) => !!g),
1244
+ [h]
1245
+ ), Pe = k(() => !i || h.length === 0 ? null : _t(i, h), [i, h]);
1246
+ if (p)
1247
+ return /* @__PURE__ */ u("div", { className: "ask-user-form-card", children: /* @__PURE__ */ u(Ne, { size: "small" }) });
1248
+ if (h.length === 0)
1249
+ return /* @__PURE__ */ u(
1250
+ ie,
1251
+ {
1252
+ payload: e,
1253
+ callbackUrl: n,
1254
+ unpublishedFormId: c ? t : void 0,
1255
+ onNotify: a
1256
+ }
1257
+ );
1258
+ const Ie = Object.keys(A).length > 0;
1259
+ async function Ee() {
1260
+ var x;
1261
+ const g = ((x = f.current) == null ? void 0 : x.getValues(Z)) ?? {};
1262
+ if (r === "post") {
1263
+ const Q = (n ?? "").trim();
1264
+ if (!Q) {
1265
+ a == null || a("error", "callback_url 为空,无法提交");
1266
+ return;
1267
+ }
1268
+ try {
1269
+ const T = await Vt(Q, g);
1270
+ T.ok ? a == null || a("success", "提交成功") : a == null || a("error", `提交失败 (${T.status})`);
1271
+ } catch (T) {
1272
+ const _e = T instanceof Error ? T.message : "提交失败";
1273
+ a == null || a("error", _e);
1274
+ }
1275
+ return;
1276
+ }
1277
+ try {
1278
+ await Se(xe(g, n)), a == null || a("success", "已复制 curl 到剪贴板");
1279
+ } catch {
1280
+ a == null || a("error", "复制失败");
1281
+ }
1282
+ }
1283
+ return /* @__PURE__ */ b("div", { className: "ask-user-form-card", children: [
1284
+ /* @__PURE__ */ u(
1285
+ ln,
1286
+ {
1287
+ ref: f,
1288
+ doc: Pe,
1289
+ surfaceId: `ask-user-${t}`,
1290
+ fieldNames: Z,
1291
+ interactive: !0
1292
+ }
1293
+ ),
1294
+ /* @__PURE__ */ u("div", { className: "ask-user-form-actions", children: /* @__PURE__ */ u(Y, { title: r === "curl" ? "点击复制 curl" : "提交 JSON 到 callback_url", children: /* @__PURE__ */ u(pe, { type: "primary", size: "small", onClick: () => void Ee(), children: "提交" }) }) }),
1295
+ Ie ? /* @__PURE__ */ u(
1296
+ ie,
1297
+ {
1298
+ payload: A,
1299
+ callbackUrl: n,
1300
+ title: "以下字段不在表单中,请使用 curl 提交",
1301
+ incompleteFormId: t,
1302
+ onNotify: a
1303
+ }
1304
+ ) : null
1305
+ ] });
1306
+ }
1307
+ export {
1308
+ bn as A2UI_PROTOCOL_VERSION,
1309
+ Sn as AskUserFormCard,
1310
+ ie as CurlSubmitBlock,
1311
+ Ke as FORM_MEDIA_SIZES,
1312
+ xn as SkoponA2uiStreamRenderer,
1313
+ ln as SkoponFormRenderer,
1314
+ Pt as a2uiToBlocks,
1315
+ ye as blocksToA2ui,
1316
+ _t as buildAskUserSurface,
1317
+ xe as buildCurlStatement,
1318
+ Se as copyTextToClipboard,
1319
+ gn as createFormClient,
1320
+ wt as extractSurfaceValues,
1321
+ jt as intersectPayloadWithForm,
1322
+ q as isA2uiSurfaceEmpty,
1323
+ re as isInputBlockType,
1324
+ qe as isLayoutBlockType,
1325
+ G as isMediaBlockType,
1326
+ Ft as mapFormDefinitionFromDto,
1327
+ he as normalizeFormDefinition,
1328
+ Et as resolveSurfaceFromFormDefinition,
1329
+ Vt as submitFormJson,
1330
+ It as surfaceDocToMessages,
1331
+ D as syncFormDefinition
1332
+ };