diff --git a/packages/fx-core/src/component/generator/apiSpec/helper.ts b/packages/fx-core/src/component/generator/apiSpec/helper.ts index ac23d879c7..0f29d542c1 100644 --- a/packages/fx-core/src/component/generator/apiSpec/helper.ts +++ b/packages/fx-core/src/component/generator/apiSpec/helper.ts @@ -1071,7 +1071,7 @@ async function updateAdaptiveCardForCustomApi( for (const item of specItems) { const name = item.item.operationId!.replace(/[^a-zA-Z0-9]/g, "_"); - const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(item.item, true); + const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(item.item, true, 5); if (jsonPath !== "$" && card.body && card.body[0] && (card.body[0] as any).$data) { (card.body[0] as any).$data = `\${${jsonPath}}`; } diff --git a/packages/spec-parser/src/adaptiveCardGenerator.ts b/packages/spec-parser/src/adaptiveCardGenerator.ts index 5059fadfc4..bdade08658 100644 --- a/packages/spec-parser/src/adaptiveCardGenerator.ts +++ b/packages/spec-parser/src/adaptiveCardGenerator.ts @@ -17,7 +17,8 @@ import { SpecParserError } from "./specParserError"; export class AdaptiveCardGenerator { static generateAdaptiveCard( operationItem: OpenAPIV3.OperationObject, - allowMultipleMediaType = false + allowMultipleMediaType = false, + maxElementCount: number = Number.MAX_SAFE_INTEGER ): [AdaptiveCard, string] { try { const { json } = Utils.getResponseJson(operationItem, allowMultipleMediaType); @@ -32,7 +33,7 @@ export class AdaptiveCardGenerator { schema = schema.properties![jsonPath] as OpenAPIV3.SchemaObject; } - cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, ""); + cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "", "", maxElementCount); } // if no schema, try to use example value @@ -73,11 +74,17 @@ export class AdaptiveCardGenerator { static generateCardFromResponse( schema: OpenAPIV3.SchemaObject, name: string, - parentArrayName = "" + parentArrayName = "", + maxElementCount = Number.MAX_SAFE_INTEGER, + counter: { count: number } = { count: 0 } ): Array { + if (counter.count >= maxElementCount) { + return []; + } if (schema.type === "array") { // schema.items can be arbitrary object: schema { type: array, items: {} } if (Object.keys(schema.items).length === 0) { + counter.count++; return [ { type: ConstantString.TextBlockType, @@ -90,8 +97,11 @@ export class AdaptiveCardGenerator { const obj = AdaptiveCardGenerator.generateCardFromResponse( schema.items as OpenAPIV3.SchemaObject, "", - name + name, + maxElementCount, + counter ); + const template = { type: ConstantString.ContainerType, $data: name ? `\${${name}}` : "${$root}", @@ -101,6 +111,7 @@ export class AdaptiveCardGenerator { template.items.push(...obj); return [template]; } + // some schema may not contain type but contain properties if (Utils.isObjectSchema(schema)) { const { properties } = schema; @@ -109,7 +120,9 @@ export class AdaptiveCardGenerator { const obj = AdaptiveCardGenerator.generateCardFromResponse( properties[property] as OpenAPIV3.SchemaObject, name ? `${name}.${property}` : property, - parentArrayName + parentArrayName, + maxElementCount, + counter ); result.push(...obj); } @@ -127,6 +140,7 @@ export class AdaptiveCardGenerator { schema.type === "boolean" || schema.type === "number" ) { + counter.count++; if (!AdaptiveCardGenerator.isImageUrlProperty(schema, name, parentArrayName)) { // string in root: "ddd" let text = "result: ${$root}"; @@ -150,23 +164,18 @@ export class AdaptiveCardGenerator { }, ]; } else { - if (name) { - return [ - { - type: "Image", - url: `\${${name}}`, - $when: `\${${name} != null && ${name} != ''}`, - }, - ]; - } else { - return [ - { - type: "Image", - url: "${$data}", - $when: "${$data != null && $data != ''}", - }, - ]; - } + const url = name ? `\${${name}}` : "${$data}"; + const condition = name + ? `\${${name} != null && ${name} != ''}` + : "${$data != null && $data != ''}"; + + return [ + { + type: "Image", + url, + $when: condition, + }, + ]; } } diff --git a/packages/spec-parser/src/manifestUpdater.ts b/packages/spec-parser/src/manifestUpdater.ts index ed7dc354da..d0605d3717 100644 --- a/packages/spec-parser/src/manifestUpdater.ts +++ b/packages/spec-parser/src/manifestUpdater.ts @@ -220,10 +220,12 @@ export class ManifestUpdater { try { const { json } = Utils.getResponseJson(operationItem); if (json.schema) { - const [card, jsonPath] = - AdaptiveCardGenerator.generateAdaptiveCard(operationItem); + const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard( + operationItem, + false, + 5 + ); - card.body = Utils.limitACBodyProperties(card.body, 5); const responseSemantic = wrapResponseSemantics(card, jsonPath); funcObj.capabilities = { response_semantics: responseSemantic, diff --git a/packages/spec-parser/src/utils.ts b/packages/spec-parser/src/utils.ts index d49263fb9a..b0b1875590 100644 --- a/packages/spec-parser/src/utils.ts +++ b/packages/spec-parser/src/utils.ts @@ -468,35 +468,4 @@ export class Utils { return serverUrl; } - - static limitACBodyProperties(body: AdaptiveCardBody, maxCount: number): AdaptiveCardBody { - const result: AdaptiveCardBody = []; - let currentCount = 0; - - for (const element of body) { - if (element.type === ConstantString.ContainerType) { - const items = this.limitACBodyProperties( - (element as ArrayElement).items, - maxCount - currentCount - ); - - result.push({ - type: ConstantString.ContainerType, - $data: (element as ArrayElement).$data, - items: items, - }); - - currentCount += items.length; - } else { - result.push(element); - currentCount++; - } - - if (currentCount >= maxCount) { - break; - } - } - - return result; - } } diff --git a/packages/spec-parser/test/adaptiveCardGenerator.test.ts b/packages/spec-parser/test/adaptiveCardGenerator.test.ts index 223cb2abd6..459d041c3d 100644 --- a/packages/spec-parser/test/adaptiveCardGenerator.test.ts +++ b/packages/spec-parser/test/adaptiveCardGenerator.test.ts @@ -462,11 +462,7 @@ describe("adaptiveCardGenerator", () => { }, ]; - const actual = AdaptiveCardGenerator.generateCardFromResponse( - schema as any, - name, - parentArrayName - ); + const actual = AdaptiveCardGenerator.generateCardFromResponse(schema as any, name); expect(actual).to.deep.equal(expected); });