UNPKG

antd-schema

Version:

799 lines (792 loc) 34.3 kB
import { withErrorBoundary } from 'react-error-boundary'; import { z, string } from 'zod'; import { search } from 'jmespath'; import { Card, Descriptions, Flex, Form, Col, Row, Typography, InputNumber, Input, Select, Table, Skeleton, DatePicker } from 'antd'; import { saveAs } from 'file-saver'; import { useState, useEffect, useRef } from 'react'; import { createPortal } from 'react-dom'; import { PermissionButton, InfiniteList, QueryList, useToolkitsStore, useModal } from 'react-toolkits'; import { create } from 'zustand'; import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; import dayjs2, { extend } from 'dayjs'; import utcPlugin from 'dayjs/plugin/utc'; import { isPlainObject, merge } from 'lodash-es'; import qs from 'query-string'; // src/index.tsx var baseSchema = z.object({ type: z.string().describe("\u7EC4\u4EF6\u7C7B\u578B"), storeId: z.string().optional().describe( "\u5B58\u50A8 ID\u3002\u7528\u4E8E\u5B58\u50A8\u8868\u5355\u7F16\u8F91\u3001Service \u7EC4\u4EF6(\u76EE\u524D\u672A\u652F\u6301) \u53D1\u8D77 HTTP \u8BF7\u6C42\u4EA7\u751F\u7684\u503C\u3002\u7EC4\u4EF6\u95F4\u4EA4\u4E92\u65F6\u7528\u5230\uFF0C\u6570\u636E\u4F1A\u4EE5\u6B64 ID \u4F5C\u4E3A key \u5B58\u50A8\u5230 Map \u4E2D\u3002" ), storeIdRef: z.string().optional().describe("\u5173\u8054\u7EC4\u4EF6\u7684 ID\uFF0C\u4F1A\u6839\u636E\u6B64 ID \u53BB store \u4E2D\u67E5\u627E\u6570\u636E\uFF0C\u5173\u8054\u7684\u6570\u636E\u4F1A\u53EF\u4EE5\u88AB\u7EC4\u4EF6\u8BBF\u95EE\u3002") }); var buttonSchema = baseSchema.extend({ type: z.literal("button"), code: z.string().optional().describe("\u6743\u9650\u7F16\u53F7"), buttonType: z.enum(["primary", "default", "dashed", "link", "text"]).optional().describe("\u6309\u94AE\u7C7B\u578B\uFF0C\u5F71\u54CD\u6309\u94AE\u7684\u663E\u793A\u6837\u5F0F"), action: z.enum(["modal", "download"]).optional(), text: z.string().optional(), data: z.any().optional().describe("\u81EA\u5B9A\u4E49\u6570\u636E"), method: z.enum(["GET", "POST"]).optional().describe("\u8BF7\u6C42\u65B9\u6CD5\uFF0C\u9ED8\u8BA4 GET"), url: string().optional().describe("\u8BF7\u6C42\u5730\u5740"), params: z.record(z.string(), z.any()).optional().describe("\u8BF7\u6C42\u65F6\u643A\u5E26\u7684\u8BF7\u6C42\u53C2\u6570"), body: z.record(z.string(), z.any()).optional().describe("\u8BF7\u6C42\u643A\u5E26\u7684\u8BF7\u6C42\u4F53"), showLoading: z.boolean().default(true).describe("\u662F\u5426\u663E\u793A\u52A0\u8F7D\u72B6\u6001"), modal: z.object({ title: z.string(), body: z.any().array().optional(), data: z.record(z.string(), z.any()).optional(), width: z.number().optional() }).optional() }).refine( (data) => { if (data.action === "download" && !data.url) { return false; } return true; }, { message: "When action is 'download', 'url' is required.", path: ["url"] } ).refine( (data) => { if (data.action === "modal" && !data.modal) { return false; } return true; }, { message: "When action is 'modal', 'modal' field is required.", path: ["modal"] } ); var baseCardSchema = baseSchema.extend({ type: z.literal("card"), title: z.string().optional(), extra: z.any().array().optional() }); var cardBodySchema = z.lazy(() => z.any().array()); var cardSchema = baseCardSchema.extend({ body: cardBodySchema.optional() }); var formItemSchema2 = baseSchema.extend({ label: z.string(), name: z.string(), preserve: z.boolean().optional(), span: z.number().optional().describe("\u6805\u683C\u5360\u4F4D\u683C\u6570"), rules: z.object({ type: z.enum(["string", "number", "boolean", "integer"]).optional().describe("\u5B57\u6BB5\u6570\u636E\u7C7B\u578B"), required: z.boolean().optional().describe("\u662F\u5426\u4E3A\u5FC5\u9009\u5B57\u6BB5"), message: z.string().optional().describe("\u9519\u8BEF\u4FE1\u606F\uFF0C\u4E0D\u8BBE\u7F6E\u65F6\u4F1A\u901A\u8FC7\u6A21\u677F\u81EA\u52A8\u751F\u6210"), min: z.number().optional().describe("\u5FC5\u987B\u8BBE\u7F6E type\uFF1Astring \u7C7B\u578B\u4E3A\u5B57\u7B26\u4E32\u6700\u5C0F\u957F\u5EA6\uFF1Bnumber \u7C7B\u578B\u65F6\u4E3A\u6700\u5C0F\u503C\uFF1Barray \u7C7B\u578B\u65F6\u4E3A\u6570\u7EC4\u6700\u5C0F\u957F\u5EA6"), max: z.number().optional().describe("\u5FC5\u987B\u8BBE\u7F6E type\uFF1Astring \u7C7B\u578B\u4E3A\u5B57\u7B26\u4E32\u6700\u5927\u957F\u5EA6\uFF1Bnumber \u7C7B\u578B\u65F6\u4E3A\u6700\u5927\u503C\uFF1Barray \u7C7B\u578B\u65F6\u4E3A\u6570\u7EC4\u6700\u5927\u957F\u5EA6") }).array().optional().describe("\u8868\u5355\u6821\u9A8C\u89C4\u5219") }); // src/schemas/date-picker.ts var datePickerSchema = formItemSchema2.extend({ type: z.literal("date-picker"), showTime: z.boolean().optional().describe("\u662F\u5426\u663E\u793A\u65F6\u95F4\u9009\u62E9\u5668"), showNow: z.boolean().optional().describe("\u663E\u793A\u5F53\u524D\u65E5\u671F\u65F6\u95F4\u7684\u5FEB\u6377\u9009\u62E9"), showWeek: z.boolean().optional().describe("\u5C55\u793A\u5F53\u524D\u5468"), utc: z.boolean().optional().describe("\u662F\u5426\u4F7F\u7528UTC\u65F6\u95F4") }); var dateRangeSchema = formItemSchema2.extend({ type: z.literal("date-range"), allowEmpty: z.tuple([z.boolean(), z.boolean()]).optional().describe("\u662F\u5426\u5141\u8BB8\u4E3A\u7A7A"), showTime: z.boolean().optional().describe("\u662F\u5426\u663E\u793A\u65F6\u95F4\u9009\u62E9\u5668"), utc: z.boolean().optional().describe("\u662F\u5426\u4F7F\u7528UTC\u65F6\u95F4") }).describe("\u65E5\u671F\u8303\u56F4\u9009\u62E9\u5668\u3002\u8BE5\u7EC4\u4EF6\u7684\u503C\u4E3A\u6570\u7EC4\u7C7B\u578B\uFF0C\u9700\u8981\u81EA\u5DF1\u505A\u6620\u5C04\u3002"); var descriptionsSchema = baseSchema.extend({ type: z.literal("descriptions"), title: z.string().optional().describe("\u6807\u9898"), dataIndex: z.string().optional().describe("JMESPath"), dataSource: z.any().optional().describe("\u6570\u636E\u6E90"), column: z.number().optional().describe("\u5217\u6570") }).describe("\u63CF\u8FF0\u5217\u8868\u7EC4\u4EF6\uFF0C\u7528\u4E8E\u5C55\u793A\u4E00\u7EC4\u63CF\u8FF0\u4FE1\u606F"); baseSchema.extend({ type: z.literal("div"), body: z.any().array().optional().describe("\u5B50\u5143\u7D20"), style: z.record(z.string(), z.any()).optional().describe("\u6837\u5F0F") }); var flexSchema = baseSchema.extend({ type: z.literal("flex"), vertical: z.boolean().optional().describe("flex \u4E3B\u8F74\u7684\u65B9\u5411\u662F\u5426\u5782\u76F4\uFF0C\u4F7F\u7528 flex-direction: column"), wrap: z.boolean().optional().describe("\u8BBE\u7F6E\u5143\u7D20\u5355\u884C\u663E\u793A\u8FD8\u662F\u591A\u884C\u663E\u793A"), justify: z.enum(["flex-start", "center", "flex-end", "space-between", "space-around", "space-evenly"]).optional().describe("\u8BBE\u7F6E\u5143\u7D20\u5728\u4E3B\u8F74\u65B9\u5411\u4E0A\u7684\u5BF9\u9F50\u65B9\u5F0F"), align: z.enum(["flex-start", "center", "flex-end", "baseline", "stretch"]).optional().describe("\u8BBE\u7F6E\u5143\u7D20\u5728\u4EA4\u53C9\u8F74\u65B9\u5411\u4E0A\u7684\u5BF9\u9F50\u65B9\u5F0F"), gap: z.union([z.number(), z.string()]).optional().describe("\u8BBE\u7F6E\u7F51\u683C\u4E4B\u95F4\u7684\u95F4\u9699"), body: z.any().array().optional().describe("\u5B50\u5143\u7D20"), style: z.record(z.string(), z.any()).optional().describe("\u6837\u5F0F") }); var formSchema = baseSchema.extend({ type: z.literal("form"), name: z.string().optional(), preserve: z.boolean().optional(), fields: z.any().array().optional().describe("\u8868\u5355\u9879\u914D\u7F6E"), initialValues: z.record(z.string(), z.any()).optional().describe("\u8BBE\u7F6E\u8868\u5355\u7684\u521D\u59CB\u503C"), layout: z.union([z.literal("horizontal"), z.literal("inline"), z.literal("vertical")]).default("horizontal").describe("\u8868\u5355\u5E03\u5C40"), labelWidth: z.union([z.number(), z.string()]).optional().describe("\u6807\u7B7E\u5BBD\u5EA6\uFF0C\u5F53\u4E3A\u6570\u5B57\u65F6\u8868\u793A\u5728 24 \u5217\u7684\u6805\u683C\u4E2D\u5360\u636E\u591A\u5C11\u5217\uFF0C\u5F53\u4E3A string \u65F6\u4F7F\u7528 flex \u5E03\u5C40"), labelAlign: z.enum(["left", "right"]).optional().describe("\u6807\u7B7E\u5BF9\u9F50\u65B9\u5F0F"), clearOnDestroy: z.boolean().optional().describe("\u5F53\u8868\u5355\u88AB\u5378\u8F7D\u65F6\u6E05\u7A7A\u8868\u5355\u503C"), gutter: z.union([ z.number().describe("\u6A2A\u5411\u95F4\u9694"), z.tuple([z.number().describe("\u6A2A\u5411\u95F4\u9694"), z.number().describe("\u7EB5\u5411\u95F4\u9694")]) ]).default(10).describe("Grid \u6805\u683C\u95F4\u9694") }); var tableSchema = baseSchema.extend({ type: z.literal("table"), rowKey: z.string().optional().describe("\u8868\u683C\u884C key \u7684\u53D6\u503C\uFF0C\u552F\u4E00\u6807\u8BC6"), columns: z.object({ title: z.string(), dataIndex: z.string().optional().describe("\u6570\u636E\u6E90\u7684\u5B57\u6BB5\u540D\uFF0C\u652F\u6301\u70B9\u8BED\u6CD5"), width: z.union([z.number(), z.string()]).optional(), align: z.enum(["left", "right", "center"]).optional(), tpl: z.string().optional().describe("\u6A21\u677F\u5B57\u7B26\u4E32\u3002\u652F\u6301\u6A21\u677F\u5B57\u7B26\u4E32\uFF0C\u53EF\u4EE5\u5728\u6B64\u5904\u505A\u6570\u636E\u6620\u5C04\u3002(\u6682\u65F6\u4E0D\u652F\u6301)") }).array().optional().describe("\u8868\u683C\u5217\u914D\u7F6E"), footer: z.any().array().optional().describe("\u8868\u683C\u5E95\u90E8"), api: z.string().optional().describe("\u6570\u636E\u67E5\u8BE2\u5730\u5740\uFF0C\u53EA\u652F\u6301 GET \u8BF7\u6C42\uFF0C\u4F18\u5148\u7EA7\u9AD8\u4E8E data"), data: z.union([z.any().array(), z.string()]).optional().describe("\u8868\u683C\u6570\u636E\u6E90\uFF0C\u53EF\u4EE5\u662F\u6570\u7EC4\u6216\u8005\u53D8\u91CF\u3002"), bordered: z.boolean().optional(), size: z.enum(["small", "middle", "large"]).default("middle"), tableLayout: z.enum(["fixed", "auto"]).optional().describe("\u8868\u683C\u5143\u7D20\u7684 table-layout \u5C5E\u6027\uFF0C\u8BBE\u4E3A fixed \u8868\u793A\u5185\u5BB9\u4E0D\u4F1A\u5F71\u54CD\u5217\u7684\u5E03\u5C40"), pagination: z.union([ z.literal(false), z.object({ current: z.number().optional(), pageSize: z.number().optional(), total: z.number().optional() }) ]).default(false).describe("\u5206\u9875\u914D\u7F6E") }).describe("\u8868\u683C\u7EC4\u4EF6\uFF0C\u5982\u679C\u9700\u8981\u53D1\u8D77\u8BF7\u6C42\uFF0C\u5EFA\u8BAE\u4F7F\u7528 query-list\u3002"); // src/schemas/infinite-list.ts var infiniteListSchema = baseSchema.extend({ type: z.literal("infinite-list"), url: z.string(), params: z.record(z.string(), z.any()).optional().describe("\u67E5\u8BE2\u53C2\u6570\u3002\u652F\u6301\u6A21\u677F\u5B57\u7B26\u4E32\uFF0C\u53EF\u4EE5\u5728\u6B64\u5904\u505A\u6570\u636E\u6620\u5C04\u3002"), code: z.string().optional().describe("\u6743\u9650\u7F16\u53F7"), extra: z.any().array().optional().describe("\u8868\u683C\u989D\u5916\u914D\u7F6E"), actions: buttonSchema.array().optional().describe("\u8868\u683C\u64CD\u4F5C\u3002\u4F1A\u81EA\u52A8\u628A\u8BE5\u884C\u7684\u8868\u683C\u6570\u636E\u6CBF\u7740\u7EC4\u4EF6\u6811\u9010\u7EA7\u5F80\u4E0B\u4F20\u9012\u3002"), formLayout: formSchema.shape.layout, gutter: formSchema.shape.gutter, fields: formSchema.shape.fields, initialValues: formSchema.shape.initialValues, rowKey: tableSchema.shape.rowKey, tableLayout: tableSchema.shape.tableLayout, footer: tableSchema.shape.footer, columns: tableSchema.shape.columns }); var inputNumberSchema = formItemSchema2.extend({ type: z.literal("input-number"), clearable: z.boolean().optional(), min: z.number().optional(), max: z.number().optional(), step: z.number().optional(), width: z.string().default("100px").describe("\u5BBD\u5EA6"), controls: z.boolean().default(false).describe("\u662F\u5426\u4F7F\u7528\u63A7\u5236\u6309\u94AE") }); var inputTextSchema = formItemSchema2.extend({ type: z.literal("input-text"), clearable: z.boolean().optional() }); var linkSchema = baseSchema.extend({ type: z.literal("link"), text: z.string().optional(), href: z.string(), target: z.enum(["_blank", "_self", "_parent", "_top"]).default("_blank"), params: z.record(z.string(), z.any()).optional().describe("\u8DF3\u8F6C\u65F6\u643A\u5E26\u7684\u67E5\u8BE2\u53C2\u6570") }); var queryListSchema = baseSchema.extend({ type: z.literal("query-list"), url: z.string(), code: z.string().optional().describe("\u6743\u9650\u7F16\u53F7"), method: z.enum(["GET", "POST"]).default("GET"), onePage: z.boolean().optional(), headers: z.record(z.string(), z.any()).optional(), body: z.record(z.string(), z.any()).optional().describe("\u8BF7\u6C42\u4F53\u3002\u652F\u6301\u6A21\u677F\u5B57\u7B26\u4E32\uFF0C\u53EF\u4EE5\u5728\u6B64\u5904\u505A\u6570\u636E\u6620\u5C04\u3002"), params: z.record(z.string(), z.any()).optional().describe("\u67E5\u8BE2\u53C2\u6570\u3002\u652F\u6301\u6A21\u677F\u5B57\u7B26\u4E32\uFF0C\u53EF\u4EE5\u5728\u6B64\u5904\u505A\u6570\u636E\u6620\u5C04\u3002"), extra: z.any().array().optional().describe("\u8868\u683C\u989D\u5916\u914D\u7F6E"), actions: buttonSchema.array().optional().describe("\u8868\u683C\u64CD\u4F5C\u3002\u4F1A\u81EA\u52A8\u628A\u8BE5\u884C\u7684\u8868\u683C\u6570\u636E\u6CBF\u7740\u7EC4\u4EF6\u6811\u9010\u7EA7\u5F80\u4E0B\u4F20\u9012\u3002"), buttonsAlign: z.enum(["left", "right", "bottom"]).optional(), formLayout: formSchema.shape.layout, gutter: formSchema.shape.gutter, fields: formSchema.shape.fields, initialValues: formSchema.shape.initialValues, rowKey: tableSchema.shape.rowKey, tableLayout: tableSchema.shape.tableLayout, footer: tableSchema.shape.footer, columns: tableSchema.shape.columns }); var selectSchema = formItemSchema2.extend({ type: z.literal("select"), allowClear: z.boolean().optional().describe("\u662F\u5426\u663E\u793A\u6E05\u9664\u6309\u94AE"), virtual: z.boolean().optional().describe("\u662F\u5426\u5F00\u542F\u865A\u62DF\u6EDA\u52A8\uFF0C\u6570\u636E\u91CF\u5927\u65F6\u5F00\u542F\u53EF\u4EE5\u63D0\u9AD8\u6027\u80FD"), showSearch: z.boolean().optional().describe("\u662F\u5426\u53EF\u641C\u7D22"), width: z.string().default("100px").describe("\u5BBD\u5EA6"), options: z.array(z.object({ label: z.string(), value: z.string() })).optional().describe("\u9009\u9879\u5217\u8868"), optionFilterProp: z.string().default("label").describe("\u641C\u7D22\u8FC7\u6EE4\u5B57\u6BB5"), source: z.string().optional().describe("\u6570\u636E\u6E90") }); var serviceSchema = baseSchema.extend({ type: z.literal("service"), method: z.enum(["GET", "POST"]).optional(), url: z.string().optional(), params: z.record(z.string(), z.any()).optional(), body: z.any().optional() }).describe("\u6570\u636E\u8BF7\u6C42\u7EC4\u4EF6\uFF0C\u7528\u4E8E\u8C03\u7528\u5916\u90E8\u670D\u52A1\uFF0C\u652F\u6301 GET \u548C POST \u8BF7\u6C42\uFF0C\u8FD4\u56DE\u7684\u6570\u636E\u4F1A\u5B58\u50A8\u5230 store \u4E2D"); var spanSchema = baseSchema.extend({ type: z.literal("span"), text: z.string().describe("\u6587\u5B57\u8282\u70B9") }).describe("\u63D2\u5165 span \u6807\u7B7E\uFF0C\u7528\u4E8E\u8F93\u51FA\u6587\u5B57\u6216\u5B57\u7B26\u4E32\u6A21\u677F"); var viewportSchema = baseSchema.extend({ type: z.literal("viewport"), body: z.any().array().optional().describe("\u89C6\u7A97\u5185\u5BB9"), data: z.record(z.string(), z.any()).optional().describe("\u89C6\u7A97\u6570\u636E") }); // src/schemas/index.ts z.union([ buttonSchema, cardSchema, datePickerSchema, dateRangeSchema, flexSchema, formSchema, infiniteListSchema, inputNumberSchema, inputTextSchema, linkSchema, queryListSchema, selectSchema, serviceSchema, spanSchema, tableSchema, viewportSchema, descriptionsSchema ]); // src/constants/index.ts var STRING_VAR_REG = /^\${(.+)}$/; var useDataStore = create()(() => ({ dataMap: /* @__PURE__ */ new Map() })); var setStoreData = (key, value) => { useDataStore.setState((prev) => ({ dataMap: new Map(prev.dataMap).set(key, value) })); }; var getStoreData = (key) => { if (key) { return useDataStore.getState().dataMap.get(key); } }; function withParsedData(schema) { return function(WrappedComponent) { return (props) => { const { data, ...restProps } = props; const [parsedData, setParsedData] = useState(null); useEffect(() => { const parsed = schema.parse(data); setParsedData(parsed); }, [data]); if (!parsedData) { return null; } return /* @__PURE__ */ jsx(WrappedComponent, { ...restProps, parsedData }); }; }; } var ModalButtonRenderer = ({ data, source }) => { const { text, buttonType, modal, storeIdRef, storeId, method, url, params, body, ...rest } = data; const { axios } = useToolkitsStore((s) => s); const [content, setContent] = useState(null); const { show, modal: modalElement } = useModal({ title: modal?.title, content, width: modal?.width, destroyOnClose: true, afterOpen: async () => { setContent(/* @__PURE__ */ jsx(Skeleton, {})); let _content; if (url) { const response = await axios.request({ method, url, params: params && replaceValueWithJMESPath(getStoreData(storeIdRef), params), data: body && replaceValueWithJMESPath(getStoreData(storeIdRef), body) }); if (storeId) { setStoreData(storeId, response.data.data); } _content = renderSchemaArray(modal?.body, response.data.data); } else { _content = renderSchemaArray(modal?.body, source); } setContent(_content); } }); return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(PermissionButton, { ...rest, type: buttonType, onClick: show, children: text }), createPortal(modalElement, document.body) ] }); }; var DownloadButtonRenderer = ({ data }) => { const { text, buttonType, url, method, params, body, storeIdRef, action, ...rest } = data; const { dataMap } = useDataStore(); const { axios } = useToolkitsStore((s) => s); const onClick = async () => { const storeData = storeIdRef ? dataMap.get(storeIdRef) : null; const newUrl = url.replace(/\$\{([^}]+)\}/g, (_match, key) => search(storeData, key) ?? ""); const response = await axios({ url: newUrl, method, params, data: body, responseType: "blob" }); const header = response.headers?.["content-disposition"]; let filename = "unknown"; filename = header?.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)?.[1]; const blob = new Blob([response.data], { type: "charset=utf-8" }); saveAs(blob, filename); }; return /* @__PURE__ */ jsx(PermissionButton, { ...rest, type: buttonType, onClick, children: text }); }; var ButtonRenderer = withParsedData(buttonSchema)(({ parsedData, source }) => { const { action, code, text, buttonType, params, body, storeIdRef, showLoading } = parsedData; const { dataMap } = useDataStore(); const storeData = storeIdRef ? dataMap.get(storeIdRef) : null; const newParams = params && replaceValueWithJMESPath(storeData, params); const newBody = body && replaceValueWithJMESPath(storeData, body); const newData = { ...parsedData, params: newParams, body: newBody }; if (action === "modal") { return /* @__PURE__ */ jsx(ModalButtonRenderer, { data: newData, source }); } else if (action === "download") { return /* @__PURE__ */ jsx(DownloadButtonRenderer, { data: newData }); } return /* @__PURE__ */ jsx(PermissionButton, { code, type: buttonType, showLoading, children: text }); }); var CardRenderer = withParsedData(cardSchema)(({ parsedData, source }) => { const { title, body } = parsedData; const children = renderSchemaArray(body, source); return /* @__PURE__ */ jsx(Card, { title, children }); }); var UnixDatePicker = (props) => { const { value, onChange, utc, ...rest } = props; const internelValue = typeof value === "number" ? utc ? minusUtcOffset(dayjs2(value * 1e3)) : dayjs2(value * 1e3) : null; const onChangeHandler = (date) => { onChange?.(utc ? addUtcOffset(date).unix() : date.unix()); }; return /* @__PURE__ */ jsx(DatePicker, { ...rest, value: internelValue, onChange: onChangeHandler }); }; var UnixDatePicker_default = UnixDatePicker; extend(utcPlugin); var UnixRangePicker = (props) => { const { value, onChange, utc, ...rest } = props; const internelValue = [ value?.[0] ? utc ? minusUtcOffset(dayjs2(value[0] * 1e3)) : dayjs2(value[0] * 1e3) : null, value?.[1] ? utc ? minusUtcOffset(dayjs2(value[1] * 1e3)) : dayjs2(value[1] * 1e3) : null ]; const onChangeHandler = (range) => { onChange?.([ range?.[0] ? utc ? addUtcOffset(range[0]).unix() : range[0].unix() : null, range?.[1] ? utc ? addUtcOffset(range[1]).unix() : range[1].unix() : null ]); }; return /* @__PURE__ */ jsx(DatePicker.RangePicker, { ...rest, value: internelValue, onChange: onChangeHandler }); }; var UnixRangePicker_default = UnixRangePicker; function withFormItem(schema) { return function(getChildren) { return withParsedData(schema)(({ parsedData, ...restProps }) => { const { label, name, preserve, rules, ...childrenProps } = parsedData; return /* @__PURE__ */ jsx(Form.Item, { label, name, rules, preserve, ...restProps, children: getChildren(childrenProps) }); }); }; } var DatePickerRenderer = withFormItem(datePickerSchema)((childrenProps) => { return /* @__PURE__ */ jsx(UnixDatePicker_default, { ...childrenProps }); }); var DateRangeRenderer = withFormItem(dateRangeSchema)((childrenProps) => { return /* @__PURE__ */ jsx(UnixRangePicker_default, { ...childrenProps }); }); var DescriptionsRenderer = withParsedData(descriptionsSchema)(({ parsedData }) => { const { title, dataSource, dataIndex, storeIdRef, ...rest } = parsedData; const { dataMap } = useDataStore(); const [items, setItems] = useState([]); useEffect(() => { let _dataSource; if (typeof dataSource === "object") { _dataSource = dataSource; } else if (storeIdRef) { _dataSource = dataMap.get(storeIdRef); } _dataSource = dataIndex ? search(_dataSource, dataIndex) : _dataSource; const _items = _dataSource?.map( (item) => ({ key: item.label, label: item.label, children: item.value }) ); setItems(_items); }, [dataMap]); return /* @__PURE__ */ jsx(Descriptions, { ...rest, title, items }); }); var FlexRenderer = withParsedData(flexSchema)(({ parsedData, source }) => { const { body, style, ...rest } = parsedData; const children = renderSchemaArray(body, source); return /* @__PURE__ */ jsx(Flex, { ...rest, style, children }); }); var FormRenderer = withParsedData(formSchema)(({ parsedData, form, externalStoreId }) => { const [formInstance] = Form.useForm(); const _from = form || formInstance; const { storeId, fields, labelWidth, gutter, ...rest } = parsedData; const _storeId = storeId || externalStoreId; const children = fields?.map((item, index) => { const { type, span } = item; const RendererComponent = rendererMap[type]; if (RendererComponent) { const key = `${type}${index}`; return /* @__PURE__ */ jsx(Col, { span, children: /* @__PURE__ */ jsx(RendererComponent, { data: item }) }, key); } return null; }); const labelCol = typeof labelWidth === "number" ? { span: labelWidth } : { flex: labelWidth }; const onValuesChange = (_, values) => { if (_storeId) { setStoreData(_storeId, values); } }; return /* @__PURE__ */ jsx(Form, { ...rest, form: _from, labelCol, onValuesChange, children: /* @__PURE__ */ jsx(Row, { gutter, children }) }); }); var InfiniteListRenderer = withParsedData(infiniteListSchema)(({ parsedData }) => { const { storeId, columns, url, footer, actions, fields, gutter, initialValues, formLayout, params, extra, ...rest } = parsedData; const ref = useRef(null); const newColumns = columns ? [...columns] : []; newColumns.forEach((column) => { column.render = (value) => { if (isPlainObject(value)) { return /* @__PURE__ */ jsx(Typography.Paragraph, { style: { maxHeight: 200, overflow: "auto" }, children: /* @__PURE__ */ jsx("pre", { children: JSON.stringify(value, null, 2) }) }); } else if (typeof value === "string") { try { const obj = JSON.parse(value); if (isPlainObject(obj)) { return /* @__PURE__ */ jsx(Typography.Paragraph, { style: { maxHeight: 200, overflow: "auto" }, children: /* @__PURE__ */ jsx("pre", { children: JSON.stringify(obj, null, 2) }) }); } return value; } catch (error) { return value; } } else { return value; } }; }); if (actions) { newColumns.push({ title: "\u64CD\u4F5C", align: "center", render: (record) => renderSchemaArray(actions, record) }); } const renderForm = (form) => { const data = formSchema.parse({ type: "form", fields, initialValues, layout: formLayout, gutter }); return /* @__PURE__ */ jsx(FormRenderer, { data, form, externalStoreId: storeId }); }; const renderFooter = footer && (() => renderSchemaArray(footer, ref.current?.data)); const getRowKey = (data) => data?.rowKey; const getDataSource = (data) => data?.reduce((acc, curr) => acc.concat(curr?.rows ?? []), []) ?? []; const getHasMore = (data) => !!data?.hasMore; const getParams = (values, rowKey) => { if (params) { return merge( { rowKey }, replaceValueWithJMESPath(values, params) ); } else { return { ...values, rowKey }; } }; const tableExtra = renderSchemaArray(extra); return /* @__PURE__ */ jsx( InfiniteList, { ...rest, ref, url, columns: newColumns, footer: renderFooter, getRowKey, getDataSource, getHasMore, params: getParams, renderForm, tableExtra } ); }); var InputNumberRenderer = withFormItem(inputNumberSchema)((props) => { const { type, width, ...rest } = props; return /* @__PURE__ */ jsx(InputNumber, { ...rest, style: { width } }); }); var InputTextRenderer = withFormItem(inputTextSchema)((childrenProps) => { return /* @__PURE__ */ jsx(Input, { ...childrenProps }); }); var LinkRenderer = withParsedData(linkSchema)(({ parsedData }) => { const { type, href, params, text, ...rest } = parsedData; const url = qs.stringifyUrl({ url: href, query: params }); return /* @__PURE__ */ jsx("a", { href: url, ...rest, children: text }); }); var QueryListRenderer = withParsedData(queryListSchema)(({ parsedData }) => { const { storeId, fields, initialValues, formLayout, columns, params, body, footer, extra, gutter, actions, ...rest } = parsedData; const ref = useRef(null); const newColumns = columns ? [...columns] : []; newColumns.forEach((column) => { column.render = (value) => { if (isPlainObject(value)) { return /* @__PURE__ */ jsx(Typography.Paragraph, { style: { maxHeight: 200, overflow: "auto" }, children: /* @__PURE__ */ jsx("pre", { children: JSON.stringify(value, null, 2) }) }); } else if (typeof value === "string") { try { const obj = JSON.parse(value); if (isPlainObject(obj)) { return /* @__PURE__ */ jsx(Typography.Paragraph, { style: { maxHeight: 200, overflow: "auto" }, children: /* @__PURE__ */ jsx("pre", { children: JSON.stringify(obj, null, 2) }) }); } return value; } catch (error) { return value; } } else { return value; } }; }); if (actions) { newColumns.push({ title: "\u64CD\u4F5C", align: "center", render: (record) => renderSchemaArray(actions, record) }); } const renderForm = (form) => { const data = formSchema.parse({ type: "form", fields, initialValues, layout: formLayout, gutter }); return /* @__PURE__ */ jsx(FormRenderer, { data, form, externalStoreId: storeId }); }; const renderFooter = footer && (() => renderSchemaArray(footer, ref.current?.data)); const getDataSource = (data) => data?.rows; const getTotal = (data) => data?.total; const getParams = ({ page, size, formValue }) => { if (params) { return merge( { page, size }, replaceValueWithJMESPath(formValue, params) ); } else { return { ...formValue, page, size }; } }; const getBody = ({ page, size, formValue }) => { if (body) { return merge( { page, size }, replaceValueWithJMESPath(formValue, body) ); } else { return { ...formValue, page, size }; } }; const tableExtra = renderSchemaArray(extra); return /* @__PURE__ */ jsx( QueryList, { ...rest, ref, columns: newColumns, renderForm, footer: renderFooter, getDataSource, getTotal, params: getParams, body: getBody, tableExtra } ); }); var SelectRenderer = withFormItem(selectSchema)((childrenProps) => { const { type, options, source, width, ...rest } = childrenProps; const { axios } = useToolkitsStore((s) => s); const [internalOptions, setInternalOptions] = useState(); useEffect(() => { if (source) { axios.get(source).then((response) => { setInternalOptions(response.data?.data?.options); }).catch(() => { setInternalOptions([]); }); } else if (options) { setInternalOptions(options); } }, [source]); return /* @__PURE__ */ jsx(Select, { ...rest, options: internalOptions, style: { width } }); }); var ServiceRenderer = withParsedData(serviceSchema)(({ parsedData }) => { const { storeId, params, url, body, storeIdRef, method } = parsedData; const { axios } = useToolkitsStore((s) => s); useEffect(() => { const storeData = getStoreData(storeIdRef); const newParams = params && replaceValueWithJMESPath(storeData, params); const newBody = params && replaceValueWithJMESPath(storeData, body); axios.request({ method, url, params: newParams, data: newBody }).then((res) => { if (storeId) { setStoreData(storeId, res.data.data); } }).catch((err) => { console.error(err); }); }, []); return null; }); var SpanRenderer = withParsedData(spanSchema)(({ parsedData, source }) => { const { text } = parsedData; const result = text.replace(/\$\{(\w+)\}/g, (_match, varName) => { return search(source, varName) ?? ""; }); return /* @__PURE__ */ jsx("span", { children: result }); }); var TableRenderer = withParsedData(tableSchema)(({ parsedData, source }) => { const { columns, footer, rowKey, data, api, storeIdRef, ...rest } = parsedData; const { dataMap } = useDataStore(); const { axios } = useToolkitsStore((s) => s); let dataSource = []; if (api) { let storeData = null; if (storeIdRef) { storeData = dataMap.get(storeIdRef); } const newUrl = api.replace(/\$\{([^}]+)\}/g, (_match, key) => search(storeData, key) ?? ""); axios.get(newUrl).then((res) => { dataSource = res.data.data; }); } else { if (Array.isArray(data)) { dataSource = data; } else { const match = data?.match(STRING_VAR_REG); if (match) { const result = search(source, match[1]); dataSource = result ?? []; } } } const renderFooter = footer && (() => renderSchemaArray(footer)); return /* @__PURE__ */ jsx(Table, { ...rest, rowKey, columns, footer: renderFooter, dataSource }); }); // src/renderers/index.ts var rendererMap = { button: ButtonRenderer, card: CardRenderer, "date-picker": DatePickerRenderer, "date-range": DateRangeRenderer, form: FormRenderer, "infinite-list": InfiniteListRenderer, "input-number": InputNumberRenderer, "input-text": InputTextRenderer, "query-list": QueryListRenderer, select: SelectRenderer, table: TableRenderer, viewport: ViewportRenderer, flex: FlexRenderer, link: LinkRenderer, span: SpanRenderer, service: ServiceRenderer, descriptions: DescriptionsRenderer }; function replaceValueWithJMESPath(source, target) { function replace(item) { if (typeof item === "string") { const match = item.match(STRING_VAR_REG); if (match) { const result = search(source, match[1]); return result; } return item; } else if (Array.isArray(item)) { return item.map(replace); } else if (typeof item === "object" && item !== null) { const newObj = {}; Object.keys(item).forEach((key) => { newObj[key] = replace(item[key]); }); return newObj; } return item; } return replace(target); } function renderSchemaArray(array, source) { return array?.map((item, index) => { const { type } = item; const RendererComponent = rendererMap[type]; if (RendererComponent) { return /* @__PURE__ */ jsx(RendererComponent, { data: item, source }, `${type}${index}`); } return null; }); } var addUtcOffset = (date) => { return date.clone().add(date.utcOffset(), "minutes"); }; var minusUtcOffset = (date) => { return date.clone().add(-date.utcOffset(), "minutes"); }; var ViewportRenderer = withParsedData(viewportSchema)(({ parsedData }) => { const { body } = parsedData; const children = renderSchemaArray(body); return /* @__PURE__ */ jsx("div", { children }); }); function fallbackRender({ error }) { return /* @__PURE__ */ jsx("pre", { children: JSON.stringify(error, null, 2) }); } var Renderer = (props) => { const { schema } = props; if (!schema) return null; return /* @__PURE__ */ jsx("div", { className: "antd-schema", children: /* @__PURE__ */ jsx(ViewportRenderer, { data: schema }) }); }; var SchemaRenderer = withErrorBoundary(Renderer, { fallbackRender }); export { SchemaRenderer, baseSchema, buttonSchema, cardSchema, formSchema, inputNumberSchema, inputTextSchema, serviceSchema, tableSchema, viewportSchema }; //# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map