@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
@@ -0,0 +1,50 @@
1
+ export interface SubmitFormJsonOptions {
2
+ fetch?: typeof fetch
3
+ headers?: Record<string, string>
4
+ }
5
+
6
+ export interface SubmitFormJsonResult {
7
+ ok: boolean
8
+ status: number
9
+ body?: unknown
10
+ }
11
+
12
+ export async function submitFormJson(
13
+ callbackUrl: string,
14
+ payload: unknown,
15
+ options?: SubmitFormJsonOptions,
16
+ ): Promise<SubmitFormJsonResult> {
17
+ const url = callbackUrl.trim()
18
+ if (!url) {
19
+ throw new Error('callback_url 为空')
20
+ }
21
+ const fetchFn = options?.fetch ?? fetch
22
+ const response = await fetchFn(url, {
23
+ method: 'POST',
24
+ headers: {
25
+ 'Content-Type': 'application/json',
26
+ ...(options?.headers ?? {}),
27
+ },
28
+ body: JSON.stringify(payload ?? {}),
29
+ })
30
+ let body: unknown
31
+ const contentType = response.headers.get('content-type') ?? ''
32
+ if (contentType.includes('application/json')) {
33
+ try {
34
+ body = await response.json()
35
+ } catch {
36
+ body = undefined
37
+ }
38
+ } else {
39
+ try {
40
+ body = await response.text()
41
+ } catch {
42
+ body = undefined
43
+ }
44
+ }
45
+ return { ok: response.ok, status: response.status, body }
46
+ }
47
+
48
+ export async function copyTextToClipboard(text: string): Promise<void> {
49
+ await navigator.clipboard.writeText(text)
50
+ }
@@ -0,0 +1,139 @@
1
+ /**
2
+ * A2UI v0.9 协议子集类型(对齐 @a2ui/react basicCatalog + skopon 自定义 catalog)。
3
+ */
4
+ export type A2uiBinding<T> = T | { path: string }
5
+
6
+ export type A2uiComponentName =
7
+ | 'Column'
8
+ | 'Row'
9
+ | 'Text'
10
+ | 'Image'
11
+ | 'Video'
12
+ | 'AudioPlayer'
13
+ | 'TextField'
14
+ | 'CheckBox'
15
+ | 'ChoicePicker'
16
+ | 'DateTimeInput'
17
+ | 'FileUpload'
18
+ | 'SkoponMedia'
19
+ | 'SkoponSelect'
20
+
21
+ export interface A2uiComponentNode {
22
+ id: string
23
+ component: A2uiComponentName | string
24
+ children?: string[]
25
+ [prop: string]: unknown
26
+ }
27
+
28
+ export interface A2uiSurfaceDoc {
29
+ root: string
30
+ components: A2uiComponentNode[]
31
+ dataModel?: Record<string, unknown>
32
+ surfaceProperties?: Record<string, unknown> & { styleId?: string | null }
33
+ }
34
+
35
+ export const A2UI_PROTOCOL_VERSION = 'v0.9' as const
36
+
37
+ export type FormJsonSchema = Record<string, unknown>
38
+
39
+ export type FormBlockType =
40
+ | 'heading'
41
+ | 'paragraph'
42
+ | 'text'
43
+ | 'textarea'
44
+ | 'email'
45
+ | 'number'
46
+ | 'select'
47
+ | 'multiselect'
48
+ | 'radio'
49
+ | 'checkbox'
50
+ | 'toggle'
51
+ | 'tel'
52
+ | 'url'
53
+ | 'datetime'
54
+ | 'time'
55
+ | 'file'
56
+ | 'image'
57
+ | 'video'
58
+ | 'audio'
59
+
60
+ export type FormMediaSize = 'huge' | 'large' | 'medium' | 'small' | 'icon'
61
+
62
+ export type FormFilePlaceholderIcon =
63
+ | 'video'
64
+ | 'audio'
65
+ | 'image'
66
+ | 'file'
67
+ | 'spreadsheet'
68
+ | 'document'
69
+
70
+ export const FORM_MEDIA_SIZES: FormMediaSize[] = [
71
+ 'huge',
72
+ 'large',
73
+ 'medium',
74
+ 'small',
75
+ 'icon',
76
+ ]
77
+
78
+ export interface FormBlockOption {
79
+ value: string
80
+ label: string
81
+ }
82
+
83
+ export interface FormBlock {
84
+ id: string
85
+ type: FormBlockType
86
+ name?: string
87
+ label?: string
88
+ placeholder?: string
89
+ help?: string
90
+ required?: boolean
91
+ options?: FormBlockOption[]
92
+ mediaUrl?: string
93
+ mediaUrls?: string[]
94
+ mediaSize?: FormMediaSize
95
+ fileAcceptTypes?: string[]
96
+ fileAcceptExtensions?: string[]
97
+ filePlaceholderIcon?: FormFilePlaceholderIcon
98
+ fileMinCount?: number
99
+ fileMaxCount?: number
100
+ defaultValue?: string | string[] | boolean
101
+ }
102
+
103
+ export interface FormSchema {
104
+ title?: string
105
+ description?: string
106
+ blocks: FormBlock[]
107
+ jsonSchema: FormJsonSchema
108
+ }
109
+
110
+ export function isMediaBlockType(type: FormBlockType): boolean {
111
+ return type === 'image' || type === 'video' || type === 'audio'
112
+ }
113
+
114
+ export function isLayoutBlockType(type: FormBlockType): boolean {
115
+ return type === 'heading' || type === 'paragraph'
116
+ }
117
+
118
+ export function isInputBlockType(type: FormBlockType): boolean {
119
+ return !isLayoutBlockType(type) && !isMediaBlockType(type)
120
+ }
121
+
122
+ export interface FormDefinitionPayload {
123
+ title?: string
124
+ description?: string
125
+ blocks?: FormBlock[]
126
+ a2ui?: A2uiSurfaceDoc
127
+ json_schema?: FormJsonSchema
128
+ jsonSchema?: FormJsonSchema
129
+ }
130
+
131
+ export interface FormDetailResult {
132
+ formUniqueId: string
133
+ formId?: number
134
+ disabled: boolean
135
+ formDefinition?: FormSchema
136
+ a2ui?: A2uiSurfaceDoc
137
+ }
138
+
139
+ export type SubmitMode = 'curl' | 'post'