UNPKG

adaptivecards-templating

Version:

Adaptive Card data binding and templating engine for JavaScript

184 lines (166 loc) 5.52 kB
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. import { IAdaptiveCard, ICardElement, IChoiceSetInput, IContainer, INumberInput, ITextInput, ITimeInput, IToggleInput } from 'adaptivecards/src/schema'; import { JSONSchema7, JSONSchema7Definition, JSONSchema7Type } from 'json-schema'; // JSON Schema Card // generates an Adaptive Card given a JSON schema export function JSONSchemaCard(schema: JSONSchema7): IAdaptiveCard | undefined { try { return { type: "AdaptiveCard", body: [ JSONSchemaCardObject(schema, '', 0), ], } } catch (e) { console.error(e); return undefined; } } // JSON Schema Elements function JSONSchemaCardElement(schema: JSONSchema7Definition, path: string, depth: number): ICardElement { if (typeof (schema) === "boolean") return null; switch (schema.type) { case "array": if (Array.isArray(schema.items)) { return JSONSchemaCardTuple(schema, path, depth); } else { return JSONSchemaCardList(schema, path, depth); } case "object": return JSONSchemaCardObject(schema, path, depth); case "boolean": return JSONSchemaCardBoolean(schema, path) case "integer": case "number": return JSONSchemaCardNumber(schema, path) case "string": if (schema.enum) { return JSONSchemaCardChoiceSet(schema, path) } else { return JSONSchemaCardText(schema, path) } case "date-time": case "time": case "date": return JSONSchemaCardTime(schema, path) default: return null; } } function encodeProperty(property: string) { return encodeURIComponent(property).replace('.', '%2e') } function textSizeAtDepth(depth: number) { switch (depth) { case 0: "large" case 1: "medium" default: "small" } } function JSONSchemaFieldTitle(schema: JSONSchema7, path: string, depth: number): ICardElement[] { return [ schema.title ? { type: "TextBlock", size: textSizeAtDepth(depth), text: schema.title, } : null, schema.description ? { type: "TextBlock", size: textSizeAtDepth(depth + 1), isSubtle: true, wrap: true, text: schema.description, } : null, ] } function JSONSchemaCardTuple(schema: JSONSchema7, path: string, depth: number): IContainer { if (!Array.isArray(schema.items)) return null; return { type: "Container", items: [ ...JSONSchemaFieldTitle(schema, path, depth), ...schema.items?.map((item: JSONSchema7Definition, idx: number) => { return JSONSchemaCardElement(item, `${path}[${idx}]`, depth + 1) }) ?? [], ], } } function JSONSchemaCardList(schema: JSONSchema7, path: string, depth: number): IContainer { return { type: "Container", items: [ ...JSONSchemaFieldTitle(schema, path, depth), // TODO not implemented ], } } function JSONSchemaCardObject(schema: JSONSchema7, path: string, depth: number): IContainer { return { type: "Container", items: [ ...JSONSchemaFieldTitle(schema, path, depth), ...schema.required?.map((property: string) => { return JSONSchemaCardElement(schema.properties[property], `${path}.${encodeProperty(property)}`, depth + 1) }) ?? [], ], } } function JSONSchemaCardBoolean(schema: JSONSchema7, path: string): IToggleInput { return { type: "Input.Toggle", id: path, title: schema.title, label: schema.description, value: schema.default as string, } } function JSONSchemaCardNumber(schema: JSONSchema7, path: string): INumberInput { return { type: "Input.Number", id: path, title: schema.title, placeholder: schema.description, value: schema.default as string, min: schema.exclusiveMinimum ?? schema.minimum, max: schema.exclusiveMaximum ?? schema.maximum, } } function JSONSchemaCardChoiceSet(schema: JSONSchema7, path: string): IChoiceSetInput { return { type: "Input.ChoiceSet", id: path, title: schema.title, choices: schema.enum.map((item: JSONSchema7Type) => { return { title: item as string, value: item as string, } }), placeholder: schema.description, value: schema.default as string, } } function JSONSchemaCardText(schema: JSONSchema7, path: string): ITextInput { return { type: "Input.Text", id: path, title: schema.title, placeholder: schema.description, value: schema.default as string, maxLength: schema.maxLength, regex: schema.pattern, } } function JSONSchemaCardTime(schema: JSONSchema7, path: string): ITimeInput { return { type: "Input.Time", id: path, title: schema.title, placeholder: schema.description, value: schema.default as string, } }