@skopon-cool/form-sdk 0.4.7 → 0.4.9

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.
@@ -9,7 +9,7 @@ export type PayloadBlocksDefinition = Pick<FormSchema, 'title' | 'description' |
9
9
  export interface PayloadBlocksIntersection {
10
10
  matchedBlocks: FormBlock[];
11
11
  extraBlocks: FormBlock[];
12
- /** 按 payload 顺序:layout + matched input(不含 extra input) */
12
+ /** 按 payload 顺序:layout/media + matched input(不含 extra input) */
13
13
  renderBlocks: FormBlock[];
14
14
  title: string;
15
15
  description: string;
@@ -25,7 +25,7 @@ export declare function intersectPayloadBlocksWithForm(payloadDef: PayloadBlocks
25
25
  export declare function extractExtraBlockValues(extraBlocks: FormBlock[]): Record<string, unknown>;
26
26
  /** payload 是否含至少一个具 name 的 input 块(可用于卡片 fallback) */
27
27
  export declare function payloadHasInputBlocks(payloadDef: PayloadBlocksDefinition): boolean;
28
- /** 交集为空时 fallback:payload 中可上屏的 blocks(layout + 非 hidden input) */
28
+ /** 交集为空时 fallback:payload 中可上屏的 blocks(layout/media + 非 hidden input) */
29
29
  export declare function getPayloadRenderableBlocks(payloadDef: PayloadBlocksDefinition): FormBlock[];
30
30
  /** payload 中所有 input 块 field name(fallback 提交用,含 hidden) */
31
31
  export declare function getPayloadInputFieldNames(payloadDef: PayloadBlocksDefinition): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"intersectPayloadBlocksWithForm.d.ts","sourceRoot":"","sources":["../../src/submit/intersectPayloadBlocksWithForm.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAG3D,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,aAAa,GAAG,QAAQ,CAAC,GAAG;IAC3F;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,EAAE,CAAA;CACxB,CAAA;AAED,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,SAAS,EAAE,CAAA;IAC1B,WAAW,EAAE,SAAS,EAAE,CAAA;IACxB,0DAA0D;IAC1D,YAAY,EAAE,SAAS,EAAE,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;CACpB;AA8ED,uEAAuE;AACvE,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,uBAAuB,GAAG,IAAI,CAmBvF;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,UAAU,EAAE,uBAAuB,EACnC,cAAc,EAAE,UAAU,GAAG,SAAS,GACrC,yBAAyB,CA+B3B;AA+BD,2CAA2C;AAC3C,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzF;AAED,sDAAsD;AACtD,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,uBAAuB,GAAG,OAAO,CAIlF;AAED,mEAAmE;AACnE,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,uBAAuB,GAAG,SAAS,EAAE,CAO3F;AAED,4DAA4D;AAC5D,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,uBAAuB,GAAG,MAAM,EAAE,CAIvF;AAED,6DAA6D;AAC7D,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,uBAAuB,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB"}
1
+ {"version":3,"file":"intersectPayloadBlocksWithForm.d.ts","sourceRoot":"","sources":["../../src/submit/intersectPayloadBlocksWithForm.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAG3D,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,aAAa,GAAG,QAAQ,CAAC,GAAG;IAC3F;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,EAAE,CAAA;CACxB,CAAA;AAED,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,SAAS,EAAE,CAAA;IAC1B,WAAW,EAAE,SAAS,EAAE,CAAA;IACxB,gEAAgE;IAChE,YAAY,EAAE,SAAS,EAAE,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;CACpB;AA+ED,uEAAuE;AACvE,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,uBAAuB,GAAG,IAAI,CAmBvF;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,UAAU,EAAE,uBAAuB,EACnC,cAAc,EAAE,UAAU,GAAG,SAAS,GACrC,yBAAyB,CA+B3B;AA+BD,2CAA2C;AAC3C,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzF;AAED,sDAAsD;AACtD,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,uBAAuB,GAAG,OAAO,CAIlF;AAED,yEAAyE;AACzE,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,uBAAuB,GAAG,SAAS,EAAE,CAO3F;AAED,4DAA4D;AAC5D,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,uBAAuB,GAAG,MAAM,EAAE,CAIvF;AAED,6DAA6D;AAC7D,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,uBAAuB,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.4.7",
6
+ "version": "0.4.9",
7
7
  "description": "Skopon form rendering SDK (A2UI + form_definition) with submit helpers",
8
8
  "type": "module",
9
9
  "sideEffects": [
@@ -14,6 +14,20 @@ function readString(value: unknown): string {
14
14
  return typeof value === 'string' ? value : ''
15
15
  }
16
16
 
17
+ /** 与 formSchema.normalizeFlowUniqueIds 对齐:兼容数组 / JSON 数组字符串。 */
18
+ function readFlowUniqueIds(raw: unknown): string[] {
19
+ if (Array.isArray(raw)) return raw.map(String).filter(Boolean)
20
+ if (typeof raw === 'string' && raw.trim()) {
21
+ try {
22
+ const parsed: unknown = JSON.parse(raw)
23
+ if (Array.isArray(parsed)) return parsed.map(String).filter(Boolean)
24
+ } catch {
25
+ /* ignore */
26
+ }
27
+ }
28
+ return []
29
+ }
30
+
17
31
  function readCaseFilter(raw: unknown): FormCaseFilter {
18
32
  if (!raw || typeof raw !== 'object') {
19
33
  return { flowUniqueIds: [], pageSize: 20 }
@@ -40,9 +54,7 @@ function readCaseFilter(raw: unknown): FormCaseFilter {
40
54
  typeof rec.category === 'string' && rec.category.trim()
41
55
  ? rec.category.trim()
42
56
  : undefined
43
- const flowUniqueIds = Array.isArray(rec.flowUniqueIds)
44
- ? rec.flowUniqueIds.map(String).filter(Boolean)
45
- : []
57
+ const flowUniqueIds = readFlowUniqueIds(rec.flowUniqueIds)
46
58
  return { agentKind, agentUniqueId, flowType, category, flowUniqueIds, pageSize }
47
59
  }
48
60
 
@@ -1,6 +1,7 @@
1
1
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
2
2
  import { Button, Spin, Tag, Tooltip } from 'antd'
3
3
  import type { FormDetailResult, FormSchema, SubmitMode } from '../types/index'
4
+ import { isInputBlockType } from '../types/index'
4
5
  import {
5
6
  resolveRealtimeWsUrl,
6
7
  resolveSubmitAuthHeaders,
@@ -213,7 +214,7 @@ function AskUserFormCardBody({
213
214
  const fieldNames = useMemo(
214
215
  () =>
215
216
  renderBlocks
216
- .filter((block) => block.name?.trim())
217
+ .filter((block) => isInputBlockType(block.type) && block.name?.trim())
217
218
  .map((block) => block.name!.trim()),
218
219
  [renderBlocks],
219
220
  )
@@ -355,10 +356,20 @@ function AskUserFormCardBody({
355
356
  return
356
357
  }
357
358
 
359
+ // form 必须是交集后的有效 schema(含 ask 动态 caseFilter),
360
+ // 不能传 vt_forms 原始 formDef,否则 flowUniqueIds 等会被编辑器默认冲掉。
361
+ const effectiveForm =
362
+ renderBlocks.length > 0
363
+ ? {
364
+ title: surfaceTitle,
365
+ description: surfaceDescription,
366
+ blocks: renderBlocks,
367
+ }
368
+ : (payloadDef ?? undefined)
358
369
  const body = buildAnswerAgentBody({
359
370
  context: resolvedAnswerAgentContext,
360
371
  payload,
361
- form: formDef ?? payloadDef,
372
+ form: effectiveForm,
362
373
  answer,
363
374
  })
364
375
  const agentError = validateAnswerAgentBody(body)
@@ -388,6 +399,8 @@ function AskUserFormCardBody({
388
399
  submitting,
389
400
  fieldNames,
390
401
  renderBlocks,
402
+ surfaceTitle,
403
+ surfaceDescription,
391
404
  extraValues,
392
405
  reportSnapshot,
393
406
  runtime,
@@ -396,7 +409,6 @@ function AskUserFormCardBody({
396
409
  resolvedSubmitHeaders,
397
410
  resolvedAnswerAgentContext,
398
411
  payload,
399
- formDef,
400
412
  payloadDef,
401
413
  ])
402
414
 
@@ -1,6 +1,6 @@
1
1
  import { normalizeFormDefinition } from '../adapter/formSchema'
2
2
  import type { FormBlock, FormSchema } from '../types/index'
3
- import { isInputBlockType, isLayoutBlockType } from '../types/index'
3
+ import { isDisplayBlockType, isInputBlockType } from '../types/index'
4
4
 
5
5
  export type PayloadBlocksDefinition = Pick<FormSchema, 'title' | 'description' | 'blocks'> & {
6
6
  /**
@@ -13,7 +13,7 @@ export type PayloadBlocksDefinition = Pick<FormSchema, 'title' | 'description' |
13
13
  export interface PayloadBlocksIntersection {
14
14
  matchedBlocks: FormBlock[]
15
15
  extraBlocks: FormBlock[]
16
- /** 按 payload 顺序:layout + matched input(不含 extra input) */
16
+ /** 按 payload 顺序:layout/media + matched input(不含 extra input) */
17
17
  renderBlocks: FormBlock[]
18
18
  title: string
19
19
  description: string
@@ -46,7 +46,8 @@ function buildRenderBlocks(
46
46
 
47
47
  const renderBlocks: FormBlock[] = []
48
48
  for (const payloadBlock of payloadDef.blocks) {
49
- if (isLayoutBlockType(payloadBlock.type)) {
49
+ // layout / media 按 payload 原样上屏(ask 动态 mediaUrls 必须保留)
50
+ if (isDisplayBlockType(payloadBlock.type)) {
50
51
  renderBlocks.push(normalizePayloadBlock(payloadBlock))
51
52
  continue
52
53
  }
@@ -205,10 +206,10 @@ export function payloadHasInputBlocks(payloadDef: PayloadBlocksDefinition): bool
205
206
  )
206
207
  }
207
208
 
208
- /** 交集为空时 fallback:payload 中可上屏的 blocks(layout + 非 hidden input) */
209
+ /** 交集为空时 fallback:payload 中可上屏的 blocks(layout/media + 非 hidden input) */
209
210
  export function getPayloadRenderableBlocks(payloadDef: PayloadBlocksDefinition): FormBlock[] {
210
211
  return payloadDef.blocks.filter((block) => {
211
- if (isLayoutBlockType(block.type)) return true
212
+ if (isDisplayBlockType(block.type)) return true
212
213
  if (!isInputBlockType(block.type) || !block.name?.trim()) return false
213
214
  // hidden text 不上屏;提交值由 getPayloadHiddenBlockValues / dataModel 补齐
214
215
  return !isHiddenTextBlock(block)