@skopon-cool/form-sdk 0.4.4 → 0.4.6
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.
- package/dist/adapter/formSchema.d.ts +3 -0
- package/dist/adapter/formSchema.d.ts.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1215 -1051
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/adapter/formSchema.test.ts +150 -10
- package/src/adapter/formSchema.ts +224 -20
- package/src/index.ts +17 -3
- package/src/submit/submit.test.ts +37 -0
- package/src/types/index.ts +34 -0
package/dist/types/index.d.ts
CHANGED
|
@@ -31,9 +31,17 @@ export interface FormBlockOption {
|
|
|
31
31
|
value: string;
|
|
32
32
|
label: string;
|
|
33
33
|
}
|
|
34
|
+
export type FormConditionOperator = 'eq' | 'ne' | 'empty' | 'notEmpty';
|
|
35
|
+
export interface FormBlockCondition {
|
|
36
|
+
fieldName: string;
|
|
37
|
+
operator: FormConditionOperator;
|
|
38
|
+
value?: string;
|
|
39
|
+
}
|
|
34
40
|
/** 简历多选组件:渲染时用于 /univ/resume/search 的筛选条件 */
|
|
35
41
|
export interface FormResumeFilter {
|
|
36
42
|
names?: string[];
|
|
43
|
+
/** Agent 类型(编辑器辅助,运行时不用) */
|
|
44
|
+
agentKind?: string;
|
|
37
45
|
agentUniqueIds?: string[];
|
|
38
46
|
resumeUniqueIds?: string[];
|
|
39
47
|
pageSize?: number;
|
|
@@ -70,6 +78,12 @@ export interface FormBlock {
|
|
|
70
78
|
fileMinCount?: number;
|
|
71
79
|
fileMaxCount?: number;
|
|
72
80
|
defaultValue?: string | string[] | boolean;
|
|
81
|
+
/** 派生 JSON Schema 时写入 property.$comment */
|
|
82
|
+
jsonSchemaDescription?: string;
|
|
83
|
+
/** 是否隐藏(仅 text 块;隐藏时仍提交) */
|
|
84
|
+
hidden?: boolean;
|
|
85
|
+
/** 是否需要 LLM 处理(持久化进 block json) */
|
|
86
|
+
needLLM?: boolean;
|
|
73
87
|
/** 简历多选:是否显示「换一批」 */
|
|
74
88
|
resumeEnableRefresh?: boolean;
|
|
75
89
|
/** 简历多选:最少选中数量,配置值 ≥ 1 */
|
|
@@ -86,6 +100,7 @@ export interface FormBlock {
|
|
|
86
100
|
caseMaxCount?: number;
|
|
87
101
|
/** 案例单选:列表筛选条件(持久化进 block json) */
|
|
88
102
|
caseFilter?: FormCaseFilter;
|
|
103
|
+
condition?: FormBlockCondition;
|
|
89
104
|
}
|
|
90
105
|
export interface FormSchema {
|
|
91
106
|
title?: string;
|
|
@@ -96,6 +111,9 @@ export interface FormSchema {
|
|
|
96
111
|
export declare function isMediaBlockType(type: FormBlockType): boolean;
|
|
97
112
|
export declare function isLayoutBlockType(type: FormBlockType): boolean;
|
|
98
113
|
export declare function isInputBlockType(type: FormBlockType): boolean;
|
|
114
|
+
export declare function isDisplayBlockType(type: FormBlockType): boolean;
|
|
115
|
+
export declare function isOptionsBlockType(type: FormBlockType): boolean;
|
|
116
|
+
export declare function supportsDefaultValue(type: FormBlockType): boolean;
|
|
99
117
|
export interface FormDefinitionPayload {
|
|
100
118
|
title?: string;
|
|
101
119
|
description?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
* @vitest-environment node
|
|
3
3
|
*/
|
|
4
4
|
import { describe, it, expect } from 'vitest'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
coerceToggleValue,
|
|
7
|
+
normalizeFormDefinition,
|
|
8
|
+
blocksToJsonSchema,
|
|
9
|
+
} from './formSchema'
|
|
6
10
|
import { mapFormDefinitionFromDto } from './resolveSurface'
|
|
7
11
|
|
|
8
12
|
describe('coerceToggleValue', () => {
|
|
@@ -38,26 +42,162 @@ describe('normalizeFormDefinition toggle default', () => {
|
|
|
38
42
|
expect(def.blocks[0]?.defaultValue).toBe(true)
|
|
39
43
|
})
|
|
40
44
|
|
|
41
|
-
it('
|
|
42
|
-
const
|
|
45
|
+
it('regenerates jsonSchema from blocks', () => {
|
|
46
|
+
const def = normalizeFormDefinition({
|
|
47
|
+
title: 'Title',
|
|
48
|
+
description: 'Desc',
|
|
49
|
+
blocks: [
|
|
50
|
+
{
|
|
51
|
+
id: 'b1',
|
|
52
|
+
type: 'text',
|
|
53
|
+
name: 'title',
|
|
54
|
+
label: '标题',
|
|
55
|
+
required: true,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
jsonSchema: { type: 'object', properties: { stale: { type: 'number' } } },
|
|
59
|
+
})
|
|
60
|
+
expect(def.jsonSchema).toEqual(
|
|
61
|
+
blocksToJsonSchema(def.blocks, 'Title', 'Desc'),
|
|
62
|
+
)
|
|
63
|
+
expect(def.jsonSchema).toMatchObject({
|
|
64
|
+
type: 'object',
|
|
65
|
+
properties: { title: { type: 'string' } },
|
|
66
|
+
required: ['title'],
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
describe('normalizeFormDefinition preserves needLLM and editor fields', () => {
|
|
72
|
+
it('keeps needLLM, hidden, condition, jsonSchemaDescription after normalize', () => {
|
|
73
|
+
const def = normalizeFormDefinition({
|
|
74
|
+
title: '',
|
|
75
|
+
description: '',
|
|
76
|
+
blocks: [
|
|
77
|
+
{
|
|
78
|
+
id: 'b1',
|
|
79
|
+
type: 'text',
|
|
80
|
+
name: 'prompt',
|
|
81
|
+
label: 'Prompt',
|
|
82
|
+
needLLM: true,
|
|
83
|
+
hidden: true,
|
|
84
|
+
jsonSchemaDescription: 'for agent',
|
|
85
|
+
condition: { fieldName: 'other', operator: 'eq', value: '1' },
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: 'b0',
|
|
89
|
+
type: 'text',
|
|
90
|
+
name: 'other',
|
|
91
|
+
label: 'Other',
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
jsonSchema: {},
|
|
95
|
+
})
|
|
96
|
+
const block = def.blocks.find((item) => item.name === 'prompt')
|
|
97
|
+
expect(block?.needLLM).toBe(true)
|
|
98
|
+
expect(block?.hidden).toBe(true)
|
|
99
|
+
expect(block?.jsonSchemaDescription).toBe('for agent')
|
|
100
|
+
expect(block?.condition).toEqual({
|
|
101
|
+
fieldName: 'other',
|
|
102
|
+
operator: 'eq',
|
|
103
|
+
value: '1',
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('keeps resumeFilter.agentKind', () => {
|
|
43
108
|
const def = normalizeFormDefinition({
|
|
44
109
|
title: '',
|
|
45
110
|
description: '',
|
|
46
|
-
blocks: [
|
|
47
|
-
|
|
111
|
+
blocks: [
|
|
112
|
+
{
|
|
113
|
+
id: 'b1',
|
|
114
|
+
type: 'resume_multiselect',
|
|
115
|
+
name: 'partners',
|
|
116
|
+
resumeFilter: {
|
|
117
|
+
agentKind: 'management',
|
|
118
|
+
names: [],
|
|
119
|
+
agentUniqueIds: [],
|
|
120
|
+
resumeUniqueIds: [],
|
|
121
|
+
pageSize: 20,
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
jsonSchema: {},
|
|
48
126
|
})
|
|
49
|
-
expect(def.
|
|
127
|
+
expect(def.blocks[0]?.resumeFilter?.agentKind).toBe('management')
|
|
50
128
|
})
|
|
51
129
|
})
|
|
52
130
|
|
|
53
131
|
describe('mapFormDefinitionFromDto jsonSchema', () => {
|
|
54
|
-
it('
|
|
55
|
-
const schema = { type: 'object' }
|
|
132
|
+
it('regenerates jsonSchema from DTO blocks', () => {
|
|
56
133
|
const def = mapFormDefinitionFromDto({
|
|
57
134
|
title: 'T',
|
|
58
135
|
blocks: [{ id: 'b1', type: 'text', name: 'x', label: 'X' }],
|
|
59
|
-
json_schema:
|
|
136
|
+
json_schema: { type: 'object', properties: { stale: { type: 'number' } } },
|
|
137
|
+
})
|
|
138
|
+
expect(def?.jsonSchema).toMatchObject({
|
|
139
|
+
type: 'object',
|
|
140
|
+
title: 'T',
|
|
141
|
+
properties: { x: { type: 'string' } },
|
|
142
|
+
})
|
|
143
|
+
})
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
describe('normalizeCaseFilter flowUniqueIds', () => {
|
|
147
|
+
it('keeps array flowUniqueIds', () => {
|
|
148
|
+
const def = normalizeFormDefinition({
|
|
149
|
+
title: '',
|
|
150
|
+
description: '',
|
|
151
|
+
blocks: [
|
|
152
|
+
{
|
|
153
|
+
id: 'b1',
|
|
154
|
+
type: 'case_multiselect',
|
|
155
|
+
name: 'cases',
|
|
156
|
+
caseFilter: { flowUniqueIds: ['flow-a', 'flow-b'], pageSize: 20 },
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
jsonSchema: {},
|
|
160
|
+
})
|
|
161
|
+
expect(def.blocks[0]?.caseFilter?.flowUniqueIds).toEqual(['flow-a', 'flow-b'])
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
it('parses JSON-string flowUniqueIds from n8n-style payloads', () => {
|
|
165
|
+
const def = normalizeFormDefinition({
|
|
166
|
+
title: '',
|
|
167
|
+
description: '',
|
|
168
|
+
blocks: [
|
|
169
|
+
{
|
|
170
|
+
id: 'b1',
|
|
171
|
+
type: 'case_multiselect',
|
|
172
|
+
name: 'cases',
|
|
173
|
+
caseFilter: {
|
|
174
|
+
flowUniqueIds: JSON.stringify(['flow-a', 'flow-b']) as unknown as string[],
|
|
175
|
+
pageSize: 20,
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
jsonSchema: {},
|
|
180
|
+
})
|
|
181
|
+
expect(def.blocks[0]?.caseFilter?.flowUniqueIds).toEqual(['flow-a', 'flow-b'])
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
it('falls back to empty array when flowUniqueIds string is not a JSON array', () => {
|
|
185
|
+
const def = normalizeFormDefinition({
|
|
186
|
+
title: '',
|
|
187
|
+
description: '',
|
|
188
|
+
blocks: [
|
|
189
|
+
{
|
|
190
|
+
id: 'b1',
|
|
191
|
+
type: 'case_multiselect',
|
|
192
|
+
name: 'cases',
|
|
193
|
+
caseFilter: {
|
|
194
|
+
flowUniqueIds: 'not-json' as unknown as string[],
|
|
195
|
+
pageSize: 20,
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
jsonSchema: {},
|
|
60
200
|
})
|
|
61
|
-
expect(def?.
|
|
201
|
+
expect(def.blocks[0]?.caseFilter?.flowUniqueIds).toEqual([])
|
|
62
202
|
})
|
|
63
203
|
})
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type {
|
|
2
|
+
FormBlock,
|
|
3
|
+
FormBlockType,
|
|
4
|
+
FormCaseFilter,
|
|
5
|
+
FormResumeFilter,
|
|
6
|
+
FormJsonSchema,
|
|
7
|
+
FormSchema,
|
|
8
|
+
} from '../types/index'
|
|
9
|
+
import { isInputBlockType, isMediaBlockType, isOptionsBlockType } from '../types/index'
|
|
3
10
|
import { generateId } from './id'
|
|
4
11
|
import {
|
|
5
12
|
filterFileAcceptExtensionsForTypes,
|
|
@@ -32,7 +39,7 @@ function normalizeFileUploadCount(raw: unknown, fallback = 1): number {
|
|
|
32
39
|
return Math.max(0, Math.floor(num))
|
|
33
40
|
}
|
|
34
41
|
|
|
35
|
-
function normalizeMultiselectCount(raw: unknown, fallback = 1): number {
|
|
42
|
+
export function normalizeMultiselectCount(raw: unknown, fallback = 1): number {
|
|
36
43
|
const num = typeof raw === 'number' ? raw : Number(raw)
|
|
37
44
|
if (!Number.isFinite(num)) return fallback
|
|
38
45
|
return Math.max(1, Math.floor(num))
|
|
@@ -42,16 +49,41 @@ function normalizeDefaultValue(
|
|
|
42
49
|
type: FormBlockType,
|
|
43
50
|
raw: FormBlock['defaultValue'],
|
|
44
51
|
): FormBlock['defaultValue'] {
|
|
45
|
-
if (raw === undefined) return undefined
|
|
46
|
-
if (type === 'toggle')
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
if (raw === undefined || raw === null) return undefined
|
|
53
|
+
if (type === 'toggle') {
|
|
54
|
+
return coerceToggleValue(raw)
|
|
55
|
+
}
|
|
56
|
+
if (
|
|
57
|
+
type === 'multiselect' ||
|
|
58
|
+
type === 'checkbox' ||
|
|
59
|
+
type === 'resume_multiselect' ||
|
|
60
|
+
type === 'case_multiselect'
|
|
61
|
+
) {
|
|
62
|
+
if (Array.isArray(raw)) {
|
|
63
|
+
const values = raw.map(String).map((item) => item.trim()).filter(Boolean)
|
|
64
|
+
return values
|
|
65
|
+
}
|
|
66
|
+
if (typeof raw === 'string' && raw.trim()) return [raw.trim()]
|
|
50
67
|
return []
|
|
51
68
|
}
|
|
52
69
|
if (typeof raw === 'boolean') return raw ? 'true' : 'false'
|
|
53
70
|
if (Array.isArray(raw)) return raw.map(String)
|
|
54
|
-
|
|
71
|
+
const trimmed = String(raw).trim()
|
|
72
|
+
return trimmed || undefined
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** n8n 等可能把 flowUniqueIds 发成 JSON 数组字符串;解析失败则 []。 */
|
|
76
|
+
function normalizeFlowUniqueIds(raw: unknown): string[] {
|
|
77
|
+
if (Array.isArray(raw)) return raw.map(String).filter(Boolean)
|
|
78
|
+
if (typeof raw === 'string' && raw.trim()) {
|
|
79
|
+
try {
|
|
80
|
+
const parsed: unknown = JSON.parse(raw)
|
|
81
|
+
if (Array.isArray(parsed)) return parsed.map(String).filter(Boolean)
|
|
82
|
+
} catch {
|
|
83
|
+
/* ignore */
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return []
|
|
55
87
|
}
|
|
56
88
|
|
|
57
89
|
function normalizeCaseFilter(raw: FormCaseFilter | undefined): FormCaseFilter {
|
|
@@ -76,9 +108,7 @@ function normalizeCaseFilter(raw: FormCaseFilter | undefined): FormCaseFilter {
|
|
|
76
108
|
typeof raw?.category === 'string' && raw.category.trim()
|
|
77
109
|
? raw.category.trim()
|
|
78
110
|
: undefined
|
|
79
|
-
const flowUniqueIds =
|
|
80
|
-
? raw.flowUniqueIds.map(String).filter(Boolean)
|
|
81
|
-
: []
|
|
111
|
+
const flowUniqueIds = normalizeFlowUniqueIds(raw?.flowUniqueIds)
|
|
82
112
|
return { agentKind, agentUniqueId, flowType, category, flowUniqueIds, pageSize }
|
|
83
113
|
}
|
|
84
114
|
|
|
@@ -88,8 +118,13 @@ function normalizeResumeFilter(raw: FormResumeFilter | undefined): FormResumeFil
|
|
|
88
118
|
Number.isFinite(pageSizeRaw) && pageSizeRaw >= 1 && pageSizeRaw <= 100
|
|
89
119
|
? Math.floor(pageSizeRaw)
|
|
90
120
|
: 20
|
|
121
|
+
const agentKind =
|
|
122
|
+
typeof raw?.agentKind === 'string' && raw.agentKind.trim()
|
|
123
|
+
? raw.agentKind.trim()
|
|
124
|
+
: undefined
|
|
91
125
|
return {
|
|
92
126
|
names: Array.isArray(raw?.names) ? raw!.names.map(String).filter(Boolean) : [],
|
|
127
|
+
agentKind,
|
|
93
128
|
agentUniqueIds: Array.isArray(raw?.agentUniqueIds)
|
|
94
129
|
? raw!.agentUniqueIds.map(String).filter(Boolean)
|
|
95
130
|
: [],
|
|
@@ -136,12 +171,22 @@ function normalizeBlock(raw: FormBlock): FormBlock {
|
|
|
136
171
|
fileMinCount: type === 'file' ? normalizeFileUploadCount(migrated.fileMinCount, 1) : undefined,
|
|
137
172
|
fileMaxCount: type === 'file' ? normalizeFileUploadCount(migrated.fileMaxCount, 1) : undefined,
|
|
138
173
|
defaultValue: normalizeDefaultValue(type, migrated.defaultValue),
|
|
174
|
+
jsonSchemaDescription: migrated.jsonSchemaDescription?.trim() ?? '',
|
|
175
|
+
hidden: type === 'text' ? migrated.hidden === true : undefined,
|
|
176
|
+
needLLM: migrated.needLLM === true ? true : undefined,
|
|
139
177
|
options: Array.isArray(migrated.options)
|
|
140
178
|
? migrated.options.map((opt, index) => ({
|
|
141
179
|
value: opt.value?.trim() || `option_${index + 1}`,
|
|
142
180
|
label: opt.label?.trim() || `选项 ${index + 1}`,
|
|
143
181
|
}))
|
|
144
182
|
: undefined,
|
|
183
|
+
condition: migrated.condition?.fieldName
|
|
184
|
+
? {
|
|
185
|
+
fieldName: migrated.condition.fieldName.trim(),
|
|
186
|
+
operator: migrated.condition.operator ?? 'eq',
|
|
187
|
+
value: migrated.condition.value,
|
|
188
|
+
}
|
|
189
|
+
: undefined,
|
|
145
190
|
resumeEnableRefresh:
|
|
146
191
|
type === 'resume_multiselect' ? migrated.resumeEnableRefresh !== false : undefined,
|
|
147
192
|
resumeMinCount:
|
|
@@ -169,12 +214,175 @@ function normalizeBlock(raw: FormBlock): FormBlock {
|
|
|
169
214
|
}
|
|
170
215
|
}
|
|
171
216
|
|
|
217
|
+
function getOptionValueSet(block: FormBlock): Set<string> {
|
|
218
|
+
return new Set((block.options ?? []).map((opt) => opt.value))
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function buildMultiselectCountJsonSchema(
|
|
222
|
+
minCount: number | undefined,
|
|
223
|
+
maxCount: number | undefined,
|
|
224
|
+
): Record<string, unknown> {
|
|
225
|
+
const schema: Record<string, unknown> = {
|
|
226
|
+
type: 'array',
|
|
227
|
+
items: { type: 'string' },
|
|
228
|
+
}
|
|
229
|
+
if (minCount !== undefined) {
|
|
230
|
+
schema.minItems = normalizeMultiselectCount(minCount, 1)
|
|
231
|
+
}
|
|
232
|
+
if (maxCount !== undefined) {
|
|
233
|
+
schema.maxItems = normalizeMultiselectCount(maxCount, 1)
|
|
234
|
+
}
|
|
235
|
+
return schema
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function resolveSchemaDefaultValue(block: FormBlock): unknown | undefined {
|
|
239
|
+
const normalized = normalizeDefaultValue(block.type, block.defaultValue)
|
|
240
|
+
if (normalized === undefined) return undefined
|
|
241
|
+
|
|
242
|
+
const optionValues = getOptionValueSet(block)
|
|
243
|
+
|
|
244
|
+
switch (block.type) {
|
|
245
|
+
case 'toggle':
|
|
246
|
+
return normalized as boolean
|
|
247
|
+
case 'number': {
|
|
248
|
+
const num = Number(normalized as string)
|
|
249
|
+
return Number.isNaN(num) ? undefined : num
|
|
250
|
+
}
|
|
251
|
+
case 'multiselect':
|
|
252
|
+
case 'checkbox': {
|
|
253
|
+
const values = (normalized as string[]).filter((item) => optionValues.has(item))
|
|
254
|
+
return values.length > 0 ? values : undefined
|
|
255
|
+
}
|
|
256
|
+
case 'select':
|
|
257
|
+
case 'radio': {
|
|
258
|
+
const value = normalized as string
|
|
259
|
+
return optionValues.has(value) ? value : undefined
|
|
260
|
+
}
|
|
261
|
+
case 'resume_multiselect':
|
|
262
|
+
case 'case_multiselect': {
|
|
263
|
+
const values = Array.isArray(normalized)
|
|
264
|
+
? (normalized as string[]).map(String).filter(Boolean)
|
|
265
|
+
: []
|
|
266
|
+
return values.length > 0 ? values : undefined
|
|
267
|
+
}
|
|
268
|
+
default:
|
|
269
|
+
return normalized
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function blockToJsonSchemaProperty(block: FormBlock): Record<string, unknown> | null {
|
|
274
|
+
const name = block.name?.trim()
|
|
275
|
+
if (!name || !isInputBlockType(block.type)) return null
|
|
276
|
+
|
|
277
|
+
let property: Record<string, unknown>
|
|
278
|
+
|
|
279
|
+
switch (block.type) {
|
|
280
|
+
case 'number':
|
|
281
|
+
property = { type: 'number' }
|
|
282
|
+
break
|
|
283
|
+
case 'toggle':
|
|
284
|
+
property = { type: 'boolean' }
|
|
285
|
+
break
|
|
286
|
+
case 'select':
|
|
287
|
+
case 'radio': {
|
|
288
|
+
property = { type: 'string' }
|
|
289
|
+
const enumValues = (block.options ?? []).map((opt) => opt.value).filter(Boolean)
|
|
290
|
+
if (enumValues.length > 0) property.enum = enumValues
|
|
291
|
+
break
|
|
292
|
+
}
|
|
293
|
+
case 'multiselect':
|
|
294
|
+
case 'checkbox': {
|
|
295
|
+
const enumValues = (block.options ?? []).map((opt) => opt.value).filter(Boolean)
|
|
296
|
+
property = {
|
|
297
|
+
type: 'array',
|
|
298
|
+
items:
|
|
299
|
+
enumValues.length > 0
|
|
300
|
+
? { type: 'string', enum: enumValues }
|
|
301
|
+
: { type: 'string' },
|
|
302
|
+
}
|
|
303
|
+
break
|
|
304
|
+
}
|
|
305
|
+
case 'file': {
|
|
306
|
+
const minCount = normalizeFileUploadCount(block.fileMinCount, 1)
|
|
307
|
+
const maxCount = normalizeFileUploadCount(block.fileMaxCount, 1)
|
|
308
|
+
if (maxCount <= 1) {
|
|
309
|
+
property = { type: 'string' }
|
|
310
|
+
} else {
|
|
311
|
+
property = {
|
|
312
|
+
type: 'array',
|
|
313
|
+
items: { type: 'string' },
|
|
314
|
+
minItems: minCount,
|
|
315
|
+
maxItems: maxCount,
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
break
|
|
319
|
+
}
|
|
320
|
+
case 'resume_multiselect':
|
|
321
|
+
property = buildMultiselectCountJsonSchema(block.resumeMinCount, block.resumeMaxCount)
|
|
322
|
+
break
|
|
323
|
+
case 'case_multiselect':
|
|
324
|
+
property = buildMultiselectCountJsonSchema(block.caseMinCount, block.caseMaxCount)
|
|
325
|
+
break
|
|
326
|
+
case 'text':
|
|
327
|
+
property = { type: 'string' }
|
|
328
|
+
if (block.hidden) property['x-hidden'] = true
|
|
329
|
+
break
|
|
330
|
+
default:
|
|
331
|
+
property = { type: 'string' }
|
|
332
|
+
break
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const comment = block.jsonSchemaDescription?.trim()
|
|
336
|
+
if (comment) property.$comment = comment
|
|
337
|
+
|
|
338
|
+
const defaultValue = resolveSchemaDefaultValue(block)
|
|
339
|
+
if (defaultValue !== undefined) property.default = defaultValue
|
|
340
|
+
|
|
341
|
+
return property
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export function blocksToJsonSchema(
|
|
345
|
+
blocks: FormBlock[],
|
|
346
|
+
title?: string,
|
|
347
|
+
description?: string,
|
|
348
|
+
): FormJsonSchema {
|
|
349
|
+
const properties: Record<string, Record<string, unknown>> = {}
|
|
350
|
+
const required: string[] = []
|
|
351
|
+
|
|
352
|
+
for (const block of blocks) {
|
|
353
|
+
const name = block.name?.trim()
|
|
354
|
+
if (!name || !isInputBlockType(block.type)) continue
|
|
355
|
+
|
|
356
|
+
const property = blockToJsonSchemaProperty(block)
|
|
357
|
+
if (!property) continue
|
|
358
|
+
|
|
359
|
+
properties[name] = property
|
|
360
|
+
if (block.required) required.push(name)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const schema: FormJsonSchema = {
|
|
364
|
+
type: 'object',
|
|
365
|
+
properties,
|
|
366
|
+
required,
|
|
367
|
+
additionalProperties: false,
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const trimmedTitle = title?.trim()
|
|
371
|
+
const trimmedDescription = description?.trim()
|
|
372
|
+
if (trimmedTitle) schema.title = trimmedTitle
|
|
373
|
+
if (trimmedDescription) schema.description = trimmedDescription
|
|
374
|
+
|
|
375
|
+
return schema
|
|
376
|
+
}
|
|
377
|
+
|
|
172
378
|
export function syncFormDefinition(definition: FormSchema): FormSchema {
|
|
379
|
+
const title = definition.title ?? ''
|
|
380
|
+
const description = definition.description ?? ''
|
|
173
381
|
return {
|
|
174
|
-
title
|
|
175
|
-
description
|
|
382
|
+
title,
|
|
383
|
+
description,
|
|
176
384
|
blocks: definition.blocks,
|
|
177
|
-
jsonSchema: definition.
|
|
385
|
+
jsonSchema: blocksToJsonSchema(definition.blocks, title, description),
|
|
178
386
|
}
|
|
179
387
|
}
|
|
180
388
|
|
|
@@ -187,7 +395,7 @@ export function normalizeFormDefinition(raw: FormSchema | undefined): FormSchema
|
|
|
187
395
|
title: typeof raw.title === 'string' ? raw.title : '',
|
|
188
396
|
description: typeof raw.description === 'string' ? raw.description : '',
|
|
189
397
|
blocks,
|
|
190
|
-
jsonSchema:
|
|
398
|
+
jsonSchema: {},
|
|
191
399
|
})
|
|
192
400
|
}
|
|
193
401
|
|
|
@@ -255,7 +463,3 @@ export function createEmptyBlock(type: FormBlockType): FormBlock {
|
|
|
255
463
|
|
|
256
464
|
return block
|
|
257
465
|
}
|
|
258
|
-
|
|
259
|
-
function isOptionsBlockType(type: FormBlockType): boolean {
|
|
260
|
-
return type === 'select' || type === 'multiselect' || type === 'radio' || type === 'checkbox'
|
|
261
|
-
}
|
package/src/index.ts
CHANGED
|
@@ -4,13 +4,17 @@ export type {
|
|
|
4
4
|
A2uiComponentNode,
|
|
5
5
|
A2uiSurfaceDoc,
|
|
6
6
|
FormBlock,
|
|
7
|
+
FormBlockCondition,
|
|
7
8
|
FormBlockOption,
|
|
8
9
|
FormBlockType,
|
|
10
|
+
FormCaseFilter,
|
|
11
|
+
FormConditionOperator,
|
|
9
12
|
FormDefinitionPayload,
|
|
10
13
|
FormDetailResult,
|
|
11
14
|
FormFilePlaceholderIcon,
|
|
12
15
|
FormJsonSchema,
|
|
13
16
|
FormMediaSize,
|
|
17
|
+
FormResumeFilter,
|
|
14
18
|
FormSchema,
|
|
15
19
|
SubmitMode,
|
|
16
20
|
} from './types/index'
|
|
@@ -18,9 +22,12 @@ export type {
|
|
|
18
22
|
export {
|
|
19
23
|
A2UI_PROTOCOL_VERSION,
|
|
20
24
|
FORM_MEDIA_SIZES,
|
|
25
|
+
isDisplayBlockType,
|
|
21
26
|
isInputBlockType,
|
|
22
27
|
isLayoutBlockType,
|
|
23
28
|
isMediaBlockType,
|
|
29
|
+
isOptionsBlockType,
|
|
30
|
+
supportsDefaultValue,
|
|
24
31
|
} from './types/index'
|
|
25
32
|
|
|
26
33
|
export {
|
|
@@ -37,7 +44,16 @@ export {
|
|
|
37
44
|
resolveSurfaceFromFormDefinition,
|
|
38
45
|
} from './adapter/resolveSurface'
|
|
39
46
|
|
|
40
|
-
export {
|
|
47
|
+
export {
|
|
48
|
+
blocksToJsonSchema,
|
|
49
|
+
coerceToggleValue,
|
|
50
|
+
createEmptyBlock,
|
|
51
|
+
createEmptyFormDefinition,
|
|
52
|
+
normalizeFormDefinition,
|
|
53
|
+
normalizeMultiselectCount,
|
|
54
|
+
resolveSchemaDefaultValue,
|
|
55
|
+
syncFormDefinition,
|
|
56
|
+
} from './adapter/formSchema'
|
|
41
57
|
|
|
42
58
|
export { extractSurfaceValues } from './adapter/extractSurfaceValues'
|
|
43
59
|
|
|
@@ -144,6 +160,4 @@ export {
|
|
|
144
160
|
type CaseSearchResult,
|
|
145
161
|
} from './catalog/caseSearchContext'
|
|
146
162
|
|
|
147
|
-
export type { FormResumeFilter, FormCaseFilter } from './types/index'
|
|
148
|
-
|
|
149
163
|
import './styles/index.css'
|
|
@@ -235,6 +235,43 @@ describe('intersectPayloadBlocksWithForm', () => {
|
|
|
235
235
|
expect(result.matchedBlocks[0]?.defaultValue).toBe('hello')
|
|
236
236
|
})
|
|
237
237
|
|
|
238
|
+
it('keeps form caseFilter when ask omits caseFilter key', () => {
|
|
239
|
+
const form: FormSchema = {
|
|
240
|
+
title: 'Form',
|
|
241
|
+
description: '',
|
|
242
|
+
blocks: [
|
|
243
|
+
{
|
|
244
|
+
id: '1',
|
|
245
|
+
type: 'case_multiselect',
|
|
246
|
+
name: 'field_aaa56f6c',
|
|
247
|
+
caseMinCount: 1,
|
|
248
|
+
caseMaxCount: 1,
|
|
249
|
+
caseFilter: { agentKind: 'business', flowUniqueIds: [], pageSize: 20 },
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
jsonSchema: {},
|
|
253
|
+
}
|
|
254
|
+
const payloadDef = parsePayloadBlocksJson({
|
|
255
|
+
title: 'Ask',
|
|
256
|
+
blocks: [
|
|
257
|
+
{
|
|
258
|
+
id: 'p1',
|
|
259
|
+
type: 'case_multiselect',
|
|
260
|
+
name: 'field_aaa56f6c',
|
|
261
|
+
caseEnableRefresh: true,
|
|
262
|
+
},
|
|
263
|
+
],
|
|
264
|
+
})!
|
|
265
|
+
const result = intersectPayloadBlocksWithForm(payloadDef, form)
|
|
266
|
+
expect(result.matchedBlocks[0]?.caseFilter).toMatchObject({
|
|
267
|
+
agentKind: 'business',
|
|
268
|
+
flowUniqueIds: [],
|
|
269
|
+
pageSize: 20,
|
|
270
|
+
})
|
|
271
|
+
expect(result.matchedBlocks[0]?.caseMinCount).toBe(1)
|
|
272
|
+
expect(result.matchedBlocks[0]?.caseMaxCount).toBe(1)
|
|
273
|
+
})
|
|
274
|
+
|
|
238
275
|
it('overlays ask caseFilter over form caseFilter', () => {
|
|
239
276
|
const form: FormSchema = {
|
|
240
277
|
title: 'Form',
|