diff --git a/apps/playground/package.json b/apps/playground/package.json index 04c4c2ad..192118eb 100644 --- a/apps/playground/package.json +++ b/apps/playground/package.json @@ -15,6 +15,6 @@ "@music163/antd": "^0.2.4", "antd": "^4.24.2", "coral-system": "^1.0.5", - "umi": "^4.0.89" + "umi": "^4.2.3" } } diff --git a/apps/playground/src/helpers/mock-files.ts b/apps/playground/src/helpers/mock-files.ts index a7493dea..2a83dafa 100644 --- a/apps/playground/src/helpers/mock-files.ts +++ b/apps/playground/src/helpers/mock-files.ts @@ -2,7 +2,7 @@ const packageJson = { name: 'demo', private: true, dependencies: { - '@music163/antd': '0.2.4', + '@music163/antd': '0.2.5', '@music163/tango-boot': '0.2.5', react: '17.0.2', 'react-dom': '17.0.2', @@ -56,15 +56,16 @@ const tangoConfigJson = { }, '@music163/antd': { description: '云音乐低代码中后台应用基础物料', - version: '0.2.4', + version: '0.2.5', library: 'TangoAntd', type: 'baseDependency', resources: [ - 'https://unpkg.com/@music163/antd@{{version}}/dist/index.js', + // 'https://unpkg.com/@music163/antd@{{version}}/dist/index.js', + 'http://localhost:8081/dist/index.js', 'https://unpkg.com/antd@4.24.13/dist/antd.css', ], designerResources: [ - 'https://unpkg.com/@music163/antd@{{version}}/dist/designer.js', + 'http://localhost:8081/dist/designer.js', 'https://unpkg.com/antd@4.24.13/dist/antd.css', ], }, @@ -85,6 +86,7 @@ export function registerComponentPrototype(proto) { const routesCode = ` import Index from "./pages/list"; +import Detail from "./pages/detail"; const routes = [ { @@ -92,6 +94,11 @@ const routes = [ exact: true, component: Index }, + { + path: '/detail', + exact: true, + component: Detail + }, ]; export default routes; @@ -150,16 +157,26 @@ import { Input, FormilyForm, FormilyFormItem, + Table, } from "@music163/antd"; import { Space } from "@music163/antd"; import { LocalButton } from "../components"; class App extends React.Component { render() { return ( - + +
your input: copy input: +
@@ -174,6 +191,9 @@ class App extends React.Component {
+

+ hello world +

+
+ ) +} + +export default definePage(App); +`; + const componentsButtonCode = ` import React from 'react'; import { registerComponentPrototype } from '../utils'; @@ -373,6 +410,7 @@ export const sampleFiles = [ { filename: '/src/style.css', code: cssCode }, { filename: '/src/index.js', code: entryCode }, { filename: '/src/pages/list.js', code: viewHomeCode }, + { filename: '/src/pages/detail.js', code: emptyPageCode }, { filename: '/src/components/button.js', code: componentsButtonCode }, { filename: '/src/components/input.js', code: componentsInputCode }, { filename: '/src/components/index.js', code: componentsEntryCode }, diff --git a/apps/playground/src/pages/index.tsx b/apps/playground/src/pages/index.tsx index d8dc4b71..827569b7 100644 --- a/apps/playground/src/pages/index.tsx +++ b/apps/playground/src/pages/index.tsx @@ -1,5 +1,5 @@ import { Box } from 'coral-system'; -import { Button, Space } from 'antd'; +import { Button, Form, Input, Modal, Space } from 'antd'; import { Designer, DesignerPanel, @@ -15,15 +15,18 @@ import { } from '@music163/tango-designer'; import { createEngine, Workspace } from '@music163/tango-core'; import prototypes from '../helpers/prototypes'; -import { Logo, ProjectDetail, bootHelperVariables, sampleFiles } from '../helpers'; +import { Logo, ProjectDetail, bootHelperVariables, emptyPageCode, sampleFiles } from '../helpers'; import { ApiOutlined, AppstoreAddOutlined, BuildOutlined, ClusterOutlined, FunctionOutlined, + PlusOutlined, createFromIconfontCN, } from '@ant-design/icons'; +import { Action } from '@music163/tango-ui'; +import { useState } from 'react'; const menuData = { common: [ @@ -52,6 +55,10 @@ const menuData = { title: 'Formily表单', items: ['FormilyForm', 'FormilyFormItem', 'FormilySubmit', 'FormilyReset'], }, + { + title: '数据展示', + items: ['Comment'], + }, ], }; @@ -88,6 +95,8 @@ createFromIconfontCN({ * 5. 平台初始化,访问 https://local.netease.com:6006/ */ export default function App() { + const [showNewPageModal, setShowNewPageModal] = useState(false); + const [form] = Form.useForm(); return ( + + } + onClick={() => setShowNewPageModal(true)} + /> + @@ -116,6 +133,30 @@ export default function App() { + setShowNewPageModal(false)} + footer={null} + > +
{ + workspace.addViewFile(values.name, emptyPageCode); + setShowNewPageModal(false); + }} + layout="vertical" + > + + + + + + + +
} > diff --git a/apps/storybook/package.json b/apps/storybook/package.json index 64ea263e..5dcf992f 100644 --- a/apps/storybook/package.json +++ b/apps/storybook/package.json @@ -16,8 +16,8 @@ "dependencies": { "@music163/tango-setting-form": "*", "@music163/tango-ui": "*", - "mobx": "6.12.0", - "mobx-react-lite": "4.0.5" + "mobx": "6.12.3", + "mobx-react-lite": "4.0.7" }, "devDependencies": { "@ant-design/icons": "^4.8.0", diff --git a/apps/storybook/src/setting-form.stories.tsx b/apps/storybook/src/setting-form.stories.tsx index 88243aac..a60eeec7 100644 --- a/apps/storybook/src/setting-form.stories.tsx +++ b/apps/storybook/src/setting-form.stories.tsx @@ -1,10 +1,7 @@ import React from 'react'; import { FormModel, SettingForm, register } from '@music163/tango-setting-form'; import { IComponentPrototype } from '@music163/tango-helpers'; -import { BorderSetter, DisplaySetter } from '@music163/tango-designer/src/setters/style-setter'; -import { JsxSetter } from '@music163/tango-designer/src/setters/jsx-setter'; -import { RenderSetter, TableCellSetter } from '@music163/tango-designer/src/setters/render-setter'; -import { NumberSetter } from '@music163/tango-designer/src/setters/number-setter'; +import { BUILT_IN_SETTERS } from '@music163/tango-designer/src/setters'; import { Box } from 'coral-system'; import { JsonView } from '@music163/tango-ui'; import { toJS } from 'mobx'; @@ -12,36 +9,9 @@ import { observer } from 'mobx-react-lite'; import { Card } from 'antd'; import { createFromIconfontCN } from '@ant-design/icons'; -// 这里按需注入,因为部分 setter 依赖 Designer 的上下文 -register({ - name: 'borderSetter', - component: BorderSetter, -}); - -register({ - name: 'displaySetter', - component: DisplaySetter, -}); - -register({ - name: 'jsxSetter', - component: JsxSetter, -}); - -register({ - name: 'renderSetter', - component: RenderSetter, -}); +const BLACK_LIST = ['codeSetter', 'eventSetter', 'modelSetter', 'routerSetter']; -register({ - name: 'tableCellSetter', - component: TableCellSetter, -}); - -register({ - name: 'numberSetter', - component: NumberSetter, -}); +BUILT_IN_SETTERS.filter((setter) => !BLACK_LIST.includes(setter.name)).forEach(register); createFromIconfontCN({ scriptUrl: '//at.alicdn.com/t/c/font_2891794_cxbtmzehxyi.js', @@ -51,165 +21,380 @@ export default { title: 'SettingForm', }; -const prototype: IComponentPrototype = { - name: 'Test', - exportType: 'namedExport', - title: '测试', - icon: 'icon-test', +/** + * 表单值预览 + */ +const FormValuePreview = observer(({ model }: { model: FormModel }) => { + const data = toJS(model.values); + return ; +}); + +interface SettingFormDemoProps { + initValues?: object; + prototype?: IComponentPrototype; +} + +function SettingFormDemo({ initValues, prototype }: SettingFormDemoProps) { + const model = new FormModel(initValues, { onChange: console.log }); + return ( + + + `time${Date.now()}`, + }} + /> + + + + + + + + ); +} + +const prototypeHasBasicProps: IComponentPrototype = { + name: 'Sample', + package: 'sample-pkg', type: 'element', - category: 'basic', - package: '@music163/antd', - hasChildren: false, props: [ + { + name: 'code', + title: 'codeSetter', + setter: 'codeSetter', + }, { name: 'text', title: 'textSetter', setter: 'textSetter', - tip: '这是一个文本属性', - docs: 'https://music-one.fn.netease.com/docs/button', - deprecated: '使用 text2 替代', - }, - { - name: 'display', - title: 'displaySetter', - setter: 'displaySetter', }, { - name: 'border', - title: 'borderSetter', - setter: 'borderSetter', + name: 'text2', + title: 'textAreaSetter', + setter: 'textAreaSetter', }, { - name: 'onClick', - title: 'eventSetter', - tip: '当点击按钮时', - setter: 'eventSetter', - group: 'event', + name: 'number', + title: 'numberSetter', + setter: 'numberSetter', }, { - name: 'children', - title: 'jsxSetter', - setter: 'jsxSetter', + name: 'number2', + title: 'sliderSetter', + setter: 'sliderSetter', }, { - name: 'render', - title: 'renderSetter', - setter: 'renderSetter', + name: 'bool', + title: 'boolSetter', + setter: 'boolSetter', }, { - name: 'cell', - title: 'tableCellSetter', - setter: 'tableCellSetter', + name: 'enum', + title: 'enumSetter', + setter: 'enumSetter', }, { - name: 'router', - title: 'routerSetter', - setter: 'routerSetter', + name: 'list', + title: 'listSetter', + setter: 'listSetter', }, - { - name: 'object', - title: '对象属性', - tip: '一个嵌套的对象', - props: [ - { - name: 'name', - title: 'Name', - setter: 'textSetter', - }, - { - name: 'age', - title: 'Age', - setter: 'numberSetter', + ], +}; + +export function Basic() { + return ( + + ); +} + +export function DeprecatedProp() { + return ( + + ); +} + +export function Validate() { + return ( + { + if (!value && value !== 0) { + return '必填'; + } + if (value < 0) { + return '必须大于 0'; + } + if (value > 10) { + return '必须小于等于 10'; + } }, - ], + }, + ], + }} + /> + ); +} + +export function ObjectSetter() { + return ( + + ); +} + +export function InitValues() { + return ( + { - return form.getValue('text') !== 'test'; - }, - }, - { - name: 'expression', - title: 'expressionSetter', - setter: 'expressionSetter', - }, - { - name: 'model', - title: 'modelSetter', - setter: 'modelSetter', - }, - { - name: 'image', - title: 'imageSetter', - setter: 'imageSetter', - }, - { - name: 'css', - title: 'cssSetter', - setter: 'cssSetter', - }, - { - name: 'extra', - title: 'jsxSetter', - setter: 'jsxSetter', - }, + object: { + text: 'text', + number: 10, + }, + object1: { + text: 'text', + number: '{{tango.stores.user?.age}}', + }, + // 只会有一种情况传下来的是字符串,就是用户代码里存在 rest operator,这时候不需要额外处理,提示用户就使用代码模式 + object2: '{{{ text: "text22", number: 22, ...{ extra: "some" } }}}', + list: [{ key: 'aaa' }, { key: 'bbb' }], // list object + list1: "{{[{ key: 'aaa' }, { key: 'bbb' }]}}", // raw code + }} + prototype={{ + name: 'InitValues', + package: 'sample-pkg', + type: 'element', + props: [ + { + name: 'bool', + title: 'value初始化', + setter: 'boolSetter', + }, + { + name: 'bool1', + title: 'value初始化', + setter: 'boolSetter', + }, + { + name: 'bool2', + title: '无初值', + setter: 'boolSetter', + }, + { + name: 'style', + title: 'codeSetter', + setter: 'codeSetter', + }, + { + name: 'object', + props: [ + { + name: 'text', + title: 'text', + setter: 'textSetter', + }, + { + name: 'number', + title: 'number', + setter: 'numberSetter', + }, + ], + }, + { + name: 'object1', + props: [ + { + name: 'text', + title: 'text', + setter: 'textSetter', + }, + { + name: 'number', + title: 'number', + setter: 'numberSetter', + }, + ], + }, + { + name: 'object2', + props: [ + { + name: 'text', + title: 'text', + setter: 'textSetter', + }, + { + name: 'number', + title: 'number', + setter: 'numberSetter', + }, + ], + }, + { + name: 'list', + title: 'listSetter', + setter: 'listSetter', + }, + { + name: 'list1', + title: 'listSetter', + setter: 'listSetter', + }, + ], + }} + /> + ); +} + +export function Lite() { + return ( + + + + ); +} + +export function HideToggleCode() { + const model = new FormModel({}); + return ( + + + + ); +} + +const prototypeHasExtraProps: IComponentPrototype = { + name: 'ExtraProps', + type: 'element', + package: '@music163/antd', + props: [ { - name: 'icon', - title: 'iconSetter', - setter: 'iconSetter', + name: 'choice', + title: 'choiceSetter', + setter: 'choiceSetter', + options: [ + { label: '选项1', value: '1' }, + { label: '选项2', value: '2' }, + { label: '选项3', value: '3' }, + ], }, { - name: 'iconType', - title: 'iconTypeSetter', - setter: 'iconTypeSetter', + name: 'picker', + title: 'pickerSetter', + setter: 'pickerSetter', + options: [ + { label: '选项1', value: '1' }, + { label: '选项2', value: '2' }, + { label: '选项3', value: '3' }, + ], }, - { - name: 'onClick2', - title: 'actionSetter', - tip: '当点击按钮时', - setter: 'actionSetter', - group: 'event', + name: 'actionList', + title: 'actionListSetter', + setter: 'actionListSetter', }, { - name: 'disabled', - title: 'boolSetter', - tip: 'disabled 是否禁用', - defaultValue: false, - setter: 'boolSetter', + name: 'list', + title: 'listSetter', + setter: 'listSetter', }, { - name: 'size', - title: 'choiceSetter', - tip: 'size 按钮的尺寸', - defaultValue: 'medium', - setter: 'choiceSetter', - setterProps: { - options: [ - { label: '小', value: 'small' }, - { label: '中', value: 'medium' }, - { label: '大', value: 'large' }, - ], - }, + name: 'options', + title: 'optionSetter', + setter: 'optionSetter', }, { - name: 'color', - title: 'colorSetter', - setter: 'colorSetter', + name: 'columns', + title: 'tableColumnsSetter', + setter: 'tableColumnsSetter', }, { - name: 'columns', - title: 'columnSetter', - setter: 'columnSetter', + name: 'css', + title: 'cssSetter', + setter: 'cssSetter', }, { name: 'date', @@ -221,145 +406,137 @@ const prototype: IComponentPrototype = { title: 'dateRangeSetter', setter: 'dateRangeSetter', }, - { - name: 'enum', - title: 'enumSetter', - setter: 'enumSetter', - setterProps: {}, - }, { name: 'time', title: 'timeSetter', setter: 'timeSetter', }, { - name: 'timeRange', + name: 'time', title: 'timeRangeSetter', setter: 'timeRangeSetter', }, { - name: 'dataSource', - title: 'jsonSetter 不推荐', - setter: 'jsonSetter', + name: 'enum', + title: 'enumSetter', + setter: 'enumSetter', }, { - name: 'listSetter', - title: 'listSetter', - setter: 'listSetter', + name: 'event', + title: 'eventSetter', + setter: 'eventSetter', }, { - name: 'count', - title: 'numberSetter', - setter: 'numberSetter', + name: 'json', + title: 'jsonSetter', + setter: 'jsonSetter', }, { - name: 'options', - title: 'optionSetter', - setter: 'optionSetter', + name: 'jsx', + title: 'jsxSetter', + setter: 'jsxSetter', }, { - name: 'type', - title: 'pickerSetter', - defaultValue: 'solid', - setter: 'pickerSetter', - setterProps: { - options: [ - { label: '文本型', value: 'text' }, - { label: '实体型', value: 'solid' }, - { label: '幽灵', value: 'ghost' }, - ], - }, + name: 'render', + title: 'renderPropsSetter', + setter: 'renderPropsSetter', }, { - name: 'title', - title: 'textSetter', - setter: 'textSetter', + name: 'cell', + title: 'tableCellSetter', + setter: 'tableCellSetter', }, { - name: 'invalid', - title: 'invalidSetter', - setter: 'invalidSetter', + name: 'expandable', + title: 'tableExpandableSetter', + setter: 'tableExpandableSetter', }, { - name: 'validate', - title: 'validate', - setter: 'numberSetter', - validate: (value) => { - if (!value && value !== 0) { - return '必填'; - } - if (value < 0) { - return '必须大于 0'; - } - if (value > 10) { - return '必须小于等于 10'; - } - }, + name: 'router', + title: 'routerSetter', + setter: 'routerSetter', }, ], }; -/** - * 表单值预览 - */ -const FormValuePreview = observer(({ model }: { model: FormModel }) => { - const data = toJS(model.values); - return ; -}); - -export function Basic() { - const model = new FormModel( - { - router: 'www.163.com', - expression: `{ foo: 'foo' }`, - object: { - name: 'Alice', - }, - image: - 'https://p6.music.126.net/obj/wonDlsKUwrLClGjCm8Kx/13270238619/2cc5/0782/1d6e/009b96bf90c557b9bbde09b1687a2c80.png', - }, - { onChange: console.log }, - ); - +export function ExtraSetters() { return ( - - - - - - - - - - - ); -} - -export function Lite() { - return ( - - - + ); } -export function NoExpressionSwitch() { - const model = new FormModel({}); +export function StyleProps() { return ( - - - + ); } diff --git a/packages/context/CHANGELOG.md b/packages/context/CHANGELOG.md index 31a2b95a..c2babca9 100644 --- a/packages/context/CHANGELOG.md +++ b/packages/context/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.1.0](https://github.com/netease/tango/compare/@music163/tango-context@1.0.2...@music163/tango-context@1.1.0) (2024-05-17) + +### Features + +- refactor parse attribute value ([#149](https://github.com/netease/tango/issues/149)) ([ffaa276](https://github.com/netease/tango/commit/ffaa276b5c205ed962d37e2fdb358a703f8fad01)) + ## [1.0.1](https://github.com/netease/tango/compare/@music163/tango-context@1.0.0...@music163/tango-context@1.0.1) (2024-04-22) ### Bug Fixes diff --git a/packages/context/package.json b/packages/context/package.json index 7eb709f4..fa9b90a4 100644 --- a/packages/context/package.json +++ b/packages/context/package.json @@ -1,6 +1,6 @@ { "name": "@music163/tango-context", - "version": "1.0.2", + "version": "1.1.0", "description": "react context for tango-apps", "keywords": [ "react", @@ -31,9 +31,9 @@ "react": ">= 16.8" }, "dependencies": { - "@music163/tango-core": "^1.0.2", - "@music163/tango-helpers": "^1.0.0", - "mobx-react-lite": "4.0.5" + "@music163/tango-core": "^1.1.0", + "@music163/tango-helpers": "^1.1.0", + "mobx-react-lite": "4.0.7" }, "publishConfig": { "access": "public", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 04f4791d..1ddff350 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.1.0](https://github.com/netease/tango/compare/@music163/tango-core@1.0.2...@music163/tango-core@1.1.0) (2024-05-17) + +### Bug Fixes + +- parse module with module alias ([#147](https://github.com/netease/tango/issues/147)) ([56d0877](https://github.com/netease/tango/commit/56d0877507b0138877eac6f36db288147b43c7d9)) + +### Features + +- refactor parse attribute value ([#149](https://github.com/netease/tango/issues/149)) ([ffaa276](https://github.com/netease/tango/commit/ffaa276b5c205ed962d37e2fdb358a703f8fad01)) + ## [1.0.1](https://github.com/netease/tango/compare/@music163/tango-core@1.0.0...@music163/tango-core@1.0.1) (2024-04-22) **Note:** Version bump only for package @music163/tango-core diff --git a/packages/core/package.json b/packages/core/package.json index ac4de0bc..bea5abae 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@music163/tango-core", - "version": "1.0.2", + "version": "1.1.0", "description": "tango core", "author": "wwsun ", "homepage": "", @@ -28,10 +28,10 @@ "@babel/parser": "^7.23.5", "@babel/traverse": "^7.23.5", "@babel/types": "^7.23.5", - "@music163/tango-helpers": "^1.0.0", + "@music163/tango-helpers": "^1.1.0", "@types/babel__generator": "^7.6.7", "@types/babel__traverse": "^7.20.4", - "mobx": "6.12.0", + "mobx": "6.12.3", "path-browserify": "^1.0.1" }, "peerDependencies": { diff --git a/packages/core/src/helpers/assert.ts b/packages/core/src/helpers/assert.ts index c21c0f45..73a0a4e9 100644 --- a/packages/core/src/helpers/assert.ts +++ b/packages/core/src/helpers/assert.ts @@ -40,6 +40,7 @@ const templatePattern = /^{(.+)}$/s; /** * 判断给定字符串是否被表达式容器`{expCode}`包裹 * @param code + * @deprecated 新版改为 {{code}} 作为容器,使用 isWrappedCode 代替 */ export function isWrappedByExpressionContainer(code: string, isStrict = true) { if (isStrict && isValidExpressionCode(code)) { diff --git a/packages/core/src/helpers/ast/generate.ts b/packages/core/src/helpers/ast/generate.ts index 798eaab7..87491495 100644 --- a/packages/core/src/helpers/ast/generate.ts +++ b/packages/core/src/helpers/ast/generate.ts @@ -3,7 +3,7 @@ */ import generator, { GeneratorOptions } from '@babel/generator'; import * as t from '@babel/types'; -import { logger } from '@music163/tango-helpers'; +import { logger, wrapCode } from '@music163/tango-helpers'; import { formatCode } from '../string'; const defaultGeneratorOptions: GeneratorOptions = { @@ -156,10 +156,10 @@ export function node2code(node: t.Node) { /** * 将 t.Node 生成为 js 值 * @param node ast node - * @param hasExpressionWrapper 是否包裹表达式 + * @param isWrapCode 是否包裹代码,例如 code -> {{code}} * @returns a plain javascript value */ -export function node2value(node: t.Node, hasExpressionWrapper = true): any { +export function node2value(node: t.Node, isWrapCode = true): any { let ret; switch (node.type) { case 'StringLiteral': @@ -171,39 +171,50 @@ export function node2value(node: t.Node, hasExpressionWrapper = true): any { case 'NullLiteral': ret = null; break; - case 'Identifier': // {data} - case 'MemberExpression': // {this.props.data} - case 'OptionalMemberExpression': // {a?.b} - case 'UnaryExpression': // {!false} - case 'ArrowFunctionExpression': // {() => {}} - case 'TemplateLiteral': // {`hello ${text}`} - case 'ConditionalExpression': // {a ? 'foo' : 'bar'} - case 'LogicalExpression': // { a || b} - case 'BinaryExpression': // { a + b} - case 'TaggedTemplateExpression': // {css``} - case 'CallExpression': // {[1,2,3].map(fn)} - case 'JSXElement': // {hello} - case 'JSXFragment': // <> + case 'Identifier': // {{data}} + case 'MemberExpression': // {{this.props.data}} + case 'OptionalMemberExpression': // {{a?.b}} + case 'UnaryExpression': // {{!false}} + case 'ArrowFunctionExpression': // {{() => {}}} + case 'TemplateLiteral': // {{`hello ${text}`}} + case 'ConditionalExpression': // {{a ? 'foo' : 'bar'}} + case 'LogicalExpression': // {{ a || b}} + case 'BinaryExpression': // {{ a + b}} + case 'TaggedTemplateExpression': // {{css``}} + case 'CallExpression': // {{[1,2,3].map(fn)}} + case 'JSXElement': // {{hello}} + case 'JSXFragment': // {{<>}} ret = expression2code(node); - if (hasExpressionWrapper) { - ret = `{${ret}}`; + if (isWrapCode) { + ret = wrapCode(ret); } break; case 'ObjectExpression': { - ret = node.properties.reduce((prev, propertyNode) => { - if (propertyNode.type === 'ObjectProperty') { - const key = keyNode2value(propertyNode.key); - const value = node2value(propertyNode.value, hasExpressionWrapper); - // key 可能是字符串,也可能是数字 - prev[key] = value; + const isSimpleObject = node.properties.every( + (propertyNode) => propertyNode.type === 'ObjectProperty', + ); + if (isSimpleObject) { + // simple object: { key1, key2, key3 } + ret = node.properties.reduce((prev, propertyNode) => { + if (propertyNode.type === 'ObjectProperty') { + const key = keyNode2value(propertyNode.key); + const value = node2value(propertyNode.value, isWrapCode); + prev[key] = value; // key 可能是字符串,也可能是数字 + } + return prev; + }, {}); + } else { + // mixed object, object property maybe SpreadElement or ObjectMethod, e.g. { key1, fn() {}, ...obj1 } + ret = expression2code(node); + if (wrapCode) { + ret = wrapCode(ret); } - // FIXME: property is a SpreadElement - return prev; - }, {}); + } break; } case 'ArrayExpression': { - ret = node.elements.map((elementNode) => node2value(elementNode, hasExpressionWrapper)); + // FIXME: 有可能会解析失败 + ret = node.elements.map((elementNode) => node2value(elementNode, isWrapCode)); break; } default: @@ -214,7 +225,7 @@ export function node2value(node: t.Node, hasExpressionWrapper = true): any { } /** - * jsx 属性值节点转为 js value + * jsx prop value 节点转为 js value */ export function jsxAttributeValueNode2value(node: t.Node): any { // e.g. 此时没有 value node @@ -232,9 +243,16 @@ export function jsxAttributeValueNode2value(node: t.Node): any { // ret = jsxAttributeValueNode2value(node.expression); break; - default: + case 'ArrayExpression': { + // 数组统一处理为 code + ret = expression2code(node); + ret = wrapCode(ret); + break; + } + default: { ret = node2value(node); break; + } } return ret; diff --git a/packages/core/src/helpers/ast/parse.ts b/packages/core/src/helpers/ast/parse.ts index df2f8635..3395c9a6 100644 --- a/packages/core/src/helpers/ast/parse.ts +++ b/packages/core/src/helpers/ast/parse.ts @@ -5,12 +5,12 @@ import { parse, parseExpression, ParserOptions } from '@babel/parser'; import * as t from '@babel/types'; import { logger, - isValidObjectString, getVariableContent, isPlainObject, Dict, + isWrappedCode, + getCodeOfWrappedCode, } from '@music163/tango-helpers'; -import { isWrappedByExpressionContainer } from '../assert'; // @see https://babeljs.io/docs/en/babel-parser#pluginss const babelParserConfig: ParserOptions = { @@ -109,9 +109,6 @@ export function code2expression(code: string) { * @returns File */ export function expressionCode2ast(code: string) { - if (isWrappedByExpressionContainer(code)) { - code = getVariableContent(code); - } const node = code2expression(code); return t.file(t.program([t.blockStatement([t.expressionStatement(node)])])); } @@ -132,18 +129,19 @@ export function value2node( | t.Expression { let ret; switch (typeof value) { - case 'number': - ret = t.numericLiteral(value); - break; case 'string': - if (isWrappedByExpressionContainer(value)) { - // 再检查是否是表达式容器,例如 {this.foo}, {1} - const innerString = getVariableContent(value); - ret = code2expression(innerString); + if (isWrappedCode(value)) { + // 再检查是否是代码 {{code}},例如 {{this.foo}}, {{1}} + const innerCode = getCodeOfWrappedCode(value); + ret = code2expression(innerCode); } else { + // 否则当成字符串处理 ret = t.stringLiteral(value); } break; + case 'number': + ret = t.numericLiteral(value); + break; case 'boolean': ret = t.booleanLiteral(value); break; @@ -167,7 +165,7 @@ export function value2node( ret = t.identifier('undefined'); break; default: { - logger.error(`value2node: unsupport value <${value}>`); + logger.error(`value2node: value <${value}> transform failed!`); break; } } @@ -196,21 +194,17 @@ export function code2jsxAttributeValueNode(code: string) { return t.jsxExpressionContainer(code2expression(code)); } +// FIXME: 统一处理为 code2jsxAttributeValueNode export function value2jsxAttributeValueNode(value: any) { let ret; switch (typeof value) { - // FIXME: 重构这个逻辑,是不是统一当成 code 处理 case 'string': { if (value.length > 1) { value = value.trim(); } - if (isValidObjectString(value)) { - // 先检查是否是对象字符串 - ret = t.jsxExpressionContainer(code2expression(value)); - } else if (isWrappedByExpressionContainer(value)) { - // 再检查是否是表达式容器,例如 {this.foo}, {1} - const innerString = getVariableContent(value); - ret = t.jsxExpressionContainer(code2expression(innerString)); + if (isWrappedCode(value)) { + const innerCode = getCodeOfWrappedCode(value); + ret = t.jsxExpressionContainer(code2expression(innerCode)); } else { ret = t.stringLiteral(value); } @@ -227,7 +221,7 @@ export function value2jsxChildrenValueNode(value: any) { let ret: t.JSXElement | t.JSXFragment | t.JSXExpressionContainer | t.JSXSpreadChild | t.JSXText; switch (typeof value) { case 'string': - if (isWrappedByExpressionContainer(value)) { + if (isValidExpressionCode(value)) { const innerString = getVariableContent(value); ret = t.jsxExpressionContainer(code2expression(innerString)); } else { diff --git a/packages/core/src/helpers/code-helpers.ts b/packages/core/src/helpers/code-helpers.ts index 68f9b377..b0f6ce2d 100644 --- a/packages/core/src/helpers/code-helpers.ts +++ b/packages/core/src/helpers/code-helpers.ts @@ -1,27 +1,8 @@ -import { getVariableContent } from '@music163/tango-helpers'; -import { value2node, expression2code, isValidExpressionCode } from './ast'; -import { isWrappedByExpressionContainer } from './assert'; +import { getCodeOfWrappedCode, isWrappedCode } from '@music163/tango-helpers'; +import { value2node, expression2code, code2expression, node2value } from './ast'; /** - * 将 js value 转换为代码字符串 - */ -export function value2code(value: any) { - const node = value2node(value); - const code = expression2code(node); - return code; -} - -/** - * 是否是字符串代码 - * @param code - * @returns - */ -function isStringCode(code: string) { - return /^".*"$/.test(code?.trim()); -} - -/** - * js value 转为表达式代码 + * js value 转为代码字符串 * @example 1 => 1 * @example hello => "hello" * @example { foo: bar } => {{ foo: bar }} @@ -30,34 +11,56 @@ function isStringCode(code: string) { * @param val js value * @returns 表达式代码 */ -export function value2expressionCode(val: any) { - if (!val) return ''; +export function value2code(val: any) { + if (val === undefined) { + return ''; + } - let ret; + if (val === null) { + return 'null'; + } + let ret; switch (typeof val) { case 'string': { - if (isValidExpressionCode(val)) { - ret = val; - } else if (isWrappedByExpressionContainer(val, false)) { - ret = getVariableContent(val); - } else if (isStringCode(val)) { - ret = val; + if (isWrappedCode(val)) { + ret = getCodeOfWrappedCode(val); } else { ret = `"${val}"`; } break; } + case 'boolean': + case 'function': case 'number': ret = String(val); break; - case 'object': - ret = value2code(val); - break; - default: - ret = ''; + default: { + // other cases, including array, object, null, undefined + const node = value2node(val); + ret = expression2code(node); break; + } } return ret; } + +export const value2expressionCode = value2code; + +/** + * 代码字符串转为具体的 js value + * @example `() => {}` 返回 undefined + * + * @param rawCode 代码字符串 + * @returns 返回解析后的 js value,包括:string, number, boolean, simpleObject, simpleArray + */ +export function code2value(rawCode: string) { + const node = code2expression(rawCode); + const value = node2value(node); + if (isWrappedCode(value)) { + // 能转的就转,转不能的就返回空 + return; + } + return value; +} diff --git a/packages/core/src/helpers/prototype.ts b/packages/core/src/helpers/prototype.ts index ea427b8f..710f107f 100644 --- a/packages/core/src/helpers/prototype.ts +++ b/packages/core/src/helpers/prototype.ts @@ -3,14 +3,17 @@ import { IComponentProp, IComponentPrototype, Dict, - isNil, logger, uuid, + isWrappedCode, + getCodeOfWrappedCode, + wrapCodeWithJSXExpressionContainer, } from '@music163/tango-helpers'; import { getRelativePath, isFilepath } from './string'; import type { IImportDeclarationPayload, IImportSpecifierData } from '../types'; import { code2expression } from './ast'; import { isWrappedByExpressionContainer } from './assert'; +import { value2code } from './code-helpers'; export function prototype2importDeclarationData( prototype: IComponentPrototype, @@ -88,48 +91,56 @@ export function getImportDeclarationPayloadByPrototype( /** * 基于 key-value 生成 prop={value} 字符串 - * @param key - * @param value + * @example { name: 'foo', initValue: false } >> name={false} + * @example { name: 'foo', initValue: 1 } >> name={1} + * @example { name: 'foo', initValue: () => {} } >> name={()=>{}} + * @example { name: 'foo', initValue: { foo: 'bar' } } >> name={{ foo: 'bar' }} + * @example { name: 'foo', initValue: [{ foo: 'bar' }] } >> name={[{ foo: 'bar' }]} + * @example { name: 'foo', initValue: 'bar' } >> name="bar" + * @example { name: 'foo', initValue: '{() => {}}' } >> name={()=>{}} + * @example { name: 'foo', initValue: '{{() => {}}}' } >> name={() => {}} + * @example { name: 'foo', initValue: '{bar}' } >> name={bar} * @returns */ -function getPropKeyValuePair(item: IComponentProp, generateValue: (...args: any[]) => string) { +export function propDataToKeyValueString( + item: IComponentProp, + generateValue?: (...args: any[]) => string, +) { const key = item.name; let value = item.initValue; if (!value && item.autoInitValue) { - value = generateValue(3); + value = generateValue?.(3) || uuid(key, 3); } - if (isNil(value)) { + if (value === undefined) { return; } switch (typeof value) { case 'number': - case 'boolean': { - value = `{${value}}`; + case 'boolean': + case 'function': { + value = wrapCodeWithJSXExpressionContainer(String(value)); break; } case 'object': { - // TIP: bugfix 如果 object 里有 jsx 或者 function 会失败 try { - value = `{${JSON.stringify(value)}}`; + value = wrapCodeWithJSXExpressionContainer(value2code(value)); } catch (err) { logger.error(err); } break; } - case 'function': { - value = `{${(value as object).toString()}}`; - break; - } case 'string': { - if (!isWrappedByExpressionContainer(value)) { - // 不是变量字符串 - value = `"${value}"`; + if (isWrappedCode(value)) { + const innerCode = getCodeOfWrappedCode(value); + value = wrapCodeWithJSXExpressionContainer(innerCode); + } else if (isWrappedByExpressionContainer(value)) { + // TIP: 兼容旧版逻辑,如果是变量字符串,无需处理 } else { - // 如果是变量字符串,无需处理 + value = `"${value}"`; } break; } @@ -163,7 +174,7 @@ export function prototype2code(prototype: IComponentPrototype, extraProps?: Dict const keys = props.reduce((acc, item) => { - const pair = getPropKeyValuePair(item, (fractionDigits: number) => + const pair = propDataToKeyValueString(item, (fractionDigits: number) => uuid(prototype.name, fractionDigits), ); return pair ? ` ${acc} ${pair}` : acc; diff --git a/packages/core/tests/assert.test.ts b/packages/core/tests/assert.test.ts index d9fb8854..9e152586 100644 --- a/packages/core/tests/assert.test.ts +++ b/packages/core/tests/assert.test.ts @@ -1,4 +1,4 @@ -import { isTangoVariable, isWrappedByExpressionContainer } from '../src/helpers'; +import { isTangoVariable } from '../src/helpers'; describe('assert', () => { it('isTangoVariable', () => { @@ -7,19 +7,4 @@ describe('assert', () => { expect(isTangoVariable('tango.stores.app?.name')).toBeTruthy(); // expect(isTangoVariable('tango.copyToClipboard')).toBeTruthy(); }); - - it('isWrappedByExpressionContainer', () => { - expect(isWrappedByExpressionContainer('{this.foo}')).toBeTruthy(); - expect(isWrappedByExpressionContainer('{!false}')).toBeTruthy(); - expect(isWrappedByExpressionContainer('{[]}')).toBeTruthy(); - expect(isWrappedByExpressionContainer('{{ foo: "bar" }}')).toBeTruthy(); - expect(isWrappedByExpressionContainer('{[{ foo: "bar" }]}')).toBeTruthy(); - expect(isWrappedByExpressionContainer('{123}')).toBeTruthy(); - expect(isWrappedByExpressionContainer('{"hello"}')).toBeTruthy(); - expect(isWrappedByExpressionContainer('{ foo: "bar" }')).toBeFalsy(); - expect(isWrappedByExpressionContainer('{ type: tango.stores?.homePage?.tabKey }')).toBeFalsy(); - expect(isWrappedByExpressionContainer('{ type: tango.stores.homePage.tabKey }')).toBeFalsy(); - expect(isWrappedByExpressionContainer('{ foo: "bar" }')).toBeFalsy(); - expect(isWrappedByExpressionContainer('{ color: tango.stores.app.color }')).toBeFalsy(); - }); }); diff --git a/packages/core/tests/ast.test.ts b/packages/core/tests/ast.test.ts index 0feb843c..38f58065 100644 --- a/packages/core/tests/ast.test.ts +++ b/packages/core/tests/ast.test.ts @@ -54,8 +54,7 @@ describe('ast helpers', () => { it('code2expression', () => { expect(code2expression('')).toBeUndefined(); - expect(code2expression('{tango.stores.app}')).toBeUndefined(); - + expect(code2expression('tango.stores.app').type).toBe('MemberExpression'); expect(code2expression('{ type: window.bar }').type).toEqual('ObjectExpression'); expect(code2expression('() => {};').type).toEqual('ArrowFunctionExpression'); expect(code2expression('').type).toBe('JSXElement'); diff --git a/packages/core/tests/helpers.test.ts b/packages/core/tests/helpers.test.ts index 9956188c..2a1405ed 100644 --- a/packages/core/tests/helpers.test.ts +++ b/packages/core/tests/helpers.test.ts @@ -17,6 +17,7 @@ import { getJSXElementAttributes, inferFileType, deepCloneNode, + code2value, } from '../src/helpers'; import { FileType } from '../src/types'; @@ -27,15 +28,18 @@ describe('helpers', () => { it('parse jsxElement attributes', () => { const node = code2expression( - "", + "", ); const attributes = getJSXElementAttributes(node as JSXElement); expect(attributes).toEqual({ - dataIndex: 'col', + id: '{{tango.user.id}}', + num: 1, + str: 'col', enumMap: { 1: '已解决', 2: '未解决', }, + list: '{{[{ key: 1 }, { key: 2 }]}}', }); }); @@ -80,15 +84,22 @@ describe('helpers', () => { it('expressionCode2ast', () => { expect(expressionCode2ast('').type).toEqual('File'); - expect(expressionCode2ast('{}').type).toEqual('File'); expect(expressionCode2ast('() => ').type).toEqual('File'); - expect(expressionCode2ast('{() => }').type).toEqual('File'); }); }); describe('string helpers', () => { it('value2code: empty array', () => { expect(value2code([])).toEqual('[]'); + expect(value2code({})).toEqual('{}'); + expect(value2code(() => {})).toEqual('() => {}'); + expect(value2code(true)).toEqual('true'); + expect(value2code(false)).toEqual('false'); + expect(value2code(1)).toEqual('1'); + expect(value2code('hello')).toEqual('"hello"'); + expect(value2code('{{window.tango}}')).toEqual('window.tango'); + expect(value2code('{{() => {}}}')).toEqual('() => {}'); + expect(value2code('{{1111}}')).toEqual('1111'); }); it('value2code: array', () => { @@ -201,10 +212,26 @@ describe('schema helpers', () => { }, ], }; - const cloned = deepCloneNode(schema); - expect(cloned.props.id).toBe(schema.props.id); - expect(cloned.children[0].props.id).toBe(schema.children[0].props.id); + it('deepCloneNode', () => { + const cloned = deepCloneNode(schema); + expect(cloned.props.id).toBe(schema.props.id); + expect(cloned.children[0].props.id).toBe(schema.children[0].props.id); + expect(cloned.id).not.toBe(schema.id); + expect(cloned.children[0].id).not.toBe(schema.children[0].id); + }); +}); - expect(cloned.id).not.toBe(schema.id); - expect(cloned.children[0].id).not.toBe(schema.children[0].id); +describe('code helper', () => { + it('code2value', () => { + expect(code2value(`1`)).toEqual(1); + expect(code2value(`false`)).toEqual(false); + expect(code2value(`"foo"`)).toEqual('foo'); + expect(code2value(`{ foo: "foo" }`)).toEqual({ foo: 'foo' }); + expect(code2value(`[{ foo: "foo" }]`)).toEqual([{ foo: 'foo' }]); + expect(code2value(`{ foo: "foo", ...{ bar: "bar"} }`)).toBe(undefined); + expect(code2value(`() => {}`)).toBe(undefined); + expect(code2value(`tango.stores.app.name`)).toBe(undefined); + expect(code2value(`window`)).toBe(undefined); + expect(code2value(`
hello
`)).toBe(undefined); + }); }); diff --git a/packages/core/tests/proto.test.ts b/packages/core/tests/proto.test.ts new file mode 100644 index 00000000..bbd35b5a --- /dev/null +++ b/packages/core/tests/proto.test.ts @@ -0,0 +1,45 @@ +import { propDataToKeyValueString } from '../src/helpers'; + +describe('prototype helpers', () => { + it('propDataToKeyValueString', () => { + // basic + expect(propDataToKeyValueString({ name: 'foo', initValue: 'bar' })).toEqual('foo="bar"'); + expect(propDataToKeyValueString({ name: 'foo', initValue: 1 })).toEqual('foo={1}'); + expect(propDataToKeyValueString({ name: 'foo', initValue: false })).toEqual('foo={false}'); + expect(propDataToKeyValueString({ name: 'foo', initValue: null })).toEqual('foo={null}'); + expect(propDataToKeyValueString({ name: 'foo', initValue: [] })).toEqual('foo={[]}'); + expect(propDataToKeyValueString({ name: 'foo', initValue: {} })).toEqual('foo={{}}'); + expect(propDataToKeyValueString({ name: 'foo', initValue: () => {} })).toEqual( + 'foo={() => {}}', + ); + expect(propDataToKeyValueString({ name: 'foo', initValue: { foo: 'bar' } })).toEqual( + 'foo={{ foo: "bar" }}', + ); + expect(propDataToKeyValueString({ name: 'foo', initValue: [{ foo: 'bar' }] })).toEqual( + 'foo={[{ foo: "bar" }]}', + ); + + // wrapped code + expect( + propDataToKeyValueString({ name: 'foo', initValue: '{{}}' }), + ).toEqual('foo={}'); + expect(propDataToKeyValueString({ name: 'foo', initValue: '{{tango}}' })).toEqual( + 'foo={tango}', + ); + expect(propDataToKeyValueString({ name: 'foo', initValue: '{{"bar"}}' })).toEqual( + 'foo={"bar"}', + ); + expect(propDataToKeyValueString({ name: 'foo', initValue: '{{() => {}}}' })).toEqual( + 'foo={() => {}}', + ); + + // compatible with old version + expect(propDataToKeyValueString({ name: 'foo', initValue: '{() => {}}' })).toEqual( + 'foo={() => {}}', + ); + expect( + propDataToKeyValueString({ name: 'foo', initValue: '{}' }), + ).toEqual('foo={}'); + // expect(propDataToKeyValueString({ name: 'foo', initValue: '{tango}' })).toEqual('foo={tango}'); + }); +}); diff --git a/packages/designer/CHANGELOG.md b/packages/designer/CHANGELOG.md index aa9c6234..3a020430 100644 --- a/packages/designer/CHANGELOG.md +++ b/packages/designer/CHANGELOG.md @@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.1.0](https://github.com/netease/tango/compare/@music163/tango-designer@1.0.3...@music163/tango-designer@1.1.0) (2024-05-17) + +### Bug Fixes + +- support quick set tid in SettingForm ([#151](https://github.com/netease/tango/issues/151)) ([1fc22a4](https://github.com/netease/tango/commit/1fc22a4535a8bdc12a018a41ebd5ab908fc46817)) + +### Features + +- refactor parse attribute value ([#149](https://github.com/netease/tango/issues/149)) ([ffaa276](https://github.com/netease/tango/commit/ffaa276b5c205ed962d37e2fdb358a703f8fad01)) + ## [1.0.2](https://github.com/netease/tango/compare/@music163/tango-designer@1.0.1...@music163/tango-designer@1.0.2) (2024-04-22) ### Bug Fixes diff --git a/packages/designer/package.json b/packages/designer/package.json index d8f3b464..09480831 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@music163/tango-designer", - "version": "1.0.3", + "version": "1.1.0", "description": "lowcode designer", "keywords": [ "react" @@ -32,25 +32,25 @@ }, "dependencies": { "@ant-design/icons": "^4.8.0", - "@music163/request": "^0.1.2", - "@music163/tango-context": "^1.0.2", - "@music163/tango-core": "^1.0.2", - "@music163/tango-helpers": "^1.0.0", - "@music163/tango-sandbox": "^1.0.2", - "@music163/tango-setting-form": "^1.1.0", - "@music163/tango-ui": "^1.0.3", + "@music163/request": "^0.2.0", + "@music163/tango-context": "^1.1.0", + "@music163/tango-core": "^1.1.0", + "@music163/tango-helpers": "^1.1.0", + "@music163/tango-sandbox": "^1.0.3", + "@music163/tango-setting-form": "^1.2.0", + "@music163/tango-ui": "^1.1.0", "antd": "^4.24.2", "cash-dom": "^8.1.2", - "classnames": "^2.3.2", + "classnames": "^2.5.1", "color": "^4.2.3", "coral-system": "^1.0.5", "cssjson": "^2.1.3", "date-fns": "^2.29.2", "lodash-es": "^4.17.21", - "moment": "^2.29.4", + "moment": "^2.30.1", "react-color": "^2.19.3", "react-resizable": "^3.0.5", - "semver": "^7.3.8" + "semver": "^7.6.2" }, "devDependencies": { "@types/color": "^3.0.5", diff --git a/packages/designer/src/components/components-popover.tsx b/packages/designer/src/components/components-popover.tsx index edf5a9f1..ed8f4f1b 100644 --- a/packages/designer/src/components/components-popover.tsx +++ b/packages/designer/src/components/components-popover.tsx @@ -20,7 +20,7 @@ export const ComponentsPopover = observer( type = 'inner', title = '添加组件', isControlled = false, - prototype, + prototype: outPrototype, children, ...popoverProps }: ComponentsPopoverProps) => { @@ -29,27 +29,31 @@ export const ComponentsPopover = observer( const designer = useDesigner(); const { addComponentPopoverPosition, showAddComponentPopover } = designer; - const selectedNodeName = workspace.selectSource.selected?.[0]?.codeId ?? '未选中'; + const selectedNode = workspace.selectSource.selected?.[0]; + const selectedNodeId = selectedNode?.codeId ?? '未选中'; + const prototype = + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + workspace.componentPrototypes.get(selectedNode?.name) ?? ({} as IComponentPrototype); // 推荐使用的子组件 const insertedList = useMemo( () => Array.isArray(prototype?.childrenName) - ? prototype.childrenName - : [prototype.childrenName].filter(Boolean), - [prototype.childrenName], + ? prototype?.childrenName + : [prototype?.childrenName].filter(Boolean), + [prototype?.childrenName], ); // 推荐使用的代码片段 - const siblingList = useMemo(() => prototype.siblingNames ?? [], [prototype.siblingNames]); + const siblingList = useMemo(() => prototype?.siblingNames ?? [], [prototype.siblingNames]); const tipsTextMap = useMemo( () => ({ - before: `点击,在 ${selectedNodeName} 的前方添加节点`, - after: `点击,在 ${selectedNodeName} 的后方添加节点`, - inner: `点击,在 ${selectedNodeName} 内部添加节点`, + before: `点击,在 ${selectedNodeId} 的前方添加节点`, + after: `点击,在 ${selectedNodeId} 的后方添加节点`, + inner: `点击,在 ${selectedNodeId} 内部添加节点`, }), - [selectedNodeName], + [selectedNodeId], ); const handleSelect = useCallback( diff --git a/packages/designer/src/components/variable-tree/service-preview.tsx b/packages/designer/src/components/variable-tree/service-preview.tsx index ddef7b17..ac89aed0 100644 --- a/packages/designer/src/components/variable-tree/service-preview.tsx +++ b/packages/designer/src/components/variable-tree/service-preview.tsx @@ -3,7 +3,8 @@ import { Box } from 'coral-system'; import { Button, Empty } from 'antd'; import { PlayCircleOutlined } from '@ant-design/icons'; import { InputCode, Panel, JsonView } from '@music163/tango-ui'; -import { isNil, logger, code2object, getValue } from '@music163/tango-helpers'; +import { isNil, logger, getValue } from '@music163/tango-helpers'; +import { code2value } from '@music163/tango-core'; export interface ServicePreviewProps { appContext?: any; @@ -22,7 +23,7 @@ export function ServicePreview({ appContext, functionKey }: ServicePreviewProps) editable showLineNumbers onChange={(value: string) => { - const obj = code2object(value); + const obj = code2value(value); // 转为 object 对象 setPayload(obj); }} /> diff --git a/packages/designer/src/helpers/dom.ts b/packages/designer/src/helpers/dom.ts index 029a30c6..12f4a040 100644 --- a/packages/designer/src/helpers/dom.ts +++ b/packages/designer/src/helpers/dom.ts @@ -75,7 +75,7 @@ export function getElementData( const display = getElementCSSDisplay(element); return { id: dnd.id, - codeId: dnd.index, + codeId: dnd.codeId, name: dnd.component || element.tagName.toLowerCase(), filename: dnd.filename, bounding, diff --git a/packages/designer/src/setters/css-setter.tsx b/packages/designer/src/setters/css-setter.tsx index da372cd0..43c0c7bc 100644 --- a/packages/designer/src/setters/css-setter.tsx +++ b/packages/designer/src/setters/css-setter.tsx @@ -2,9 +2,8 @@ import React, { useCallback, useEffect, useState } from 'react'; import { Box } from 'coral-system'; // @ts-ignore import { toJSON } from 'cssjson'; -import { InputNumber, Space } from 'antd'; +import { InputNumber, Slider, Space } from 'antd'; import { FormItemComponentProps } from '@music163/tango-setting-form'; -import { SliderSetter } from './number-setter'; import { BgSetter, BorderSetter, @@ -16,10 +15,11 @@ import { FlexJustifyContentSetter, SpacingSetter, } from './style-setter'; +import { wrapCode } from '@music163/tango-helpers'; const getRawCssValue = (value: string) => { - if (value && value.startsWith('{css`')) { - return value.split('').slice(5, -2).join('').trim(); + if (value && value.startsWith('{{css`')) { + return value.split('').slice(6, -3).join('').trim(); } return value; }; @@ -51,7 +51,8 @@ const cssPattern = (string: string, name: string): any => { }; /** - * 废弃 + * coral-system css prop + * @example 提供 css-in-js 代码支持,例如 css`background: red;` * @deprecated 使用嵌套属性代替 */ export function CssSetter(props: FormItemComponentProps) { @@ -82,16 +83,14 @@ export function CssSetter(props: FormItemComponentProps) { useEffect(() => { if (contentValue || contentValue === '') { - onChange(`{css\`${contentValue}\`}`, { - // relatedImports: [''] - }); + onChange(wrapCode(`css\`${contentValue}\``)); } }, [contentValue]); const isFlex = ['flex', 'inline-flex'].includes(display); return ( - + ) { /> - { + onChange={(v: number) => { changeStyle(v, 'opacity'); }} /> diff --git a/packages/designer/src/setters/date-setter.tsx b/packages/designer/src/setters/date-setter.tsx index 227386b1..28b126a9 100644 --- a/packages/designer/src/setters/date-setter.tsx +++ b/packages/designer/src/setters/date-setter.tsx @@ -25,13 +25,18 @@ const style = { width: '100%', }; -export function DateSetter({ value, onChange, format = 'YYYY-MM-DD', ...rest }: FormItemComponentProps) { +export function DateSetter({ + value, + onChange, + format = 'YYYY-MM-DD', + ...rest +}: FormItemComponentProps) { return ( { onChange && onChange(str); }} @@ -46,7 +51,12 @@ function toMoments(value: string[], format: string): moment.Moment[] { return []; } -export function DateRangeSetter({ value, onChange, format = 'YYYY-MM-DD', ...rest }: FormItemComponentProps) { +export function DateRangeSetter({ + value, + onChange, + format = 'YYYY-MM-DD', + ...rest +}: FormItemComponentProps) { return ( ) { +export function TimeSetter({ + value, + onChange, + format = 'HH:mm:ss', + ...rest +}: FormItemComponentProps) { return ( ) { +export function TimeRangeSetter({ + value, + onChange, + format = 'HH:mm:ss', + ...rest +}: FormItemComponentProps) { return ( (); // 事件类型 const [temp, setTemp] = useState(''); // 二级暂存值 - const { actionVariables, routeOptions } = useWorkspaceData(); const workspace = useWorkspace(); const modalOptions = workspace.activeViewModule.listModals() || []; + const code = value2code(value); + const handleChange = useCallback( (nextValue: any, ...args) => { - const ret = getWrappedExpressionCode(nextValue); - if (ret !== value) { - onChange(ret, ...args); + if (!nextValue) { + onChange(undefined); + } + if (nextValue !== code) { + onChange(wrapCode(nextValue), ...args); } }, - [onChange, value], + [onChange, code], ); const options = useMemo( () => [ @@ -52,7 +57,7 @@ export function EventSetter(props: EventSetterProps) { { label: '打印事件', value: EventAction.ConsoleLog }, { label: ( - { @@ -61,7 +66,7 @@ export function EventSetter(props: EventSetterProps) { dataSource={actionVariables} > 绑定 JS 表达式 - + ), value: EventAction.BindExpression, }, @@ -88,7 +93,7 @@ export function EventSetter(props: EventSetterProps) { } }; - const actionText = getActionText(type, temp, value); + const actionText = getActionText(type, temp, code); return ( @@ -142,12 +147,12 @@ const handlerMap = { [EventAction.NavigateTo]: 'navigateTo', }; -function getActionText(type: EventAction, temp: string, value: any) { +function getActionText(type: EventAction, temp: string, fallbackCode: string) { let text; if (handlerMap[type]) { text = getExpressionValue(type, temp); - } else if (value) { - text = value; + } else if (fallbackCode) { + text = fallbackCode; } text = text || '请选择'; return text; @@ -156,6 +161,6 @@ function getActionText(type: EventAction, temp: string, value: any) { function getExpressionValue(type: EventAction, value = '') { const handler = handlerMap[type]; if (handler) { - return `{() => tango.${handler}("${value}")}`; + return `() => tango.${handler}("${value}")`; } } diff --git a/packages/designer/src/setters/exp-setter.tsx b/packages/designer/src/setters/exp-setter.tsx deleted file mode 100644 index a1ffb1bf..00000000 --- a/packages/designer/src/setters/exp-setter.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import { SingleMonacoEditor } from '@music163/tango-ui'; -import { Box } from 'coral-system'; -import { FormItemComponentProps } from '@music163/tango-setting-form/src/form-item'; - -export function ExpressionSetter({ value, onChange }: FormItemComponentProps) { - return ( - - { - if (newValue !== value) { - onChange(`{${newValue}}`); - } - }} - language="javascript" - options={{ - lineNumbers: 'off', - minimap: { - enabled: false, - }, - }} - /> - - ); -} diff --git a/packages/designer/src/setters/expression-setter.tsx b/packages/designer/src/setters/expression-setter.tsx index 9e7ac41a..14da0071 100644 --- a/packages/designer/src/setters/expression-setter.tsx +++ b/packages/designer/src/setters/expression-setter.tsx @@ -1,12 +1,8 @@ import React, { useState, useEffect, useCallback } from 'react'; import { Box, Text, css } from 'coral-system'; import { Dropdown, Button } from 'antd'; -import { - isValidExpressionCode, - isWrappedByExpressionContainer, - value2expressionCode, -} from '@music163/tango-core'; -import { getVariableContent, noop, getValue, IVariableTreeNode } from '@music163/tango-helpers'; +import { isValidExpressionCode } from '@music163/tango-core'; +import { getValue, IVariableTreeNode, noop } from '@music163/tango-helpers'; import { CloseCircleFilled, ExpandAltOutlined, MenuOutlined } from '@ant-design/icons'; import { Panel, InputCode, Action, DragPanel } from '@music163/tango-ui'; import { FormItemComponentProps } from '@music163/tango-setting-form'; @@ -17,42 +13,19 @@ import { CODE_TEMPLATES } from '../helpers'; import { shapeServiceValues } from '../sidebar/datasource-panel/interface-config'; export const expressionValueValidate = (value: string) => { - if (isWrappedByExpressionContainer(value)) { - const exp = getVariableContent(value); - if (!isValidExpressionCode(exp)) { - return '表达式存在语法错误!'; - } + if (!isValidExpressionCode(value)) { + return '表达式存在语法错误!'; } }; export const jsonValueValidate = (value: string) => { - if (isWrappedByExpressionContainer(value)) { - const jsonStr = getVariableContent(value); - try { - JSON.parse(jsonStr); - } catch (e) { - return '不是合法的 JSON 语法!'; - } + try { + JSON.parse(value); + } catch (e) { + return '不是合法的 JSON 语法!'; } }; -/** - * 返回 `{}` 包裹后的表达式代码 - * @param code 原始代码 - * @returns - */ -export function getWrappedExpressionCode(code: string) { - let ret; - if (!code) { - // do nothing - } else if (isWrappedByExpressionContainer(code)) { - ret = code; - } else { - ret = `{${code}}`; - } - return ret; -} - const suffixStyle = css` display: flex; align-items: center; @@ -78,22 +51,19 @@ export function ExpressionSetter(props: ExpressionSetterProps) { modalTitle, modalTip, autoCompleteOptions, - placeholder = '输入JS代码', + placeholder = '在这里输入JS代码', value: valueProp, status, allowClear = true, newStoreTemplate, showOptionsDropDown = true, } = props; - const [inputValue, setInputValue] = useState(() => { - return value2expressionCode(valueProp); - }); - const sandbox = useSandboxQuery(); - const evaluateContext = sandbox.window; + // const codeValue = getCodeOfWrappedCode(valueProp); + const [inputValue, setInputValue] = useState(valueProp); // when receive new value, sync state useEffect(() => { - setInputValue(value2expressionCode(valueProp)); + setInputValue(valueProp); }, [valueProp]); const change = useCallback( @@ -101,18 +71,14 @@ export function ExpressionSetter(props: ExpressionSetterProps) { if (code === valueProp) { return; } - - const ret = getWrappedExpressionCode(code); - - if (ret === valueProp) { - return; - } - - onChange(ret); + onChange(code); }, [valueProp, onChange], ); + const sandbox = useSandboxQuery(); + const evaluateContext = sandbox.window; + return ( {/* 同时支持下拉框展示 */} @@ -148,7 +114,7 @@ export function ExpressionSetter(props: ExpressionSetterProps) { } size="small" /> )} - { + if (!open) { + setExp(undefined); + setError(''); + } + }} body={ <> - {error ? 输入的表达式存在语法错误,请修改后再提交! : null} + {error ? ( + + 出错了!输入的表达式存在语法错误,请修改后再提交! + + ) : ( + + 说明:你可以在上面的代码输入框里输入常规的 javascript 代码,还可以直接使用 jsx + 代码,但需要符合该属性的接受值定义。 + + )} { + setValue(newValue); + }} onBlur={(newValue) => { if (newValue !== value) { - onChange(`{${newValue}}`); + onChange(newValue); } }} language="json" diff --git a/packages/designer/src/setters/jsx-setter.tsx b/packages/designer/src/setters/jsx-setter.tsx index 2db2e039..8d4f1617 100644 --- a/packages/designer/src/setters/jsx-setter.tsx +++ b/packages/designer/src/setters/jsx-setter.tsx @@ -1,5 +1,4 @@ -import React from 'react'; -import { isPlainString } from '@music163/tango-helpers'; +import React, { useEffect, useState } from 'react'; import { ActionSelect, InputCode } from '@music163/tango-ui'; import { FormItemComponentProps } from '@music163/tango-setting-form'; import { Box } from 'coral-system'; @@ -54,24 +53,36 @@ const defaultGetTemplate = (key: string) => { */ export function JsxSetter(props: JsxSetterProps) { const { showInput, getTemplate = defaultGetTemplate, value, onChange } = props; + const [inputValue, setInputValue] = useState(value); + useEffect(() => { + setInputValue(value); + }, [value]); return ( { const [tpl, deps] = getTemplate(key); if (tpl) { - onChange(`{${tpl}}`, { relatedImports: deps }); + onChange(tpl, { relatedImports: deps }); } else { onChange(undefined); } }} /> - {value && } + {value && ( + setInputValue(val)} + onBlur={() => { + onChange(inputValue); + }} + /> + )} ); } diff --git a/packages/designer/src/setters/list-setter.tsx b/packages/designer/src/setters/list-setter.tsx index c5896d40..24dddd15 100644 --- a/packages/designer/src/setters/list-setter.tsx +++ b/packages/designer/src/setters/list-setter.tsx @@ -234,6 +234,7 @@ function NewOptionForm({ fields = [], initialValues = {}, onSubmit }: NewOptionF label={item.label} name={item.name} required={item.required} + rules={[{ required: item.required }]} valuePropName={item.valuePropName} extra={item.extra} style={{ @@ -260,7 +261,7 @@ interface ListSetterProps extends FormItemComponentProps { addBtnText?: string; getListItemKey?: (item: any) => React.Key; renderItem?: (item: any) => React.ReactNode; -}; +} const defaultListItemFormFields: ListSetterItemProps['formFields'] = [ { label: 'key', name: 'key', required: true }, diff --git a/packages/designer/src/setters/render-setter.tsx b/packages/designer/src/setters/render-setter.tsx index 42715de9..c038b42f 100644 --- a/packages/designer/src/setters/render-setter.tsx +++ b/packages/designer/src/setters/render-setter.tsx @@ -2,7 +2,6 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { ActionSelect, InputCode } from '@music163/tango-ui'; import { FormItemComponentProps } from '@music163/tango-setting-form'; import { Box } from 'coral-system'; -import { value2expressionCode } from '@music163/tango-core'; interface IRenderOption { label: string; @@ -17,6 +16,11 @@ export interface RenderSetterProps { fallbackOption?: IRenderOption; } +const defaultOptions: IRenderOption[] = [ + { label: '取消自定义', value: '' }, + { label: '自定义渲染', value: 'Box', render: '() => ' }, +]; + /** * Render Props Setters */ @@ -24,14 +28,12 @@ export function RenderSetter({ value, onChange, text = '自定义渲染为', - options = [], + options = defaultOptions, fallbackOption, }: FormItemComponentProps & RenderSetterProps) { - const [inputValue, setInputValue] = useState(() => { - return value2expressionCode(value); - }); + const [inputValue, setInputValue] = useState(value || ''); useEffect(() => { - setInputValue(value2expressionCode(value)); + setInputValue(value); }, [value]); const optionsMap = useMemo(() => { @@ -67,17 +69,22 @@ export function RenderSetter({ } const getRender = (content: string, type?: 'tableCell' | 'tableExpandable') => { + let code; switch (type) { case 'tableCell': - return `{(value, record, index) => ${content}}`; + code = `(value, record, index) => ${content}`; + break; case 'tableExpandable': - return `{{ - expandedRowRender: (record) => ${content}, - rowExpandable: (record) => true - }}`; + code = `{ + expandedRowRender: (record) => ${content}, + rowExpandable: (record) => true + }`; + break; default: - return `{() => ${content}}`; + code = `() => ${content}`; + break; } + return code; }; const tableCellOptions: RenderSetterProps['options'] = [ @@ -122,6 +129,7 @@ export function TableCellSetter(props: FormItemComponentProps) { return ; } +// FIXME: 应该直接用 props 嵌套的模式 export function TableExpandableSetter(props: FormItemComponentProps) { return ; } diff --git a/packages/designer/src/setters/style-setter.tsx b/packages/designer/src/setters/style-setter.tsx index d4b1937d..b5b5165a 100644 --- a/packages/designer/src/setters/style-setter.tsx +++ b/packages/designer/src/setters/style-setter.tsx @@ -7,8 +7,6 @@ import { BgColorsOutlined, EyeInvisibleOutlined, FileImageOutlined } from '@ant- import { SingleMonacoEditor, LineSolidOutlined, LineDashedOutlined } from '@music163/tango-ui'; import { FormItemComponentProps } from '@music163/tango-setting-form'; import { ChoiceSetter } from './choice-setter'; -import { TextSetter } from './text-setter'; -// import { ImageSetter } from './image-setter'; function getRawCssValue(value: string) { if (value && value.startsWith('{css`')) { @@ -17,12 +15,13 @@ function getRawCssValue(value: string) { return value; } +// TODO: style object setter + /** * 不稳定,暂不推荐使用 */ export function CssCodeSetter({ value, onChange }: FormItemComponentProps) { const contentValue = getRawCssValue(value); - // TODO: relatedImports return ( { if (newCode != contentValue) { - onChange(`{css\`${newCode}\`}`, { - // relatedImports: [''] - }); + onChange(`{css\`${newCode}\`}`, {}); } }} /> @@ -239,9 +236,10 @@ export function BgSetter({ value, onChange }: FormItemComponentProps) { {mode === 'color' && } {mode === 'image' && ( - { + onChange={(e) => { + const imgUrl = e.target.value; onChange(imgUrl ? `url(${imgUrl})` : undefined); }} /> diff --git a/packages/designer/src/setting-panel.tsx b/packages/designer/src/setting-panel.tsx index 95df475c..88f9e706 100644 --- a/packages/designer/src/setting-panel.tsx +++ b/packages/designer/src/setting-panel.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Box } from 'coral-system'; import { SettingForm, FormModel, SettingFormProps } from '@music163/tango-setting-form'; import { Panel } from '@music163/tango-ui'; -import { clone } from '@music163/tango-helpers'; +import { clone, parseDndId } from '@music163/tango-helpers'; import { observer, useDesigner, useWorkspace } from '@music163/tango-context'; import { registerBuiltinSetters } from './setters'; @@ -103,6 +103,11 @@ export const SettingPanel = observer((props: SettingPanelProps) => { prototype={prototype} showIdentifier={{ identifierKey: 'tid', + getIdentifier: () => { + // 直接拿当前的虚拟 id 作为 tid + const { codeId } = parseDndId(workspace.selectSource.first.id); + return codeId; + }, }} {...props} /> diff --git a/packages/designer/src/sidebar/datasource-panel/interface-config.tsx b/packages/designer/src/sidebar/datasource-panel/interface-config.tsx index 964fcd0b..44379489 100644 --- a/packages/designer/src/sidebar/datasource-panel/interface-config.tsx +++ b/packages/designer/src/sidebar/datasource-panel/interface-config.tsx @@ -1,8 +1,6 @@ import React from 'react'; import { observer, useWorkspace, useWorkspaceData } from '@music163/tango-context'; import { Box } from 'coral-system'; -import { getVariableContent } from '@music163/tango-helpers'; -import { isWrappedByExpressionContainer } from '@music163/tango-core'; import { VariableTree } from '../../components'; import { useSandboxQuery } from '../../context'; @@ -10,10 +8,6 @@ import { useSandboxQuery } from '../../context'; export function shapeServiceValues(val: any) { const shapeValues = { ...val }; delete shapeValues.type; - // 兼容旧版,如果 formatter 包裹了 {} 则删掉首尾 - if (shapeValues.formatter && isWrappedByExpressionContainer(shapeValues.formatter)) { - shapeValues.formatter = getVariableContent(shapeValues.formatter); - } return shapeValues; } diff --git a/packages/designer/src/sidebar/outline-panel/components-tree.tsx b/packages/designer/src/sidebar/outline-panel/components-tree.tsx index d2827582..5454c340 100644 --- a/packages/designer/src/sidebar/outline-panel/components-tree.tsx +++ b/packages/designer/src/sidebar/outline-panel/components-tree.tsx @@ -81,8 +81,8 @@ const OutlineTreeNode: React.FC<{ node: ITangoViewNodeData } & ComponentsTreePro const sandboxQuery = useSandboxQuery(); const [visible, setVisible] = useState(true); const nodeLabel = (() => { - const { index } = parseDndId(node.id); - return index; + const { codeId } = parseDndId(node.id); + return codeId; })(); const componentPrototype = workspace.componentPrototypes.get(node.component); const icon = componentPrototype?.icon || 'icon-placeholder'; diff --git a/packages/designer/src/simulator/selection.tsx b/packages/designer/src/simulator/selection.tsx index d2dbfb4f..a3141577 100644 --- a/packages/designer/src/simulator/selection.tsx +++ b/packages/designer/src/simulator/selection.tsx @@ -197,7 +197,7 @@ function SelectionBox({ showActions, actions, data }: SelectionBoxProps) { /> {!isPage && actions} {prototype.hasChildren !== false && ( - + } /> diff --git a/packages/helpers/CHANGELOG.md b/packages/helpers/CHANGELOG.md index e9f36a02..97ab5279 100644 --- a/packages/helpers/CHANGELOG.md +++ b/packages/helpers/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.1.0](https://github.com/netease/tango/compare/@music163/tango-helpers@1.0.0...@music163/tango-helpers@1.1.0) (2024-05-17) + +### Bug Fixes + +- parse module with module alias ([#147](https://github.com/netease/tango/issues/147)) ([56d0877](https://github.com/netease/tango/commit/56d0877507b0138877eac6f36db288147b43c7d9)) +- support quick set tid in SettingForm ([#151](https://github.com/netease/tango/issues/151)) ([1fc22a4](https://github.com/netease/tango/commit/1fc22a4535a8bdc12a018a41ebd5ab908fc46817)) + +### Features + +- refactor parse attribute value ([#149](https://github.com/netease/tango/issues/149)) ([ffaa276](https://github.com/netease/tango/commit/ffaa276b5c205ed962d37e2fdb358a703f8fad01)) + # [1.0.0-alpha.7](https://github.com/netease/tango/compare/@music163/tango-helpers@1.0.0-alpha.6...@music163/tango-helpers@1.0.0-alpha.7) (2024-04-22) ### Bug Fixes diff --git a/packages/helpers/package.json b/packages/helpers/package.json index 74e0a9d9..a0ef0db2 100644 --- a/packages/helpers/package.json +++ b/packages/helpers/package.json @@ -1,6 +1,6 @@ { "name": "@music163/tango-helpers", - "version": "1.0.0", + "version": "1.1.0", "description": "Shared types, helpers, and hooks of tango-apps", "keywords": [ "shared", diff --git a/packages/helpers/src/helpers/code-helper.ts b/packages/helpers/src/helpers/code-helper.ts new file mode 100644 index 00000000..0fcb6083 --- /dev/null +++ b/packages/helpers/src/helpers/code-helper.ts @@ -0,0 +1,197 @@ +import { isString } from './assert'; + +/** + * 给定字符串是否是合法的 JSON 字符串 + * @param str + */ +export function isJSONString(str: string) { + if (!str) { + return false; + } + + let json; + try { + json = JSON.parse(str); + return typeof json === 'object'; + } catch (err) { + return false; + } +} + +/** + * 给定代码是否是有效的函数代码 + * @param str + */ +export function isValidFunctionCode(str: string) { + try { + // eslint-disable-next-line no-eval + const ret = eval(`typeof (${str})`); + return ret === 'function'; + } catch (e) { + return false; + } +} + +const templatePattern = /^{{(.+)}}$/s; + +/** + * 判断给定代码是否被双花括号包裹 + * @example {{[]}} + * @example {{{}}} + * @example {{this.foo}} + * @example {{123}} + * @param str + * @returns + */ +export function isWrappedCode(str: string) { + // 排除简单对象后,再用正则匹配 + return templatePattern.test(str); +} + +export const isVariableString = isWrappedCode; + +/** + * 从包裹的代码中获取代码内容 + * @param str + * @returns + */ +export function getCodeOfWrappedCode(str: string) { + const match = templatePattern.exec(str); + if (match && match.length) { + return match[1]; + } + return str; +} + +export const getVariableContent = getCodeOfWrappedCode; + +/** + * 给输入代码加上双花括号 code -> {{code}} + * @example foo -> {{foo}} + * @example "hello" => {{"hello"}} + * @example () => {} => {{() => {}}} + * + * @param code 输入代码 + * @returns 加上花括号后的代码 + */ +export function wrapCode(code: string) { + if (isWrappedCode(code)) { + return code; + } + return `{{${code}}}`; +} + +/** + * 使用 JSX 表达式容器包裹代码 + * @example foo -> {foo} + * @example "hello" => {"hello"} + * @param code + * @returns + */ +export function wrapCodeWithJSXExpressionContainer(code: string) { + return `{${code}}`; +} + +/** + * 是否为简单字符串,非变量字符串 + * @param str + */ +export function isPlainString(str: string) { + const isWrapped = isString(str) && isWrappedCode(str); + return isString && !isWrapped; +} + +const codeBlockPattern = /```(\w*)([\s\S]*?)```/g; + +/** + * 从 markdown 中解析出代码片段,仅返回第一个匹配的代码片段 + * @param markdown + * @returns + */ +export function getCodeBlockFormMarkdown(markdown: string) { + const match = codeBlockPattern.exec(markdown.trim()); + if (match && match.length) { + return match[2]; + } +} + +export function url2serviceName(url: string) { + if (url.startsWith('http')) { + // 去除域名前缀 + url = url + .replace(/https?:\/\//, '') + .split('/') + .slice(1) + .join('/'); + } + + return ( + url + // 去除 api + 模块名前缀 + // - 云音乐 api 规范为 /api/模块名/ + // - 后端公技基本使用 /模块名/api/ + // - 中台类服务似乎常用 /api/middle/模块名/ + // 目前的实现是去除了模块名,只干掉 /api/middle/ 和 /api/backend/ 这种常用前缀 + .replace(/^\/[^/]+?\/api\/|^\/api\/middle\/|^\/api\/backend\/|^\/api\//, '') + // 去除路由参数 + .replace(/\/\{.*?\}/, '') + // 忽略下划线与减号,将后面的字符转成大驼峰 + .replace(/[-/_]+\w/g, (str) => str.replace(/[-/_]+/, '').toUpperCase()) + // 首字母转小写 + .replace(/^./, (str) => str.toLowerCase()) + // 方法名以数字开头,添加 api 前缀 + .replace(/^\d/, (str) => `api${str}`) + ); +} + +/** + * 解析状态变量的 path + * @example stores.foo.bar => { storeName: 'foo', variableName: 'bar' } + * @example stores.user.count => { storeName: 'user', variableName: 'count' } + * + * @param variablePath + * @returns + */ +export function parseStoreVariablePath(variablePath: string) { + const [, storeName, variableName] = variablePath.split('.'); + return { + storeName, + variableName, + }; +} + +/** + * 解析服务变量的 path + * @param variablePath + * @returns + * + * @example services.list => { moduleName: 'index', name: 'list' } + * @example services.sub.list => { moduleName: 'sub', name: 'list' } + * @example foo => undefined + */ +export function parseServiceVariablePath(variablePath: string) { + const parts = variablePath.split('.'); + if (parts[0] !== 'services') { + return {}; + } + + let moduleName = 'index'; + let name = ''; + switch (parts.length) { + case 2: { + name = parts[1]; + break; + } + case 3: { + moduleName = parts[1]; + name = parts[2]; + break; + } + default: + break; + } + return { + moduleName, + name, + }; +} diff --git a/packages/helpers/src/helpers/index.ts b/packages/helpers/src/helpers/index.ts index 87f0e702..cd88f196 100644 --- a/packages/helpers/src/helpers/index.ts +++ b/packages/helpers/src/helpers/index.ts @@ -7,5 +7,6 @@ export * from './events'; export * from './function'; export * from './logger'; export * from './string'; -export * from './react-helper'; export * from './object'; +export * from './react-helper'; +export * from './code-helper'; diff --git a/packages/helpers/src/helpers/string.ts b/packages/helpers/src/helpers/string.ts index 95210300..ece586de 100644 --- a/packages/helpers/src/helpers/string.ts +++ b/packages/helpers/src/helpers/string.ts @@ -75,9 +75,13 @@ export function parseDndTrackId(str: string) { interface DndIdParsedType { /** - * 完整的 ID + * full id */ id?: string; + /** + * 组件代码中的 id,一般对应组件的 tid 属性 + */ + codeId?: string; /** * 组件名 */ @@ -86,19 +90,11 @@ interface DndIdParsedType { * 文件名 */ filename?: string; - /** - * @deprecated 使用 filename 代替 - */ - module?: string; - /** - * 序号 - */ - index?: string; } /** * 解析 dnd id - * @example Button:123 -> { component: "Button", id: "Button:123" } + * @example Button:button123 -> { component: "Button", id: "Button:123" } * @example LocalBlock:Button:123 -> { filename: LocalBlock, component: "Button", id: "Button:123" } * @param str */ @@ -109,277 +105,23 @@ export function parseDndId(str: string): DndIdParsedType { const parts = str.split(':'); if (parts.length === 2) { + // e.g. Button:button123 return { - component: parts[0], - index: parts[1], id: str, + component: parts[0], + codeId: parts[1], }; } else if (parts.length >= 3) { + // e.g. LocalBlock:Button:button123 const filename = decodeURIComponent(parts[0]); return { - module: filename, + id: str, filename, component: parts[1], - index: parts[2], - id: str, + codeId: parts[2], }; } return { id: str, }; } - -/** - * 给定字符串是否是合法的 JSON 字符串 - * @param str - */ -export function isJSONString(str: string) { - if (!str) { - return false; - } - - let json; - try { - json = JSON.parse(str); - return typeof json === 'object'; - } catch (err) { - return false; - } -} - -/** - * 给定代码是否是有效的函数代码 - * @param str - */ -export function isValidFunctionCode(str: string) { - try { - // eslint-disable-next-line no-eval - const ret = eval(`typeof (${str})`); - return ret === 'function'; - } catch (e) { - return false; - } -} - -/** - * 是否是有效的对象字符串 - * - * @example { foo: 'foo' } - * @example [{ foo: 'foo' }] - * TODO: 考虑箭头函数的情况 () => {} - * - * @param str - * @returns - */ -export function isValidObjectString(str: string) { - const obj = code2object(str); - if (obj && typeof obj === 'object') { - return true; - } - return false; -} - -const templatePattern = /^{(.+)}$/s; - -/** - * 判断给定字符串是否为变量字符串 - * @deprecated 使用 isWrappedByExpressionContainer 代替 - * - * @example {[]} - * @example {{}} - * @example {this.foo} - * @example {123} - * @param str - * @returns - */ -export function isVariableString(str: string) { - // 先检查是否是简单的对象 - // FIXME: 这里有问题,如果代码中有引用,会被误判 - if (code2object(str)) { - return false; - } - - // 排除简单对象后,再用正则匹配 - return templatePattern.test(str); -} - -/** - * 给输入代码加上花括号 - * @example foo -> {foo} - * @example "hello" => {"hello"} - * @example () => {} => {() => {}} - * - * @deprecated 有问题,不要使用 - * - * @param code 输入代码 - * @returns 加上花括号后的代码 - */ -export function wrapCode(code: string) { - if (isVariableString(code)) { - return code; - } - return `{${code}}`; -} - -/** - * 是否为简单字符串,非变量字符串 - * @param str - */ -export function isPlainString(str: string) { - const isString = typeof str === 'string'; - const isVarString = isString && isVariableString(str); - return isString && !isVarString; -} - -/** - * 解析并获取变量字符串的内容 - * @param str - * @returns - */ -export function getVariableContent(str: string) { - const match = templatePattern.exec(str); - if (match && match.length) { - return match[1]; - } - return str; -} - -// 提供给代码执行环境的全局变量 -const patchCode = ` -var tango = { - stores: {}, - services: {}, - config: {}, - refs: {}, -}; -`; - -/** - * 将代码放到函数体中进行执行 - * @param code - * @returns 函数执行的结果 - */ -export function runCode(code: string) { - let ret; - try { - // eslint-disable-next-line no-new-func - ret = new Function(`${patchCode}\n return ${code}`)(); - } catch (err) { - // ignore error - } - return ret; -} - -// eslint-disable-next-line no-useless-escape -const objectWrapperPattern = /^[{\[].*[}\]]$/s; - -/** - * 将代码片段转成 js 对象 - * @param code 代码文本 - * @param isStrict 是否为严格模式(是否废弃) - * @returns - */ -export function code2object(code: string, isStrict = true) { - // 非严格模式直接执行 - // 严格模式下需检测 code 是一个对象 - if (!isStrict || (isStrict && objectWrapperPattern.test(code))) { - const ret = runCode(code); - return typeof ret === 'object' ? ret : undefined; - } - return code; -} - -const codeBlockPattern = /```(\w*)([\s\S]*?)```/g; - -/** - * 从 markdown 中解析出代码片段,仅返回第一个匹配的代码片段 - * @param markdown - * @returns - */ -export function getCodeBlockFormMarkdown(markdown: string) { - const match = codeBlockPattern.exec(markdown.trim()); - if (match && match.length) { - return match[2]; - } -} - -export function url2serviceName(url: string) { - if (url.startsWith('http')) { - // 去除域名前缀 - url = url - .replace(/https?:\/\//, '') - .split('/') - .slice(1) - .join('/'); - } - - return ( - url - // 去除 api + 模块名前缀 - // - 云音乐 api 规范为 /api/模块名/ - // - 后端公技基本使用 /模块名/api/ - // - 中台类服务似乎常用 /api/middle/模块名/ - // 目前的实现是去除了模块名,只干掉 /api/middle/ 和 /api/backend/ 这种常用前缀 - .replace(/^\/[^/]+?\/api\/|^\/api\/middle\/|^\/api\/backend\/|^\/api\//, '') - // 去除路由参数 - .replace(/\/\{.*?\}/, '') - // 忽略下划线与减号,将后面的字符转成大驼峰 - .replace(/[-/_]+\w/g, (str) => str.replace(/[-/_]+/, '').toUpperCase()) - // 首字母转小写 - .replace(/^./, (str) => str.toLowerCase()) - // 方法名以数字开头,添加 api 前缀 - .replace(/^\d/, (str) => `api${str}`) - ); -} - -/** - * 解析状态变量的 path - * @example stores.foo.bar => { storeName: 'foo', variableName: 'bar' } - * @example stores.user.count => { storeName: 'user', variableName: 'count' } - * - * @param variablePath - * @returns - */ -export function parseStoreVariablePath(variablePath: string) { - const [, storeName, variableName] = variablePath.split('.'); - return { - storeName, - variableName, - }; -} - -/** - * 解析服务变量的 path - * @param variablePath - * @returns - * - * @example services.list => { moduleName: 'index', name: 'list' } - * @example services.sub.list => { moduleName: 'sub', name: 'list' } - * @example foo => undefined - */ -export function parseServiceVariablePath(variablePath: string) { - const parts = variablePath.split('.'); - if (parts[0] !== 'services') { - return {}; - } - - let moduleName = 'index'; - let name = ''; - switch (parts.length) { - case 2: { - name = parts[1]; - break; - } - case 3: { - moduleName = parts[1]; - name = parts[2]; - break; - } - default: - break; - } - return { - moduleName, - name, - }; -} diff --git a/packages/helpers/tests/helpers.test.ts b/packages/helpers/tests/helpers.test.ts index 5f20584c..15017b16 100644 --- a/packages/helpers/tests/helpers.test.ts +++ b/packages/helpers/tests/helpers.test.ts @@ -1,7 +1,5 @@ import { isVariableString, - isValidObjectString, - code2object, parseDndTrackId, getVariableContent, camelCase, @@ -35,40 +33,22 @@ describe('string', () => { }); it('isVariableString', () => { - expect(isVariableString('{this.foo}')).toBeTruthy(); - expect(isVariableString('{!false}')).toBeTruthy(); - expect(isVariableString('{[]}')).toBeTruthy(); - expect(isVariableString('{{ foo: "bar" }}')).toBeTruthy(); - expect(isVariableString('{[{ foo: "bar" }]}')).toBeTruthy(); - expect(isVariableString('{123}')).toBeTruthy(); - expect(isVariableString('{value}')).toBeTruthy(); - expect(isVariableString('{"hello"}')).toBeTruthy(); + expect(isVariableString('{{this.foo}}')).toBeTruthy(); + expect(isVariableString('{{!false}}')).toBeTruthy(); + expect(isVariableString('{{[]}}')).toBeTruthy(); + expect(isVariableString('{{{ foo: "bar" }}}')).toBeTruthy(); + expect(isVariableString('{{[{ foo: "bar" }]}}')).toBeTruthy(); + expect(isVariableString('{{123}}')).toBeTruthy(); + expect(isVariableString('{{value}}')).toBeTruthy(); + expect(isVariableString('{{"hello"}}')).toBeTruthy(); expect(isVariableString('{ foo: "bar" }')).toBeFalsy(); expect(isVariableString('{ type: tango.stores?.homePage?.tabKey }')).toBeFalsy(); - // expect(isVariableString('{ type: tango.stores.homePage.tabKey }')).toBeFalsy(); // TIP: failed + expect(isVariableString('{ type: tango.stores.homePage.tabKey }')).toBeFalsy(); expect(isVariableString('{ foo: "bar" }')).toBeFalsy(); }); it('getVariableContent', () => { - expect(getVariableContent('{!false}')).toBe('!false'); - }); - - it('isValidObjectString', () => { - expect(isValidObjectString('{ foo: "bar" }')).toBeTruthy(); - expect(isValidObjectString('[{ foo: "bar" }]')).toBeTruthy(); - expect(isValidObjectString('[1,2,3]')).toBeTruthy(); - expect(isValidObjectString('["hello", "world"]')).toBeTruthy(); - // expect(isValidObjectString('() => {}')).toBeTruthy(); - expect(isValidObjectString('hello')).toBeFalsy(); - }); - - it('code2object', () => { - expect(code2object(`{ foo: 12 }`)).toEqual({ foo: 12 }); - expect(code2object(`[]`)).toEqual([]); - expect(code2object(`{this.foo}`)).toBeUndefined(); - expect(code2object(`{foo}`)).toBeUndefined(); - expect(code2object('() => {}')).toEqual('() => {}'); - expect(code2object('hello')).toEqual('hello'); + expect(getVariableContent('{{!false}}')).toBe('!false'); }); it('parseDndTrackId', () => { @@ -78,22 +58,21 @@ describe('string', () => { it('parseDndId', () => { expect(parseDndId('123')).toEqual({ id: '123' }); - expect(parseDndId('Button:123')).toEqual({ + expect(parseDndId('Button:button123')).toEqual({ component: 'Button', - id: 'Button:123', - index: '123', + id: 'Button:button123', + codeId: 'button123', }); - expect(parseDndId('Button.Group:123')).toEqual({ + expect(parseDndId('Button.Group:buttonGroup123')).toEqual({ component: 'Button.Group', - id: 'Button.Group:123', - index: '123', + id: 'Button.Group:buttonGroup123', + codeId: 'buttonGroup123', }); - expect(parseDndId('LocalBlock:Button.Group:123')).toEqual({ + expect(parseDndId('LocalBlock:Button.Group:buttonGroup123')).toEqual({ + id: 'LocalBlock:Button.Group:buttonGroup123', filename: 'LocalBlock', - module: 'LocalBlock', component: 'Button.Group', - id: 'LocalBlock:Button.Group:123', - index: '123', + codeId: 'buttonGroup123', }); }); diff --git a/packages/sandbox/CHANGELOG.md b/packages/sandbox/CHANGELOG.md index 1bad59eb..71b724d8 100644 --- a/packages/sandbox/CHANGELOG.md +++ b/packages/sandbox/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.0.3](https://github.com/netease/tango/compare/@music163/tango-sandbox@1.0.2...@music163/tango-sandbox@1.0.3) (2024-05-17) + +**Note:** Version bump only for package @music163/tango-sandbox + ## [1.0.1](https://github.com/netease/tango/compare/@music163/tango-sandbox@1.0.0...@music163/tango-sandbox@1.0.1) (2024-04-22) **Note:** Version bump only for package @music163/tango-sandbox diff --git a/packages/sandbox/package.json b/packages/sandbox/package.json index 5848a2ea..b8a285dc 100644 --- a/packages/sandbox/package.json +++ b/packages/sandbox/package.json @@ -1,6 +1,6 @@ { "name": "@music163/tango-sandbox", - "version": "1.0.2", + "version": "1.0.3", "description": "sandbox of tango apps", "author": "wwsun ", "homepage": "", @@ -29,8 +29,8 @@ }, "dependencies": { "@ant-design/icons": "^4.8.0", - "@music163/tango-core": "^1.0.2", - "@music163/tango-helpers": "^1.0.0", + "@music163/tango-core": "^1.1.0", + "@music163/tango-helpers": "^1.1.0", "crypto-js": "^4.1.1", "lodash.isequal": "4.5.0", "react-frame-component": "^5.2.4" diff --git a/packages/setting-form/CHANGELOG.md b/packages/setting-form/CHANGELOG.md index c730d274..e7f01bac 100644 --- a/packages/setting-form/CHANGELOG.md +++ b/packages/setting-form/CHANGELOG.md @@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.2.0](https://github.com/netease/tango/compare/@music163/tango-setting-form@1.1.0...@music163/tango-setting-form@1.2.0) (2024-05-17) + +### Bug Fixes + +- support quick set tid in SettingForm ([#151](https://github.com/netease/tango/issues/151)) ([1fc22a4](https://github.com/netease/tango/commit/1fc22a4535a8bdc12a018a41ebd5ab908fc46817)) + +### Features + +- refactor parse attribute value ([#149](https://github.com/netease/tango/issues/149)) ([ffaa276](https://github.com/netease/tango/commit/ffaa276b5c205ed962d37e2fdb358a703f8fad01)) + ## [1.0.2](https://github.com/netease/tango/compare/@music163/tango-setting-form@1.0.1...@music163/tango-setting-form@1.0.2) (2024-04-22) **Note:** Version bump only for package @music163/tango-setting-form diff --git a/packages/setting-form/package.json b/packages/setting-form/package.json index 19592f9c..7996f9f4 100644 --- a/packages/setting-form/package.json +++ b/packages/setting-form/package.json @@ -1,6 +1,6 @@ { "name": "@music163/tango-setting-form", - "version": "1.1.0", + "version": "1.2.0", "description": "setting form of tango-apps", "author": "wwsun ", "homepage": "", @@ -28,13 +28,13 @@ }, "dependencies": { "@ant-design/icons": "^4.8.0", - "@music163/tango-core": "^1.0.2", - "@music163/tango-helpers": "^1.0.0", - "@music163/tango-ui": "^1.0.3", + "@music163/tango-core": "^1.1.0", + "@music163/tango-helpers": "^1.1.0", + "@music163/tango-ui": "^1.1.0", "antd": "^4.24.2", "coral-system": "^1.0.5", - "mobx": "6.12.0", - "mobx-react-lite": "4.0.5" + "mobx": "6.12.3", + "mobx-react-lite": "4.0.7" }, "publishConfig": { "access": "public", diff --git a/packages/setting-form/src/form-item.tsx b/packages/setting-form/src/form-item.tsx index 54082280..5e0f17f5 100644 --- a/packages/setting-form/src/form-item.tsx +++ b/packages/setting-form/src/form-item.tsx @@ -1,12 +1,21 @@ -import React from 'react'; +import React, { useState } from 'react'; import { toJS } from 'mobx'; import { observer } from 'mobx-react-lite'; -import { clone, ComponentPropValidate, IComponentProp, useBoolean } from '@music163/tango-helpers'; -import { isWrappedByExpressionContainer } from '@music163/tango-core'; -import { ToggleButton, CodeOutlined } from '@music163/tango-ui'; +import { + clone, + ComponentPropValidate, + getCodeOfWrappedCode, + IComponentProp, + isNil, + isString, + isWrappedCode, + wrapCode, +} from '@music163/tango-helpers'; +import { ErrorBoundary } from '@music163/tango-ui'; +import { code2value, value2code } from '@music163/tango-core'; import { InputProps } from 'antd'; import { useFormModel, useFormVariable } from './context'; -import { FormControl } from './form-ui'; +import { FormControl, ToggleCodeButton } from './form-ui'; import { Box, Text } from 'coral-system'; import { ISetterOnChangeCallbackDetail } from './types'; @@ -43,6 +52,10 @@ export interface IFormItemCreateOptions { * 设置器别名列表,支持多个名字 */ alias?: string[]; + /** + * 设置器类型,value类设置器支持切换到codeSetter,默认为 value setter + */ + type?: 'code' | 'value'; /** * 渲染设置器使用的组件 */ @@ -64,9 +77,98 @@ export interface IFormItemCreateOptions { const defaultGetSetterProps = () => ({}); const defaultGetVisible = () => true; +function parseFieldValue(fieldValue: any) { + let value: any; + let code: string; + + if (!fieldValue) { + return []; + } + + const isCodeString = isString(fieldValue) && isWrappedCode(fieldValue); + if (isCodeString) { + code = getCodeOfWrappedCode(fieldValue); + value = code2value(code); + } else { + code = value2code(fieldValue); + value = fieldValue; + } + return [value, code]; +} + +interface UseSetterValueProps { + fieldValue: any; + setter?: string; + setterType?: IFormItemCreateOptions['type']; + /** + * 强制初始化为 codeSetter,适用于外部需要特别干预的情况 + */ + forceCodeSetter?: boolean; +} + +export function useSetterValue({ + fieldValue, + setter, + setterType, + forceCodeSetter, +}: UseSetterValueProps) { + const [value, code] = parseFieldValue(fieldValue); + const [isCodeSetter, setIsCodeSetter] = useState(() => { + if (forceCodeSetter) { + return true; + } + + // 同时不存在,表示是空置,使用默认模式 + if (!code && !value) { + return false; + } + + // value 解析出错的情况,使用 codeSetter + if (isNil(value)) { + return true; + } + + // 其他情况,均使用默认模式 + return false; + }); + + const toggleSetter = () => { + setIsCodeSetter(!isCodeSetter); + }; + + let fixedSetter: string; + let setterValue: any; + if (setterType === 'code') { + fixedSetter = setter; + setterValue = code; + } else { + fixedSetter = isCodeSetter ? 'codeSetter' : setter; + setterValue = isCodeSetter ? code : value; + } + + return { + value, + code, + setter: fixedSetter, + setterValue, // setter value + isCodeSetter, // 是否为 codeSetter + toggleSetter, // 切换 setter + }; +} + export function createFormItem(options: IFormItemCreateOptions) { const renderSetter = options.render ?? ((props: any) => React.createElement(options.component, props)); + const setterType = options.type ?? 'value'; // 设置器的模式 + + function getShowToggleCodeButton(disableVariableSetter = options.disableVariableSetter) { + if (setterType === 'code') { + // codeSetter 无需切换按钮 + return false; + } + // 如果用户设置了 disableVariableSetter,则不显示切换按钮 + return !disableVariableSetter; + } function FormItem({ name, @@ -75,11 +177,11 @@ export function createFormItem(options: IFormItemCreateOptions) { placeholder, docs, autoCompleteOptions, - setter, + setter: setterProp, setterProps, defaultValue, options: setterOptions, - disableVariableSetter: disableVariableSetterProp = options.disableVariableSetter, + disableVariableSetter, getVisible: getVisibleProp, getSetterProps: getSetterPropsProp, deprecated, @@ -91,36 +193,40 @@ export function createFormItem(options: IFormItemCreateOptions) { const { disableSwitchExpressionSetter, showItemSubtitle } = useFormVariable(); const model = useFormModel(); const field = model.getField(name); - const value = toJS(field.value ?? defaultValue); - const disableVariableSetter = disableSwitchExpressionSetter ?? disableVariableSetterProp; // Form 的设置优先 - const [isVariable, { toggle: toggleIsVariable }] = useBoolean( - () => !disableVariableSetter && isWrappedByExpressionContainer(value), - ); - const setterName = isVariable ? 'expressionSetter' : setter; + const fieldValue = toJS(field.value ?? defaultValue); + const { setterValue, setter, isCodeSetter, toggleSetter } = useSetterValue({ + fieldValue, + setter: setterProp, + setterType, + }); field.setConfig({ validate: validate || options.validate, }); - const baseComponentProps = clone( - { - value, - defaultValue, - onChange: field.handleChange, - status: field.error ? 'error' : undefined, - placeholder, - options: setterOptions, + let baseComponentProps: FormItemComponentProps = { + value: setterValue, + defaultValue, + onChange(value, detail) { + if ((setterType === 'code' || isCodeSetter) && isString(value) && value) { + value = wrapCode(value); + } + field.setValue(value, detail); }, - false, - ) as FormItemComponentProps; + status: field.error ? 'error' : undefined, + placeholder, + options: setterOptions, + }; + baseComponentProps = clone(baseComponentProps, false); let expProps = {}; // FIXME: 重新考虑这段代码的位置,外置这个逻辑 if ( - ['expressionSetter', 'expSetter', 'actionSetter', 'eventSetter'].includes(setter) || - isVariable + ['codeSetter', 'expressionSetter', 'expSetter', 'actionSetter', 'eventSetter'].includes( + setter, + ) ) { expProps = { modalTitle: title, @@ -131,10 +237,10 @@ export function createFormItem(options: IFormItemCreateOptions) { const getSetterProps = getSetterPropsProp || defaultGetSetterProps; // 从注册表中获取 expSetter - const ExpressionSetter = REGISTERED_FORM_ITEM_MAP['expressionSetter']?.config?.component; + const CodeSetter = REGISTERED_FORM_ITEM_MAP['codeSetter']?.config?.component; - const setterNode = isVariable ? ( - + const setterNode = isCodeSetter ? ( + ) : ( renderSetter({ ...expProps, @@ -148,9 +254,13 @@ export function createFormItem(options: IFormItemCreateOptions) { if (noStyle) { // 无样式模式 - return getVisible(model) ? setterNode :
; + return getVisible(model) ? setterNode :
; } + const showToggleCodeButton = getShowToggleCodeButton( + disableSwitchExpressionSetter || disableVariableSetter, + ); + return ( {extra} - {!disableVariableSetter ? ( - toggleIsVariable()} - > - - + {showToggleCodeButton ? ( + ) : null} } footer={footer} - data-setter={setterName} + data-setter={setter} data-field={name} > - {setterNode} + {setterNode} ); } @@ -202,9 +301,9 @@ const REGISTERED_FORM_ITEM_MAP: Record * @param config 注册选项 */ export function register(config: IFormItemCreateOptions) { - const names = [config.name, ...(config.alias ?? [])]; - names.forEach((name) => { - REGISTERED_FORM_ITEM_MAP[name] = createFormItem(config); + REGISTERED_FORM_ITEM_MAP[config.name] = createFormItem(config); + (Array.isArray(config.alias) ? config.alias : []).forEach((alias) => { + REGISTERED_FORM_ITEM_MAP[alias] = REGISTERED_FORM_ITEM_MAP[config.name]; }); } @@ -212,13 +311,13 @@ export function SettingFormItem(props: FormItemProps) { const { setter } = props; const Comp = REGISTERED_FORM_ITEM_MAP[setter]; if (Comp == null) { - const Fallback = REGISTERED_FORM_ITEM_MAP.expressionSetter; + const Fallback = REGISTERED_FORM_ITEM_MAP.codeSetter; return ( - {props.setter} is invalid + + invalid {props.setter}, fallback to codeSetter } /> diff --git a/packages/setting-form/src/form-model.tsx b/packages/setting-form/src/form-model.tsx index 7974b088..8788f46c 100644 --- a/packages/setting-form/src/form-model.tsx +++ b/packages/setting-form/src/form-model.tsx @@ -195,7 +195,7 @@ export class Field { error: computed, validate: action, handleBlur: action, - handleChange: action, + setValue: action, }); } @@ -248,7 +248,7 @@ export class Field { return this.validate('blur'); }; - handleChange = (nextValue: any, valueDetail: any) => { + setValue = (nextValue: any, valueDetail: any) => { this.detail = valueDetail; this.value = nextValue; return this.validate('change'); diff --git a/packages/setting-form/src/form-object.tsx b/packages/setting-form/src/form-object.tsx index 8d034dc8..8422f7f1 100644 --- a/packages/setting-form/src/form-object.tsx +++ b/packages/setting-form/src/form-object.tsx @@ -1,11 +1,12 @@ import React from 'react'; import { Box } from 'coral-system'; import { observer } from 'mobx-react-lite'; -import { IComponentProp } from '@music163/tango-helpers'; -import { SettingFormItem } from './form-item'; +import { IComponentProp, isString, wrapCode } from '@music163/tango-helpers'; +import { SettingFormItem, useSetterValue } from './form-item'; import { FormModelProvider, useFormModel } from './context'; -import { FormControlGroup } from './form-ui'; +import { FormControlGroup, ToggleCodeButton } from './form-ui'; import { isValidNestProps } from './helpers'; +import { CodeSetter } from './setters'; export type SettingFormObjectProps = IComponentProp; @@ -27,6 +28,12 @@ export const SettingFormObject = observer( const parent = useFormModel(); const visible = getVisible(parent); const subModel = parent.getSubModel(name); + const subModelValue = subModel.values || defaultValue; + const forceCodeSetter = isString(subModelValue); + const { setterValue, isCodeSetter, toggleSetter } = useSetterValue({ + fieldValue: subModelValue, + forceCodeSetter, // TODO: 最好是在内部 code2value 失败,而不是在这里强制设置 + }); return ( @@ -41,13 +48,31 @@ export const SettingFormObject = observer( parent.setValue(name, nextValue); parent.onChange(name, nextValue); // 非 Field 发起, 主动调一次 }} + extra={ + + } > - {props.map((prop) => { - if (isValidNestProps(prop.props)) { - return ; - } - return ; - })} + {isCodeSetter ? ( + { + const nextVal = val ? wrapCode(val) : undefined; + parent.setValue(name, nextVal); + parent.onChange(name, nextVal); // 非 Field 发起, 主动调一次 + }} + /> + ) : ( + props.map((prop) => { + if (isValidNestProps(prop.props)) { + return ; + } + return ; + }) + )} diff --git a/packages/setting-form/src/form-ui.tsx b/packages/setting-form/src/form-ui.tsx index e7b4af17..943c77ab 100644 --- a/packages/setting-form/src/form-ui.tsx +++ b/packages/setting-form/src/form-ui.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { css, Box, HTMLCoralProps, Link } from 'coral-system'; -import { Checkbox, Tooltip } from 'antd'; -import { CollapsePanel } from '@music163/tango-ui'; +import { Checkbox, Popconfirm, Tooltip } from 'antd'; +import { CodeOutlined, CollapsePanel, ToggleButton } from '@music163/tango-ui'; import { isString } from '@music163/tango-helpers'; import { WarningOutlined } from '@ant-design/icons'; @@ -35,7 +35,7 @@ export function FormControl({ {children} {footer} {!!error && ( - + {error} )} @@ -268,3 +268,66 @@ export function FormHeader({ title, extra, subTitle }: FormHeaderProps) { ); } + +export interface ToggleCodeButtonProps { + /** + * 在反选时是否需要用户确认操作 + */ + confirm?: boolean; + selected: boolean; + onToggle: () => void; +} + +export function ToggleCodeButton({ confirm, selected, onToggle }: ToggleCodeButtonProps) { + if (confirm && selected) { + return ( + { + e.stopPropagation(); + onToggle?.(); + }} + onCancel={(e) => { + e.stopPropagation(); + }} + > +
{ + e.stopPropagation(); + }} + > + + + +
+
+ ); + } + + return ( + { + e.stopPropagation(); + onToggle?.(); + }} + > + + + ); +} diff --git a/packages/setting-form/src/form.tsx b/packages/setting-form/src/form.tsx index 000cc57f..806d72f4 100644 --- a/packages/setting-form/src/form.tsx +++ b/packages/setting-form/src/form.tsx @@ -14,7 +14,7 @@ import { FormModelProvider, FormVariableProvider } from './context'; import { FormModel, FormModelOptionsType } from './form-model'; import { SettingFormObject } from './form-object'; import { isValidNestProps } from './helpers'; -import { registerBuiltinSetters } from './setter'; +import { registerBuiltinSetters } from './setters/register'; import { FormHeader } from './form-ui'; import { QuestionCircleOutlined } from '@ant-design/icons'; @@ -76,7 +76,7 @@ interface IFormTabsGroupOption { const internalGroups: IFormTabsGroupOption[] = [ { label: '基本', value: 'basic' }, - // { label: '事件', value: 'event' }, + { label: '事件', value: 'event' }, { label: '样式', value: 'style' }, { label: '高级', value: 'advanced' }, ]; @@ -104,7 +104,8 @@ export interface SettingFormProps { showIdentifier?: | false | { - identifierKey: string; + identifierKey: string; // 唯一标识符属性key + getIdentifier?: () => string; // 获取唯一标识符的方法 }; /** * 是否显示搜索框 @@ -127,7 +128,7 @@ export interface SettingFormProps { */ renderItemExtra?: (props: IComponentProp) => React.ReactNode; /** - * 是否允许表单项切换到表达式设置器 + * 是否禁用 codeSetter 切换,默认所有的 setter 都支持切换到 codeSetter */ disableSwitchExpressionSetter?: boolean; } @@ -217,11 +218,14 @@ export function SettingForm({ {showIdentifier && ( } diff --git a/packages/setting-form/src/index.ts b/packages/setting-form/src/index.ts index f68d4454..321eb795 100644 --- a/packages/setting-form/src/index.ts +++ b/packages/setting-form/src/index.ts @@ -3,3 +3,4 @@ export * from './form-item'; export * from './form-object'; export * from './form-model'; export * from './context'; +export * from './setters'; diff --git a/packages/setting-form/src/setter.tsx b/packages/setting-form/src/setter.tsx deleted file mode 100644 index 484120c8..00000000 --- a/packages/setting-form/src/setter.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { Input, InputProps } from 'antd'; -import { InputCode } from '@music163/tango-ui'; -import { FormItemComponentProps, register } from './form-item'; -import { Box, css } from 'coral-system'; - -export function ExpressionSetter({ value, onChange, ...rest }: FormItemComponentProps) { - return onChange?.(val)} value={value || ''} {...rest} />; -} - -export function TextSetter({ onChange, ...rest }: FormItemComponentProps) { - return onChange?.(e.target.value)} {...rest} />; -} - -const idInputStyle = css` - > .ant-input-borderless { - border: 1px solid transparent; - padding: 4px; - } - - > .ant-input-borderless:hover { - background-color: var(--tango-colors-fill1); - } -`; - -const idPattern = /^[a-z]+[\w]*$/; - -export function IdSetter({ - value: valueProp, - defaultValue, - onChange, - placeholder = '输入唯一组件ID', - ...rest -}: FormItemComponentProps) { - const [value, setValue] = useState(valueProp || defaultValue); - const [error, setError] = useState(''); - const [editable, setEditable] = useState(false); - - // value controlled - useEffect(() => { - setValue(valueProp); - }, [valueProp]); - - const __props: InputProps = editable - ? { - status: error ? 'error' : undefined, - onBlur() { - setEditable(false); - if (!error) { - onChange?.(value || undefined); - } - }, - onChange(e) { - const newValue = e.target.value; - setValue(e.target.value); - setError(newValue && !idPattern.test(newValue) ? 'error' : ''); - }, - } - : { - readOnly: true, - bordered: false, - onClick() { - setEditable(true); - }, - }; - - return ( - - - - ); -} - -export function registerBuiltinSetters() { - // 预注册基础 Setter - register({ - name: 'expressionSetter', - component: ExpressionSetter, - disableVariableSetter: true, - }); - - register({ - name: 'textSetter', - component: TextSetter, - }); - - register({ - name: 'idSetter', - component: IdSetter, - }); -} diff --git a/packages/designer/src/setters/bool-setter.tsx b/packages/setting-form/src/setters/bool-setter.tsx similarity index 73% rename from packages/designer/src/setters/bool-setter.tsx rename to packages/setting-form/src/setters/bool-setter.tsx index 8e2e6e3b..3f01599f 100644 --- a/packages/designer/src/setters/bool-setter.tsx +++ b/packages/setting-form/src/setters/bool-setter.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Switch } from 'antd'; -import { FormItemComponentProps } from '@music163/tango-setting-form/src/form-item'; +import { FormItemComponentProps } from '../form-item'; export function BoolSetter({ value, onChange, ...props }: FormItemComponentProps) { return onChange?.(val)} {...props} />; diff --git a/packages/setting-form/src/setters/code-setter.tsx b/packages/setting-form/src/setters/code-setter.tsx new file mode 100644 index 00000000..8f9bba7e --- /dev/null +++ b/packages/setting-form/src/setters/code-setter.tsx @@ -0,0 +1,23 @@ +import React, { useState } from 'react'; +import { FormItemComponentProps } from '../form-item'; +import { InputCode } from '@music163/tango-ui'; + +export function CodeSetter({ + value: valueProp, + onChange, + ...rest +}: FormItemComponentProps) { + const [value, setValue] = useState(valueProp || ''); + return ( + { + setValue(val); + }} + onBlur={() => { + onChange?.(value); + }} + value={value} + {...rest} + /> + ); +} diff --git a/packages/setting-form/src/setters/id-setter.tsx b/packages/setting-form/src/setters/id-setter.tsx new file mode 100644 index 00000000..4cb9b76b --- /dev/null +++ b/packages/setting-form/src/setters/id-setter.tsx @@ -0,0 +1,100 @@ +import React, { useEffect, useState } from 'react'; +import { Input, InputProps, Tooltip } from 'antd'; +import { css, Box } from 'coral-system'; +import { FormItemComponentProps } from '../form-item'; +import { ExclamationCircleOutlined, ThunderboltOutlined } from '@ant-design/icons'; +import { Action } from '@music163/tango-ui'; + +const idInputStyle = css` + > .ant-input-borderless { + border: 1px solid transparent; + padding: 4px; + } + + > .ant-input-borderless:hover { + background-color: var(--tango-colors-fill1); + } +`; + +const idPattern = /^[a-z]+[\w]*$/; + +export function IdSetter({ + value: valueProp, + defaultValue, + onChange, + placeholder = '输入唯一组件ID', + getId, + ...rest +}: FormItemComponentProps) { + const [value, setValue] = useState(valueProp || defaultValue); + const [error, setError] = useState(''); + const [editable, setEditable] = useState(false); + + // value controlled + useEffect(() => { + setValue(valueProp); + }, [valueProp]); + + const __props: InputProps = editable + ? { + status: error ? 'error' : undefined, + onBlur() { + setEditable(false); + if (!error) { + onChange?.(value || undefined); + } + }, + onChange(e) { + const newValue = e.target.value; + setValue(e.target.value); + setError( + newValue && !idPattern.test(newValue) + ? '非法的组件ID,必须使用字母开头的字母数字组合,例如 button1' + : '', + ); + }, + } + : { + readOnly: true, + bordered: false, + onClick() { + setEditable(true); + }, + }; + + const showQuickIdButton = !value || error; // 没有设置 id 或 id 不合法的时候显示快捷生成按钮 + + return ( + + + + + ) : null + } + suffix={ + showQuickIdButton ? ( + } + tooltip="快捷设置组件ID" + onClick={() => { + const id = getId?.(); + if (id) { + setValue(id); + onChange?.(id); + } + }} + /> + ) : null + } + /> + + ); +} diff --git a/packages/setting-form/src/setters/index.ts b/packages/setting-form/src/setters/index.ts new file mode 100644 index 00000000..ba8a3b59 --- /dev/null +++ b/packages/setting-form/src/setters/index.ts @@ -0,0 +1,6 @@ +export * from './bool-setter'; +export * from './code-setter'; +export * from './id-setter'; +export * from './number-setter'; +export * from './text-setter'; +export * from './register'; diff --git a/packages/designer/src/setters/number-setter.tsx b/packages/setting-form/src/setters/number-setter.tsx similarity index 67% rename from packages/designer/src/setters/number-setter.tsx rename to packages/setting-form/src/setters/number-setter.tsx index b5922eb0..7a6beccf 100644 --- a/packages/designer/src/setters/number-setter.tsx +++ b/packages/setting-form/src/setters/number-setter.tsx @@ -1,12 +1,12 @@ import React from 'react'; -import { InputNumber, InputNumberProps, Slider } from 'antd'; -import { FormItemComponentProps } from '@music163/tango-setting-form'; +import { InputNumber, Slider } from 'antd'; +import { FormItemComponentProps } from '../form-item'; const style = { width: '100%', }; -export function NumberSetter({ onChange, ...props }: InputNumberProps) { +export function NumberSetter({ onChange, ...props }: FormItemComponentProps) { return ( {}; -interface TextSetterProps extends Omit { - value?: string; - onChange?: (value: string) => void; -} - export function TextSetter({ value: valueProp, onChange = noop, - placeholder = '请输入', + placeholder = '请输入文本', ...props -}: TextSetterProps) { +}: FormItemComponentProps) { const [valueState, setValue] = useState(valueProp); useEffect(() => { @@ -28,7 +23,9 @@ export function TextSetter({ value={valueState} onChange={(e) => setValue(e.target.value)} onBlur={() => { - onChange(valueState); + if (valueState !== valueProp) { + onChange(valueState); + } }} {...props} /> @@ -43,7 +40,7 @@ const autoSize = { export function TextAreaSetter({ value: valueProp, onChange = noop, - placeholder = '请输入', + placeholder = '请输入文本', ...props }: FormItemComponentProps) { const [valueState, setValue] = useState(valueProp); @@ -59,7 +56,9 @@ export function TextAreaSetter({ value={valueState} onChange={(e) => setValue(e.target.value)} onBlur={() => { - onChange(valueState); + if (valueState !== valueProp) { + onChange(valueState); + } }} autoSize={autoSize} {...props} diff --git a/packages/ui/CHANGELOG.md b/packages/ui/CHANGELOG.md index b7667983..b0ad3eb4 100644 --- a/packages/ui/CHANGELOG.md +++ b/packages/ui/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.1.0](https://github.com/netease/tango/compare/@music163/tango-ui@1.0.3...@music163/tango-ui@1.1.0) (2024-05-17) + +### Features + +- refactor parse attribute value ([#149](https://github.com/netease/tango/issues/149)) ([ffaa276](https://github.com/netease/tango/commit/ffaa276b5c205ed962d37e2fdb358a703f8fad01)) + ## [1.0.2](https://github.com/netease/tango/compare/@music163/tango-ui@1.0.1...@music163/tango-ui@1.0.2) (2024-04-22) ### Bug Fixes diff --git a/packages/ui/package.json b/packages/ui/package.json index 64f18906..45f056ba 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@music163/tango-ui", - "version": "1.0.3", + "version": "1.1.0", "description": "ui widgets of tango", "keywords": [ "react", @@ -34,12 +34,12 @@ }, "dependencies": { "@ant-design/icons": "^4.8.0", - "@codemirror/autocomplete": "^6.11.1", - "@codemirror/lang-javascript": "^6.2.1", - "@codemirror/lint": "^6.4.2", - "@codemirror/search": "^6.5.5", - "@music163/tango-helpers": "^1.0.0", - "@uiw/react-codemirror": "^4.21.21", + "@codemirror/autocomplete": "^6.16.0", + "@codemirror/lang-javascript": "^6.2.2", + "@codemirror/lint": "^6.7.1", + "@codemirror/search": "^6.5.6", + "@music163/tango-helpers": "^1.1.0", + "@uiw/react-codemirror": "^4.22.0", "antd": "^4.24.2", "classnames": "^2.5.1", "coral-system": "^1.0.5", diff --git a/packages/ui/src/drag-panel.tsx b/packages/ui/src/drag-panel.tsx index f8e6d403..13ba97ff 100644 --- a/packages/ui/src/drag-panel.tsx +++ b/packages/ui/src/drag-panel.tsx @@ -3,6 +3,7 @@ import { Box, Text, styled } from 'coral-system'; import { Popover, PopoverProps, IconFont } from '@music163/tango-ui'; import Draggable from 'react-draggable'; import { CloseOutlined } from '@ant-design/icons'; +import { noop } from '@music163/tango-helpers'; const CloseIcon = styled(CloseOutlined)` cursor: pointer; @@ -37,16 +38,26 @@ export function DragPanel({ children, width = 330, extra, + onOpenChange = noop, ...props }: DragPanelProps) { const [open, setOpen] = useState(false); - const footerNode = typeof footer === 'function' ? footer(() => setOpen(false)) : footer; + const footerNode = + typeof footer === 'function' + ? footer(() => { + setOpen(false); + onOpenChange(false); + }) + : footer; return ( { + setOpen(innerOpen); + onOpenChange(innerOpen); + }} overlay={ { setOpen(false); - props?.onOpenChange?.(false); + onOpenChange(false); }} /> diff --git a/packages/ui/src/input-code.tsx b/packages/ui/src/input-code.tsx index c799de52..d415b872 100644 --- a/packages/ui/src/input-code.tsx +++ b/packages/ui/src/input-code.tsx @@ -1,5 +1,5 @@ import React, { useMemo } from 'react'; -import { Box, HTMLCoralProps } from 'coral-system'; +import { Box, HTMLCoralProps, css } from 'coral-system'; import CodeMirror, { ReactCodeMirrorProps } from '@uiw/react-codemirror'; import { javascript, javascriptLanguage, esLint } from '@codemirror/lang-javascript'; import { CompletionContext } from '@codemirror/autocomplete'; @@ -200,6 +200,7 @@ function useInputCode({ lineNumbers: showLineNumbers ?? lineNumbers, foldGutter: showFoldGutter ?? foldGutter, searchKeymap: false, // 默认关闭搜索快捷键,原因:https://github.com/uiwjs/react-codemirror/issues/280 + scrollbarStyle: 'null', }, }; } diff --git a/packages/ui/src/popover.tsx b/packages/ui/src/popover.tsx index e76771d8..d260ab1d 100644 --- a/packages/ui/src/popover.tsx +++ b/packages/ui/src/popover.tsx @@ -1,29 +1,50 @@ -import React, { useState, useRef, useEffect, useMemo } from 'react'; +import React, { useState, useRef, useEffect, useMemo, useCallback } from 'react'; import ReactDOM from 'react-dom'; +import { noop } from '@music163/tango-helpers'; +import { Box } from 'coral-system'; export interface PopoverProps { open?: boolean; - // 浮层内容 + /** + * 浮层内容 + */ overlay: React.ReactNode; + /** + * 浮层打开或关闭时的回调 + */ onOpenChange?: (open: boolean) => void; - children?: React.ReactNode; /** * 浮层被遮挡时自动调整位置 */ autoAdjustOverflow?: boolean; + /** + * 手动唤起时的位置 + */ left?: number; + /** + * 手动唤起时的位置 + */ top?: number; + /** + * z-index + */ zIndex?: number; + /** + * popoverStyle + */ + popoverStyle?: React.CSSProperties; + children?: React.ReactNode; } export const Popover: React.FC = ({ open, overlay, - onOpenChange, autoAdjustOverflow = true, left: controlledLeft, top: controlledTop, children, + popoverStyle, + onOpenChange = noop, zIndex = 9999, }) => { const [visible, setVisible] = useState(false); @@ -49,15 +70,18 @@ export const Popover: React.FC = ({ } }, [controlledTop]); - const handleClick = (e: React.MouseEvent) => { - e.preventDefault(); - const x = e.clientX; - const y = e.clientY; - setLeft(x); - setTop(y + 10); - setVisible(true); - onOpenChange(true); - }; + const handleClick = useCallback( + (e: React.MouseEvent) => { + e.preventDefault(); + const x = e.clientX; + const y = e.clientY; + setLeft(x); + setTop(y + 10); + setVisible(true); + onOpenChange(true); + }, + [onOpenChange], + ); useEffect(() => { setVisible(open); @@ -82,20 +106,24 @@ export const Popover: React.FC = ({ } }, [visible, autoAdjustOverflow]); - const popoverStyle: React.CSSProperties = { - display: visible ? 'block' : 'none', - position: 'fixed', - left, - top, - zIndex, - }; + const overlayStyle: React.CSSProperties = useMemo( + () => ({ + display: visible ? 'block' : 'none', + position: 'fixed', + left, + top, + zIndex, + ...popoverStyle, + }), + [left, popoverStyle, top, visible, zIndex], + ); const overlayDom = ( -
-
+ + {overlay} -
-
+
+ ); return ( diff --git a/yarn.lock b/yarn.lock index 0feeb4c1..c651b5e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -110,28 +110,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@7.23.2": - version "7.23.2" - resolved "https://registry.npmmirror.com/@babel/core/-/core-7.23.2.tgz" - integrity sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helpers" "^7.23.2" - "@babel/parser" "^7.23.0" - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.2" - "@babel/types" "^7.23.0" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/core@^7.1.0", "@babel/core@^7.11.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.17.9", "@babel/core@^7.19.6", "@babel/core@^7.21.4", "@babel/core@^7.23.6", "@babel/core@^7.7.5": +"@babel/core@7.23.6", "@babel/core@^7.1.0", "@babel/core@^7.11.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.17.9", "@babel/core@^7.19.6", "@babel/core@^7.21.4", "@babel/core@^7.23.6", "@babel/core@^7.7.5": version "7.23.6" resolved "https://registry.npmmirror.com/@babel/core/-/core-7.23.6.tgz" integrity sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw== @@ -152,16 +131,7 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/eslint-parser@7.22.15": - version "7.22.15" - resolved "https://registry.npmmirror.com/@babel/eslint-parser/-/eslint-parser-7.22.15.tgz" - integrity sha512-yc8OOBIQk1EcRrpizuARSQS0TWAcOMpEJ1aafhNznaeYkeL+OhqnDObGFylB8ka8VFF/sZc+S4RzHyO+3LjQxg== - dependencies: - "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" - eslint-visitor-keys "^2.1.0" - semver "^6.3.1" - -"@babel/eslint-parser@^7.16.3", "@babel/eslint-parser@^7.23.3": +"@babel/eslint-parser@7.23.3", "@babel/eslint-parser@^7.16.3", "@babel/eslint-parser@^7.23.3": version "7.23.3" resolved "https://registry.npmmirror.com/@babel/eslint-parser/-/eslint-parser-7.23.3.tgz" integrity sha512-9bTuNlyx7oSstodm1cR1bECj4fkiknsDa1YniISkJemMY3DGhJNYBECbe6QD/q54mp2J8VO66jW3/7uP//iFCw== @@ -170,7 +140,7 @@ eslint-visitor-keys "^2.1.0" semver "^6.3.1" -"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.23.0", "@babel/generator@^7.23.5", "@babel/generator@^7.23.6", "@babel/generator@^7.7.2": +"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.23.5", "@babel/generator@^7.23.6", "@babel/generator@^7.7.2": version "7.23.6" resolved "https://registry.npmmirror.com/@babel/generator/-/generator-7.23.6.tgz" integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== @@ -288,7 +258,7 @@ dependencies: "@babel/types" "^7.22.15" -"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.23.0", "@babel/helper-module-transforms@^7.23.3": +"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.23.3": version "7.23.3" resolved "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz" integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== @@ -379,7 +349,7 @@ "@babel/template" "^7.22.15" "@babel/types" "^7.22.19" -"@babel/helpers@^7.12.5", "@babel/helpers@^7.23.2", "@babel/helpers@^7.23.6": +"@babel/helpers@^7.12.5", "@babel/helpers@^7.23.6": version "7.23.6" resolved "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.23.6.tgz" integrity sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA== @@ -397,7 +367,7 @@ chalk "^2.4.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0", "@babel/parser@^7.23.5", "@babel/parser@^7.23.6": +"@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.5", "@babel/parser@^7.23.6": version "7.23.6" resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.23.6.tgz" integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== @@ -879,16 +849,7 @@ "@babel/helper-module-transforms" "^7.23.3" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-commonjs@7.23.0": - version "7.23.0" - resolved "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz" - integrity sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ== - dependencies: - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-simple-access" "^7.22.5" - -"@babel/plugin-transform-modules-commonjs@^7.23.3": +"@babel/plugin-transform-modules-commonjs@7.23.3", "@babel/plugin-transform-modules-commonjs@^7.23.3": version "7.23.3" resolved "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz" integrity sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA== @@ -1296,14 +1257,7 @@ resolved "https://registry.npmmirror.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@7.23.2": - version "7.23.2" - resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.2.tgz" - integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.7", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.20.0", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.5.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.7.7", "@babel/runtime@^7.8.4": +"@babel/runtime@7.23.6", "@babel/runtime@^7.0.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.7", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.20.0", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.5.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.7.7", "@babel/runtime@^7.8.4": version "7.23.6" resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.6.tgz" integrity sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ== @@ -1326,7 +1280,7 @@ "@babel/parser" "^7.22.15" "@babel/types" "^7.22.15" -"@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.23.2", "@babel/traverse@^7.23.5", "@babel/traverse@^7.23.6", "@babel/traverse@^7.4.5": +"@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.23.5", "@babel/traverse@^7.23.6", "@babel/traverse@^7.4.5": version "7.23.6" resolved "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.23.6.tgz" integrity sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ== @@ -1374,7 +1328,7 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@codemirror/autocomplete@^6.0.0", "@codemirror/autocomplete@^6.11.1": +"@codemirror/autocomplete@^6.0.0": version "6.11.1" resolved "https://registry.npmmirror.com/@codemirror/autocomplete/-/autocomplete-6.11.1.tgz" integrity sha512-L5UInv8Ffd6BPw0P3EF7JLYAMeEbclY7+6Q11REt8vhih8RuLreKtPy/xk8wPxs4EQgYqzI7cdgpiYwWlbS/ow== @@ -1384,6 +1338,16 @@ "@codemirror/view" "^6.17.0" "@lezer/common" "^1.0.0" +"@codemirror/autocomplete@^6.16.0": + version "6.16.0" + resolved "https://registry.npmmirror.com/@codemirror/autocomplete/-/autocomplete-6.16.0.tgz#595eb30099ba91a835ed65ed8ff7497388f604b3" + integrity sha512-P/LeCTtZHRTCU4xQsa89vSKWecYv1ZqwzOd5topheGRf+qtacFgBeIMQi3eL8Kt/BUNvxUWkx+5qP2jlGoARrg== + dependencies: + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.17.0" + "@lezer/common" "^1.0.0" + "@codemirror/commands@^6.0.0", "@codemirror/commands@^6.1.0": version "6.3.2" resolved "https://registry.npmmirror.com/@codemirror/commands/-/commands-6.3.2.tgz" @@ -1394,10 +1358,10 @@ "@codemirror/view" "^6.0.0" "@lezer/common" "^1.1.0" -"@codemirror/lang-javascript@^6.2.1": - version "6.2.1" - resolved "https://registry.npmmirror.com/@codemirror/lang-javascript/-/lang-javascript-6.2.1.tgz" - integrity sha512-jlFOXTejVyiQCW3EQwvKH0m99bUYIw40oPmFjSX2VS78yzfe0HELZ+NEo9Yfo1MkGRpGlj3Gnu4rdxV1EnAs5A== +"@codemirror/lang-javascript@^6.2.2": + version "6.2.2" + resolved "https://registry.npmmirror.com/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz#7141090b22994bef85bcc5608a3bc1257f2db2ad" + integrity sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg== dependencies: "@codemirror/autocomplete" "^6.0.0" "@codemirror/language" "^6.6.0" @@ -1419,7 +1383,7 @@ "@lezer/lr" "^1.0.0" style-mod "^4.0.0" -"@codemirror/lint@^6.0.0", "@codemirror/lint@^6.4.2": +"@codemirror/lint@^6.0.0": version "6.4.2" resolved "https://registry.npmmirror.com/@codemirror/lint/-/lint-6.4.2.tgz" integrity sha512-wzRkluWb1ptPKdzlsrbwwjYCPLgzU6N88YBAmlZi8WFyuiEduSd05MnJYNogzyc8rPK7pj6m95ptUApc8sHKVA== @@ -1428,7 +1392,16 @@ "@codemirror/view" "^6.0.0" crelt "^1.0.5" -"@codemirror/search@^6.0.0", "@codemirror/search@^6.5.5": +"@codemirror/lint@^6.7.1": + version "6.7.1" + resolved "https://registry.npmmirror.com/@codemirror/lint/-/lint-6.7.1.tgz#bed4b3a38785678efbe683efe0e61d8ccf478d58" + integrity sha512-rELba6QJD20/bNXWP/cKTGLrwVEcpa2ViwULCV03ONcY1Je85++7sczVRUlnE4TJMjatx3IJTz6HX4NXi+moXw== + dependencies: + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + crelt "^1.0.5" + +"@codemirror/search@^6.0.0": version "6.5.5" resolved "https://registry.npmmirror.com/@codemirror/search/-/search-6.5.5.tgz" integrity sha512-PIEN3Ke1buPod2EHbJsoQwlbpkz30qGZKcnmH1eihq9+bPQx8gelauUwLYaY4vBOuBAuEhmpDLii4rj/uO0yMA== @@ -1437,6 +1410,15 @@ "@codemirror/view" "^6.0.0" crelt "^1.0.5" +"@codemirror/search@^6.5.6": + version "6.5.6" + resolved "https://registry.npmmirror.com/@codemirror/search/-/search-6.5.6.tgz#8f858b9e678d675869112e475f082d1e8488db93" + integrity sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q== + dependencies: + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + crelt "^1.0.5" + "@codemirror/state@^6.0.0", "@codemirror/state@^6.1.1", "@codemirror/state@^6.1.4", "@codemirror/state@^6.2.0": version "6.3.3" resolved "https://registry.npmmirror.com/@codemirror/state/-/state-6.3.3.tgz" @@ -1774,6 +1756,30 @@ esquery "^1.5.0" jsdoc-type-pratt-parser "~4.0.0" +"@esbuild-kit/cjs-loader@^2.4.1": + version "2.4.4" + resolved "https://registry.npmmirror.com/@esbuild-kit/cjs-loader/-/cjs-loader-2.4.4.tgz#8638177732e2de258a3243597bfdba082993c442" + integrity sha512-NfsJX4PdzhwSkfJukczyUiZGc7zNNWZcEAyqeISpDnn0PTfzMJR1aR8xAIPskBejIxBJbIgCCMzbaYa9SXepIg== + dependencies: + "@esbuild-kit/core-utils" "^3.2.3" + get-tsconfig "^4.7.0" + +"@esbuild-kit/core-utils@^3.0.0", "@esbuild-kit/core-utils@^3.2.3", "@esbuild-kit/core-utils@^3.3.2": + version "3.3.2" + resolved "https://registry.npmmirror.com/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz#186b6598a5066f0413471d7c4d45828e399ba96c" + integrity sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ== + dependencies: + esbuild "~0.18.20" + source-map-support "^0.5.21" + +"@esbuild-kit/esm-loader@^2.5.4": + version "2.6.5" + resolved "https://registry.npmmirror.com/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz#6eedee46095d7d13b1efc381e2211ed1c60e64ea" + integrity sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA== + dependencies: + "@esbuild-kit/core-utils" "^3.3.2" + get-tsconfig "^4.7.0" + "@esbuild/android-arm64@0.17.19": version "0.17.19" resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" @@ -2698,16 +2704,9 @@ "@music163/tango-boot" "^0.3.0" coral-system "^1.0.6" -"@music163/request@^0.1.2": - version "0.1.2" - resolved "https://registry.npmjs.org/@music163/request/-/request-0.1.2.tgz" - integrity sha512-zOI0REeABp5qVq7it1KT7fzdEmIkbJpdoitmpXquO0qS7UXtQlh9DDhMT9eXCJ8NDqswGRZir2iHRxHDswwFjA== - dependencies: - axios "^1.4.0" - "@music163/request@^0.2.0": version "0.2.0" - resolved "https://registry.npmjs.org/@music163/request/-/request-0.2.0.tgz" + resolved "https://registry.npmjs.org/@music163/request/-/request-0.2.0.tgz#f7114ffa5582939da7996d780052aff34a0406d9" integrity sha512-nCO0gMOaYSEA0fAkvXez9JtEPoZEw3+dJzQGLCwEpL/nV76ouZoOZ+gFCjF6/J2Gh3ZGOqb/8jVaNFVlr3QjRQ== dependencies: axios "^1.4.0" @@ -4082,6 +4081,13 @@ deepmerge "^4.2.2" svgo "^2.8.0" +"@swc/helpers@0.5.1": + version "0.5.1" + resolved "https://registry.npmmirror.com/@swc/helpers/-/helpers-0.5.1.tgz#e9031491aa3f26bfcc974a67f48bd456c8a5357a" + integrity sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg== + dependencies: + tslib "^2.4.0" + "@tootallnate/once@2": version "2.0.0" resolved "https://registry.npmmirror.com/@tootallnate/once/-/once-2.0.0.tgz" @@ -4735,10 +4741,10 @@ "@typescript-eslint/types" "6.15.0" eslint-visitor-keys "^3.4.1" -"@uiw/codemirror-extensions-basic-setup@4.21.21": - version "4.21.21" - resolved "https://registry.npmmirror.com/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.21.21.tgz" - integrity sha512-+0i9dPrRSa8Mf0CvyrMvnAhajnqwsP3IMRRlaHDRgsSGL8igc4z7MhvUPn+7cWFAAqWzQRhMdMSWzo6/TEa3EA== +"@uiw/codemirror-extensions-basic-setup@4.22.0": + version "4.22.0" + resolved "https://registry.npmmirror.com/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.22.0.tgz#383962e76025537ec81a32ec00145e7cc4eb67f1" + integrity sha512-3vdpMq1Oj3qRKGjNgi5NeMxWem/cJ/gL0dZSu62MLBR4w3BWlEVi6xsk/MEk0+mT1AVKOzQV3jFS5y7mzxrfeA== dependencies: "@codemirror/autocomplete" "^6.0.0" "@codemirror/commands" "^6.0.0" @@ -4748,90 +4754,106 @@ "@codemirror/state" "^6.0.0" "@codemirror/view" "^6.0.0" -"@uiw/react-codemirror@^4.21.21": - version "4.21.21" - resolved "https://registry.npmmirror.com/@uiw/react-codemirror/-/react-codemirror-4.21.21.tgz" - integrity sha512-PaxBMarufMWoR0qc5zuvBSt76rJ9POm9qoOaJbqRmnNL2viaF+d+Paf2blPSlm1JSnqn7hlRjio+40nZJ9TKzw== +"@uiw/react-codemirror@^4.22.0": + version "4.22.0" + resolved "https://registry.npmmirror.com/@uiw/react-codemirror/-/react-codemirror-4.22.0.tgz#47ad835ecaba756376a30f33216adaa8ccb7a8e8" + integrity sha512-ZbC9NX1458McehTN0XGVUHK/hb79DJXwwP3SfvumcjzIx/zIwAK0wtGABposlGHpxifIF6RAxMmUcL3gDVpiMA== dependencies: "@babel/runtime" "^7.18.6" "@codemirror/commands" "^6.1.0" "@codemirror/state" "^6.1.1" "@codemirror/theme-one-dark" "^6.0.0" - "@uiw/codemirror-extensions-basic-setup" "4.21.21" + "@uiw/codemirror-extensions-basic-setup" "4.22.0" codemirror "^6.0.0" -"@umijs/ast@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/ast/-/ast-4.0.89.tgz" - integrity sha512-19J5oQubKa/TiAFuQIEp9AZXN0WcGLtWxDdLyVS0ja8T8q0/74yUDTIdbz6zb/i3dX3qeySoi5lQwHc9i/i3Aw== +"@umijs/ast@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/ast/-/ast-4.2.3.tgz#00a3e5a2a7da828d3cf8a5a21e0c3a064afdc854" + integrity sha512-gsvJ/rYguPTJ3oTdeeTQR5e4T6fhZWKK9bYFdqufflZArZN7/5O2vpeRW0FYb26AXqZ+DWG4FFw0tL815jNY7A== dependencies: - "@umijs/bundler-utils" "4.0.89" + "@umijs/bundler-utils" "4.2.3" -"@umijs/babel-preset-umi@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/babel-preset-umi/-/babel-preset-umi-4.0.89.tgz" - integrity sha512-Q9/SaEU3K9q+aNMmwIxcfkqtYdhE4n/J0BRx0XUo71rN0mN+4EOuOPLNMD8hKtJw5CZeASeS3qQbQKd44SjOow== +"@umijs/babel-preset-umi@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/babel-preset-umi/-/babel-preset-umi-4.2.3.tgz#c14b829cc12dcafb497194f4706b7c2cab2dbdc3" + integrity sha512-7FnvIQhcO2v14qydKjm0gAViIreQ3XAPx0u4XZc/qVGifscU5HULuiuYXmZnOo4ov8fJK3yHGjsdWy7rQc3bMA== dependencies: - "@babel/runtime" "7.23.2" + "@babel/runtime" "7.23.6" "@bloomberg/record-tuple-polyfill" "0.0.4" - "@umijs/bundler-utils" "4.0.89" - "@umijs/utils" "4.0.89" - core-js "3.28.0" + "@umijs/bundler-utils" "4.2.3" + "@umijs/utils" "4.2.3" + core-js "3.34.0" -"@umijs/bundler-esbuild@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/bundler-esbuild/-/bundler-esbuild-4.0.89.tgz" - integrity sha512-VF/67qtDmSnTZLTK6tIPUb3meKhkzha0kalSYlrvYLkOxGVIfKrxgDZB3hqi2pmwPdNiDxP16Cp1OewCZed4Gg== +"@umijs/bundler-esbuild@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/bundler-esbuild/-/bundler-esbuild-4.2.3.tgz#80d525c3de0f50ba60058aaf62b57035b75c2888" + integrity sha512-ujQHSqcBufTQnFwZGRbEAptqgsMawrOq9cgQy14FmhKfnG4878BHSitengGjtD+/UeshYwePL6TZYHDjqSiAIg== dependencies: - "@umijs/bundler-utils" "4.0.89" - "@umijs/utils" "4.0.89" + "@umijs/bundler-utils" "4.2.3" + "@umijs/utils" "4.2.3" enhanced-resolve "5.9.3" postcss "^8.4.21" postcss-flexbugs-fixes "5.0.2" postcss-preset-env "7.5.0" -"@umijs/bundler-utils@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/bundler-utils/-/bundler-utils-4.0.89.tgz" - integrity sha512-/nKdEj0ku9MX5RYYLzDObuvDBb1sd89XD2Opldk7kgLbLw1iePksrWtP8gR5X2UGjqtEZYvcfrYFt0jV0LCcQg== +"@umijs/bundler-mako@0.4.16": + version "0.4.16" + resolved "https://registry.npmmirror.com/@umijs/bundler-mako/-/bundler-mako-0.4.16.tgz#62ba2af091b64f29dd63f04d4e7c678afd0fad4b" + integrity sha512-gyCvNSKnmj/256ugW+8/iPdopOUTYZ+tYFBL1BW2ffUvYVa42lbuu6inNpfsWC4eqmm7CB6KvzaxVWxp2K2mFA== dependencies: - "@umijs/utils" "4.0.89" + "@umijs/bundler-utils" "^4.0.81" + "@umijs/mako" "0.4.16" + chalk "^4.1.2" + compression "^1.7.4" + connect-history-api-fallback "^2.0.0" + cors "^2.8.5" + express "^4.18.2" + lodash "^4.17.21" + rimraf "5.0.1" + webpack-5-chain "8.0.1" + +"@umijs/bundler-utils@4.2.3", "@umijs/bundler-utils@^4.0.81": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/bundler-utils/-/bundler-utils-4.2.3.tgz#b817be9df858cc76382249b5c97c2a1cc7116bcf" + integrity sha512-RKOdHKk2Sa1FOF7vS343TWiMl8z0H9pZ4BqQms8iqtJLu+2WJfo537+/k4CmGVFY6TmjrZ8NRG6wj6K9o2qQ0A== + dependencies: + "@umijs/utils" "4.2.3" esbuild "0.17.19" regenerate "^1.4.2" regenerate-unicode-properties "10.1.1" spdy "^4.0.2" -"@umijs/bundler-vite@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/bundler-vite/-/bundler-vite-4.0.89.tgz" - integrity sha512-4dfBmVK44AqsJm1+YhFijKXcrHoM26vO9Ju5Us4+J0Ca3rDUtWQZJ9xFEkqsNsf7AMaJ7B8zDd422sThvvSXGQ== +"@umijs/bundler-vite@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/bundler-vite/-/bundler-vite-4.2.3.tgz#2b4c113417dcf8e55261e5aef714e9fc0e186316" + integrity sha512-QPxGkCKN0O2pt1mpnnt7tfvxRQiajS0sA+GtPt7jD5OJY3aAfILUugrasHx56YhAz9Iq8L/RtfxWU7/JAwzpxA== dependencies: "@svgr/core" "6.5.1" - "@umijs/bundler-utils" "4.0.89" - "@umijs/utils" "4.0.89" + "@umijs/bundler-utils" "4.2.3" + "@umijs/utils" "4.2.3" "@vitejs/plugin-react" "4.0.0" - core-js "3.28.0" + core-js "3.34.0" less "4.1.3" postcss-preset-env "7.5.0" rollup-plugin-visualizer "5.9.0" systemjs "^6.14.1" - vite "4.3.1" + vite "4.5.2" -"@umijs/bundler-webpack@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/bundler-webpack/-/bundler-webpack-4.0.89.tgz" - integrity sha512-BfCpmxDIzhRa7wnEAODOj5auHXd/n954qt0QUkUUlGJYa5GrtgRiKsGtnwew+8uVX1vm0y7XDqnCU+trWAq0nQ== +"@umijs/bundler-webpack@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/bundler-webpack/-/bundler-webpack-4.2.3.tgz#83dce64453c69c1e8fa4fc5a05e27676ea1fe405" + integrity sha512-IZVO0sa1oPllsFsJgqyfRdNEBuybl9oH2lV5CHrd3hgKeDBXKkjIH7D9AAXXgFsOvk95mVUaO3iestX5Nx7n2g== dependencies: "@svgr/core" "6.5.1" "@svgr/plugin-jsx" "^6.5.1" "@svgr/plugin-svgo" "^6.5.1" "@types/hapi__joi" "17.1.9" - "@umijs/babel-preset-umi" "4.0.89" - "@umijs/bundler-utils" "4.0.89" + "@umijs/babel-preset-umi" "4.2.3" + "@umijs/bundler-utils" "4.2.3" "@umijs/case-sensitive-paths-webpack-plugin" "^1.0.1" - "@umijs/mfsu" "4.0.89" + "@umijs/mfsu" "4.2.3" "@umijs/react-refresh-webpack-plugin" "0.5.11" - "@umijs/utils" "4.0.89" + "@umijs/utils" "4.2.3" cors "^2.8.5" css-loader "6.7.1" es5-imcompatible-versions "^0.1.78" @@ -4849,13 +4871,13 @@ resolved "https://registry.npmmirror.com/@umijs/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-1.0.1.tgz" integrity sha512-kDKJ8yTarxwxGJDInG33hOpaQRZ//XpNuuznQ/1Mscypw6kappzFmrBr2dOYave++K7JHouoANF354UpbEQw0Q== -"@umijs/core@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/core/-/core-4.0.89.tgz" - integrity sha512-S6K2Y8h6DyRoPP0EVrYgDs3iO7B2hHcd9QN+n6v0JHzhkHMVvsPnGlPx66yAptACBlBirR/ICIm0Pr1CrDADbg== +"@umijs/core@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/core/-/core-4.2.3.tgz#c7f8fc74e63f2d8b49913ebc02b5d500b0906480" + integrity sha512-zsesEQmoJWop3HXENpz7xZ2CRGMXXc4Qj1OFmuogQXUW1VX6z7emFg0Zbk0OIBfL03vmCpdkNTExlsPX3yj0aw== dependencies: - "@umijs/bundler-utils" "4.0.89" - "@umijs/utils" "4.0.89" + "@umijs/bundler-utils" "4.2.3" + "@umijs/utils" "4.2.3" "@umijs/did-you-know@1.0.3": version "1.0.3" @@ -4930,17 +4952,17 @@ "@babel/runtime" "^7.7.6" query-string "^6.13.6" -"@umijs/lint@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/lint/-/lint-4.0.89.tgz" - integrity sha512-z7pSpZoAecTltLwBEiyyzZYY3wPlg7DA5U4llWJbkfz/U0TdKgeDAzH6cq1SpvuRBsLTO3aiD6+6DP0NDuU82g== +"@umijs/lint@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/lint/-/lint-4.2.3.tgz#ec957fd0513945c8ae889abb46b840b7360d4150" + integrity sha512-lub5igyO9PIJ9ksl8oXdgMGgZMy2S7CcFuDLlVYlTj7GWOHcQVpdFgGAVJN5jr+nvHgJgf1j8fmnUA+Me82b6w== dependencies: - "@babel/core" "7.23.2" - "@babel/eslint-parser" "7.22.15" + "@babel/core" "7.23.6" + "@babel/eslint-parser" "7.23.3" "@stylelint/postcss-css-in-js" "^0.38.0" "@typescript-eslint/eslint-plugin" "^5.62.0" "@typescript-eslint/parser" "^5.62.0" - "@umijs/babel-preset-umi" "4.0.89" + "@umijs/babel-preset-umi" "4.2.3" eslint-plugin-jest "27.2.3" eslint-plugin-react "7.33.2" eslint-plugin-react-hooks "4.6.0" @@ -4948,51 +4970,85 @@ postcss-syntax "0.36.2" stylelint-config-standard "25.0.0" -"@umijs/mfsu@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/mfsu/-/mfsu-4.0.89.tgz" - integrity sha512-CcpIh88r5JaiYtPkr/Dnch6Pm8e02wHPy7BWW3A6ina0SZS4o5K2BPr/fbWoFRrfWLHQT4BGvwIkz1LavDieZQ== +"@umijs/mako-darwin-arm64@0.4.16": + version "0.4.16" + resolved "https://registry.npmmirror.com/@umijs/mako-darwin-arm64/-/mako-darwin-arm64-0.4.16.tgz#827fb9957292b70b6c23d98f9538c88096347090" + integrity sha512-UbVonLm1cYoeUCTskqlrovhloRDCW9tt3FgX8eWbomRiy53YaMPUw2BOl+iOQ9/U/wGhg8gIXrH7jMHnzpfydw== + +"@umijs/mako-darwin-x64@0.4.16": + version "0.4.16" + resolved "https://registry.npmmirror.com/@umijs/mako-darwin-x64/-/mako-darwin-x64-0.4.16.tgz#89ab298f16fe5c65f3e3a8c8c301b66f7010932e" + integrity sha512-3yrqKN3jnajUIvND0Nks5yak34SHHeKzhcPuVzQk5mMhcCUMlRFM1XCcn9bIvzKKbX/RRPf/gcwl3u56qNnRwg== + +"@umijs/mako-linux-x64-gnu@0.4.16": + version "0.4.16" + resolved "https://registry.npmmirror.com/@umijs/mako-linux-x64-gnu/-/mako-linux-x64-gnu-0.4.16.tgz#2c75315bbf1fa9de522b48db95fa99028814020b" + integrity sha512-V0RnrvVAjW/D1AALKHhAoorBwP8C2r65tDU9KCfrdSW08qCayMnsAO5MI1OCzZUwbqs5zX9thwTpA/rkOKV7qg== + +"@umijs/mako@0.4.16": + version "0.4.16" + resolved "https://registry.npmmirror.com/@umijs/mako/-/mako-0.4.16.tgz#cf7c2404c78d250f6dbca9bbcb02249edb3ff53c" + integrity sha512-jJASCwzlg8ZUXADreQGU66BsDhZMX6whQoF1eGlyghePxsb9xzePO4LkExB/7tTfhr3cklUrwTE+pplWs+QzIQ== + dependencies: + "@swc/helpers" "0.5.1" + less "^4.2.0" + less-plugin-resolve "^1.0.2" + node-libs-browser-okam "^2.2.5" + react-error-overlay "6.0.9" + react-refresh "^0.14.0" + workerpool "^9.1.1" + yargs-parser "^21.1.1" + optionalDependencies: + "@umijs/mako-darwin-arm64" "0.4.16" + "@umijs/mako-darwin-x64" "0.4.16" + "@umijs/mako-linux-x64-gnu" "0.4.16" + +"@umijs/mfsu@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/mfsu/-/mfsu-4.2.3.tgz#b14cb7f77b7379b22adf630b567e184f084dfc6a" + integrity sha512-uCri9Ro8BbK1wMvbqInpuo71iWRsPsiwL11jGwlMITKgUEScH1jIiXtJkdhycGg/MHs2nS079PdoYywx0tRLBA== dependencies: - "@umijs/bundler-esbuild" "4.0.89" - "@umijs/bundler-utils" "4.0.89" - "@umijs/utils" "4.0.89" + "@umijs/bundler-esbuild" "4.2.3" + "@umijs/bundler-utils" "4.2.3" + "@umijs/utils" "4.2.3" enhanced-resolve "5.9.3" is-equal "^1.6.4" -"@umijs/plugin-run@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/plugin-run/-/plugin-run-4.0.89.tgz" - integrity sha512-YsqaZz8ee3jHIsiLj43I/rtz7cy6tVhB3dUJ6zQH6a4b8u2fl7MYQcccj5gqjuRGQK5HcUScyYIJftR3cSUGKg== +"@umijs/plugin-run@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/plugin-run/-/plugin-run-4.2.3.tgz#e49728bf6d4508e73e729a40f72d6bc413ba2ca2" + integrity sha512-hrw+FiIPC/g/1FPM7ZEPARtivrVTUFABToyQj4QZYltOPQ5LJ9Df872XejMsXLiZTmKR70Q/3LpYPXxszoNrrg== dependencies: - tsx "^3.12.2" + tsx "3.12.2" -"@umijs/preset-umi@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/preset-umi/-/preset-umi-4.0.89.tgz" - integrity sha512-S0dn0e9C5eD2IX8bGGrNEDd0EaQVGuAwyJw2ruIU/FCO9B1HwdjCdRMuEADCBOuXMzBRt4+wKToFgId5tz3gAA== +"@umijs/preset-umi@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/preset-umi/-/preset-umi-4.2.3.tgz#7f6936fb8019666b0d377a5750c0cf3df042afa1" + integrity sha512-F4CYQV4WSczf0cCxxDVcIRfjehM1iiUNkh39/yF/vl9vp+M5PjVxehGHAz+/AAATAHDQ+9wcxKSuY5oYlEgK0g== dependencies: "@iconify/utils" "2.1.1" "@svgr/core" "6.5.1" - "@umijs/ast" "4.0.89" - "@umijs/babel-preset-umi" "4.0.89" - "@umijs/bundler-esbuild" "4.0.89" - "@umijs/bundler-utils" "4.0.89" - "@umijs/bundler-vite" "4.0.89" - "@umijs/bundler-webpack" "4.0.89" - "@umijs/core" "4.0.89" + "@umijs/ast" "4.2.3" + "@umijs/babel-preset-umi" "4.2.3" + "@umijs/bundler-esbuild" "4.2.3" + "@umijs/bundler-mako" "0.4.16" + "@umijs/bundler-utils" "4.2.3" + "@umijs/bundler-vite" "4.2.3" + "@umijs/bundler-webpack" "4.2.3" + "@umijs/core" "4.2.3" "@umijs/did-you-know" "1.0.3" "@umijs/es-module-parser" "0.0.7" "@umijs/history" "5.3.1" - "@umijs/mfsu" "4.0.89" - "@umijs/plugin-run" "4.0.89" - "@umijs/renderer-react" "4.0.89" - "@umijs/server" "4.0.89" + "@umijs/mfsu" "4.2.3" + "@umijs/plugin-run" "4.2.3" + "@umijs/renderer-react" "4.2.3" + "@umijs/server" "4.2.3" "@umijs/ui" "3.0.1" - "@umijs/utils" "4.0.89" - "@umijs/zod2ts" "4.0.89" + "@umijs/utils" "4.2.3" + "@umijs/zod2ts" "4.2.3" babel-plugin-dynamic-import-node "2.3.3" click-to-react-component "^1.0.8" - core-js "3.28.0" + core-js "3.34.0" current-script-polyfill "1.0.0" enhanced-resolve "5.9.3" fast-glob "3.2.12" @@ -5022,38 +5078,38 @@ schema-utils "^3.0.0" source-map "^0.7.3" -"@umijs/renderer-react@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/renderer-react/-/renderer-react-4.0.89.tgz" - integrity sha512-GDnUHzWzndT52gA8FnsHUOvO6wl6rQfrc9Q5O/cmWXtt1xMMk8H9bwR0rMYWE66ToKPTusP87YwSOtlGRtIPWg== +"@umijs/renderer-react@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/renderer-react/-/renderer-react-4.2.3.tgz#3852ec475e9b97fc55b7173b51ac5b0f0a513132" + integrity sha512-SS9aUQXuLCD2+41MCHfXrXspeGkdVD43sgTbiTyYk3gtu2EbWzc12FmH4V4gWEVLAmR6/HnGHIJPK/IxXb7cyQ== dependencies: - "@babel/runtime" "7.23.2" + "@babel/runtime" "7.23.6" "@loadable/component" "5.15.2" history "5.3.0" react-helmet-async "1.3.0" react-router-dom "6.3.0" -"@umijs/server@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/server/-/server-4.0.89.tgz" - integrity sha512-k+3KXt6vyYpnFQXrzm6JTyIaepW4uKkMNu4AQJBSpbC0FZVJw43mYIjVEoTlFUcXzR3IeP3ghny6J2Q2KLkF0g== +"@umijs/server@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/server/-/server-4.2.3.tgz#009ce51beefba26113eb15e3a23324a281f16f6c" + integrity sha512-KV3QPlp8AIlROTgzKRP2DW86Rf+9dnaI610PKp18Gp2uy+rdBqosVzixewDSSmDZpEKuXgKC7bsGw6879ULLuQ== dependencies: - "@umijs/bundler-utils" "4.0.89" + "@umijs/bundler-utils" "4.2.3" history "5.3.0" react "18.1.0" react-dom "18.1.0" react-router-dom "6.3.0" -"@umijs/test@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/test/-/test-4.0.89.tgz" - integrity sha512-eOVyk1zkCypEC0AtrnM1Kfp0+6DQK8FImXMTd3t3w8eSXTkh2v4Njy27qRC7soQeQhC/RieP3qpcs+k15rZYvg== +"@umijs/test@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/test/-/test-4.2.3.tgz#48ff82bcaf6e358a9b8012dfbd065f99e3592393" + integrity sha512-wZo0aMxzL3NVUt5QrZAm0t8O5eipsKwd66+g4znlz8lVh6hAyo1mC/dDV7UNDTUJV/mZRHDxpfoy5cnv2J0dYQ== dependencies: - "@babel/plugin-transform-modules-commonjs" "7.23.0" + "@babel/plugin-transform-modules-commonjs" "7.23.3" "@jest/types" "27.5.1" - "@umijs/bundler-utils" "4.0.89" - "@umijs/utils" "4.0.89" - babel-jest "^29.4.3" + "@umijs/bundler-utils" "4.2.3" + "@umijs/utils" "4.2.3" + babel-jest "^29.7.0" esbuild "0.17.19" identity-obj-proxy "3.0.0" isomorphic-unfetch "4.0.2" @@ -5063,18 +5119,18 @@ resolved "https://registry.npmmirror.com/@umijs/ui/-/ui-3.0.1.tgz" integrity sha512-zcz37AJH0xt/6XVVbyO/hmsK9Hq4vH23HZ4KYVi5A8rbM9KeJkJigTS7ELOdArawZhVNGe+h3a5Oixs4a2QsWw== -"@umijs/utils@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/utils/-/utils-4.0.89.tgz" - integrity sha512-Gq2yyuhp4m17DfU9VE59MkJGQrnbSsFp9/pfOFhbArV6AWzSo+EUY6UwLPmuQdJbJzVacZlN6N8t6cb794sVNw== +"@umijs/utils@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/utils/-/utils-4.2.3.tgz#4812d497388574a95c99770a904dbf29fb4b4e3b" + integrity sha512-zAiUmFyGmrpeiWk9hfjRfeuDvcSbZOFopwgOm76HDGjHTBdsC1+ps7xi2VFOnXALHwvKJxviev4i8CZGXTxnLA== dependencies: chokidar "3.5.3" pino "7.11.0" -"@umijs/zod2ts@4.0.89": - version "4.0.89" - resolved "https://registry.npmmirror.com/@umijs/zod2ts/-/zod2ts-4.0.89.tgz" - integrity sha512-LjPmRHutjqtFATIYbcF+yR/I6pxDaES1J0CCHRnap5oV9VTUu/acgVpFEX/Op8G0oT4ioHA2FaFxgAGF9OwMPg== +"@umijs/zod2ts@4.2.3": + version "4.2.3" + resolved "https://registry.npmmirror.com/@umijs/zod2ts/-/zod2ts-4.2.3.tgz#6be9fdecf1b7525b62d8323142d75e71822fc478" + integrity sha512-qh+pWoDhJhXLTdKH5glC74EFwQ6Qxwu4F09D3/qgIIjnVi0GQbpek1rW5EVjIetzOQ7Xulp5zho3AcYVxm0yWw== "@ungap/structured-clone@^1.2.0": version "1.2.0" @@ -5868,6 +5924,14 @@ asn1.js@^5.2.0: minimalistic-assert "^1.0.0" safer-buffer "^2.1.0" +assert-okam@^1.1.1: + version "1.5.0" + resolved "https://registry.npmmirror.com/assert-okam/-/assert-okam-1.5.0.tgz#c697095e6ba2d97dc9b02a6ad1464e3668a471bc" + integrity sha512-pchhPo40i8GsTj/7h6P8LSSzwRErnh2nCEiwXNTxy4VYw6lSesSac4rTKqwsA+fOZdj6FT81Mb9U1vIZEua1EQ== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + assert@^1.1.1: version "1.5.1" resolved "https://registry.npmmirror.com/assert/-/assert-1.5.1.tgz" @@ -5924,7 +5988,7 @@ asynciterator.prototype@^1.0.0: asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz" + resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== at-least-node@^1.0.0: @@ -5977,16 +6041,7 @@ axe-core@=4.7.0: resolved "https://registry.npmmirror.com/axe-core/-/axe-core-4.7.0.tgz" integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== -axios@^1.4.0: - version "1.6.2" - resolved "https://registry.npmmirror.com/axios/-/axios-1.6.2.tgz" - integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== - dependencies: - follow-redirects "^1.15.0" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - -axios@^1.6.0: +axios@^1.4.0, axios@^1.6.0: version "1.6.8" resolved "https://registry.npmmirror.com/axios/-/axios-1.6.8.tgz" integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ== @@ -6002,7 +6057,7 @@ axobject-query@^3.2.1: dependencies: dequal "^2.0.3" -babel-jest@^29.4.3, babel-jest@^29.7.0: +babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.npmmirror.com/babel-jest/-/babel-jest-29.7.0.tgz" integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== @@ -6281,6 +6336,24 @@ body-parser@1.20.1: type-is "~1.6.18" unpipe "1.0.0" +body-parser@1.20.2: + version "1.20.2" + resolved "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + boolbase@^1.0.0: version "1.0.0" resolved "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz" @@ -6440,6 +6513,15 @@ buffer-from@^1.0.0: resolved "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer-okam@^4.3.0: + version "4.9.2" + resolved "https://registry.npmmirror.com/buffer-okam/-/buffer-okam-4.9.2.tgz#63225572fbf6626dc1225736068b0720f4f360b0" + integrity sha512-t+vozme+an7flUs6GXHGMiP3PdodTse1NgRHSDWioIFJAtmMlj3pj7qD20Mkr9hZy0+9HA4R0xcumpMewrRdZQ== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.npmmirror.com/buffer-xor/-/buffer-xor-1.0.3.tgz" @@ -6629,6 +6711,17 @@ call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: get-intrinsic "^1.2.1" set-function-length "^1.1.1" +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + call-me-maybe@^1.0.1: version "1.0.2" resolved "https://registry.npmmirror.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz" @@ -6860,7 +6953,7 @@ classnames@2.x, classnames@^2.2.1, classnames@^2.2.3, classnames@^2.2.5, classna classnames@^2.5.1: version "2.5.1" - resolved "https://registry.npmmirror.com/classnames/-/classnames-2.5.1.tgz" + resolved "https://registry.npmmirror.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== clean-css@^4.2.3: @@ -7080,7 +7173,7 @@ columnify@1.6.0: combined-stream@^1.0.8: version "1.0.8" - resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz" + resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" @@ -7198,6 +7291,11 @@ concat-stream@^2.0.0: readable-stream "^3.0.2" typedarray "^0.0.6" +connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== + console-browserify@^1.1.0: version "1.2.0" resolved "https://registry.npmmirror.com/console-browserify/-/console-browserify-1.2.0.tgz" @@ -7220,7 +7318,7 @@ content-disposition@0.5.4: dependencies: safe-buffer "5.2.1" -content-type@~1.0.4: +content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" resolved "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== @@ -7437,6 +7535,11 @@ cookie@0.5.0: resolved "https://registry.npmmirror.com/cookie/-/cookie-0.5.0.tgz" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.npmmirror.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== + copy-anything@^2.0.1: version "2.0.6" resolved "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz" @@ -7503,12 +7606,7 @@ core-js-pure@^3.23.3: resolved "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.34.0.tgz" integrity sha512-pmhivkYXkymswFfbXsANmBAewXx86UBfmagP+w0wkK06kLsLlTK5oQmsURPivzMkIBQiYq2cjamcZExIwlFQIg== -core-js@3.28.0: - version "3.28.0" - resolved "https://registry.npmmirror.com/core-js/-/core-js-3.28.0.tgz" - integrity sha512-GiZn9D4Z/rSYvTeg1ljAIsEqFm0LaN9gVtwDCrKL80zHtS31p9BAjmTxVqTQDMpwlMolJZOFntUG2uwyj7DAqw== - -core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: +core-js@3.34.0, core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: version "3.34.0" resolved "https://registry.npmmirror.com/core-js/-/core-js-3.34.0.tgz" integrity sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag== @@ -7956,6 +8054,11 @@ deep-is@^0.1.3: resolved "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +deepmerge@^1.5.2: + version "1.5.2" + resolved "https://registry.npmmirror.com/deepmerge/-/deepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753" + integrity sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ== + deepmerge@^4.2.2: version "4.3.1" resolved "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz" @@ -8004,6 +8107,15 @@ define-data-property@^1.0.1, define-data-property@^1.1.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" @@ -8047,7 +8159,7 @@ define-property@^2.0.2: delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz" + resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== delegates@^1.0.0: @@ -8512,6 +8624,18 @@ es-array-method-boxes-properly@^1.0.0: resolved "https://registry.npmmirror.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz" integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + es-get-iterator@^1.0.2, es-get-iterator@^1.1.3: version "1.1.3" resolved "https://registry.npmmirror.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz" @@ -8587,7 +8711,7 @@ es6-shim@^0.35.5: resolved "https://registry.npmmirror.com/es6-shim/-/es6-shim-0.35.8.tgz" integrity sha512-Twf7I2v4/1tLoIXMT8HlqaBSS5H2wQTs2wx3MNYCI8K1R1/clXyCazrcVCPm/FuO9cyV8+leEaZOWD5C253NDg== -esbuild@0.17.19, esbuild@^0.17.5: +esbuild@0.17.19: version "0.17.19" resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.17.19.tgz" integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== @@ -8615,7 +8739,7 @@ esbuild@0.17.19, esbuild@^0.17.5: "@esbuild/win32-ia32" "0.17.19" "@esbuild/win32-x64" "0.17.19" -esbuild@~0.18.20: +esbuild@^0.18.10, esbuild@~0.18.20: version "0.18.20" resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz" integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== @@ -9026,6 +9150,11 @@ eventemitter3@^5.0.1: resolved "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.1.tgz" integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== +events-okam@^3.0.0: + version "3.3.0" + resolved "https://registry.npmmirror.com/events-okam/-/events-okam-3.3.0.tgz#66819139831f3c8b2e1e07fc8d33225673d87acb" + integrity sha512-6iR7z9hAJEwrT+D2Ywg6Fx62HSmN86OlcvPdrnq1JBeFr30dMF6l+j7M3VabjHfIi2KMtF8rO0J1rIZEfwMAwg== + events@^3.0.0: version "3.3.0" resolved "https://registry.npmmirror.com/events/-/events-3.3.0.tgz" @@ -9188,6 +9317,43 @@ express@^4.17.1: utils-merge "1.0.1" vary "~1.1.2" +express@^4.18.2: + version "4.19.2" + resolved "https://registry.npmmirror.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.6.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.npmmirror.com/extend-shallow/-/extend-shallow-2.0.1.tgz" @@ -9528,7 +9694,7 @@ flux@^4.0.1: fbemitter "^3.0.0" fbjs "^3.0.1" -follow-redirects@^1.0.0, follow-redirects@^1.15.0: +follow-redirects@^1.0.0: version "1.15.3" resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.3.tgz" integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== @@ -9618,7 +9784,7 @@ fork-ts-checker-webpack-plugin@^6.0.4: form-data@^4.0.0: version "4.0.0" - resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz" + resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" @@ -9737,7 +9903,7 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.2, fsevents@~2.3.3: +fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.2: version "2.3.3" resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -9816,6 +9982,17 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@ has-symbols "^1.0.3" hasown "^2.0.0" +get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.npmmirror.com/get-package-type/-/get-package-type-0.1.0.tgz" @@ -9871,13 +10048,20 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" -get-tsconfig@^4.5.0, get-tsconfig@^4.7.2: +get-tsconfig@^4.5.0: version "4.7.2" resolved "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.7.2.tgz" integrity sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A== dependencies: resolve-pkg-maps "^1.0.0" +get-tsconfig@^4.7.0: + version "4.7.5" + resolved "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.7.5.tgz#5e012498579e9a6947511ed0cd403272c7acbbaf" + integrity sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw== + dependencies: + resolve-pkg-maps "^1.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.npmmirror.com/get-value/-/get-value-2.0.6.tgz" @@ -10018,6 +10202,17 @@ glob@^10.2.2, glob@^10.3.10: minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-scurry "^1.10.1" +glob@^10.2.5: + version "10.3.15" + resolved "https://registry.npmmirror.com/glob/-/glob-10.3.15.tgz#e72bc61bc3038c90605f5dd48543dc67aaf3b50d" + integrity sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.6" + minimatch "^9.0.1" + minipass "^7.0.4" + path-scurry "^1.11.0" + glob@^7.0.5, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.3" resolved "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz" @@ -10195,6 +10390,13 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.2.2" +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + has-proto@^1.0.1: version "1.0.1" resolved "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.1.tgz" @@ -10754,6 +10956,11 @@ inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, i resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA== + inherits@2.0.3: version "2.0.3" resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.3.tgz" @@ -11517,7 +11724,7 @@ iterator.prototype@^1.1.2: reflect.getprototypeof "^1.0.4" set-function-name "^2.0.1" -jackspeak@^2.3.5: +jackspeak@^2.3.5, jackspeak@^2.3.6: version "2.3.6" resolved "https://registry.npmmirror.com/jackspeak/-/jackspeak-2.3.6.tgz" integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== @@ -11536,6 +11743,11 @@ jake@^10.8.5: filelist "^1.0.4" minimatch "^3.1.2" +javascript-stringify@^2.0.1: + version "2.1.0" + resolved "https://registry.npmmirror.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" + integrity sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg== + jest-changed-files@^29.7.0: version "29.7.0" resolved "https://registry.npmmirror.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz" @@ -12287,7 +12499,7 @@ lerna@^8.1.2: yargs "17.7.2" yargs-parser "21.1.1" -less-plugin-resolve@1.0.2: +less-plugin-resolve@1.0.2, less-plugin-resolve@^1.0.2: version "1.0.2" resolved "https://registry.npmmirror.com/less-plugin-resolve/-/less-plugin-resolve-1.0.2.tgz" integrity sha512-e1AHq0XNTU8S3d9JCc8CFYajoUBr0EK3pcuLT5PogyBBeE0knzZJL105kKKSZWfq2lQLq3/uEDrMK3JPq+fHaA== @@ -12311,6 +12523,23 @@ less@4.1.3: needle "^3.1.0" source-map "~0.6.0" +less@^4.2.0: + version "4.2.0" + resolved "https://registry.npmmirror.com/less/-/less-4.2.0.tgz#cbefbfaa14a4cd388e2099b2b51f956e1465c450" + integrity sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA== + dependencies: + copy-anything "^2.0.1" + parse-node-version "^1.0.1" + tslib "^2.3.0" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + make-dir "^2.1.0" + mime "^1.4.1" + needle "^3.1.0" + source-map "~0.6.0" + leven@^3.1.0: version "3.1.0" resolved "https://registry.npmmirror.com/leven/-/leven-3.1.0.tgz" @@ -12688,6 +12917,11 @@ lru-cache@^10.0.1, "lru-cache@^9.1.1 || ^10.0.0": resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.1.0.tgz" integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== +lru-cache@^10.2.0: + version "10.2.2" + resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.2.2.tgz#48206bc114c1252940c41b25b41af5b545aca878" + integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz" @@ -13185,6 +13419,11 @@ minipass@^5.0.0: resolved "https://registry.npmmirror.com/minipass/-/minipass-7.0.4.tgz" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== +minipass@^7.0.4: + version "7.1.1" + resolved "https://registry.npmmirror.com/minipass/-/minipass-7.1.1.tgz#f7f85aff59aa22f110b20e27692465cf3bf89481" + integrity sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA== + minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.npmmirror.com/minizlib/-/minizlib-2.1.2.tgz" @@ -13229,28 +13468,33 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.npmmirror.com/mkdirp/-/mkdirp-1.0.4.tgz" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mobx-react-lite@4.0.5: - version "4.0.5" - resolved "https://registry.npmmirror.com/mobx-react-lite/-/mobx-react-lite-4.0.5.tgz" - integrity sha512-StfB2wxE8imKj1f6T8WWPf4lVMx3cYH9Iy60bbKXEs21+HQ4tvvfIBZfSmMXgQAefi8xYEwQIz4GN9s0d2h7dg== +mobx-react-lite@4.0.7: + version "4.0.7" + resolved "https://registry.npmmirror.com/mobx-react-lite/-/mobx-react-lite-4.0.7.tgz#f4e21e18d05c811010dcb1d3007e797924c4d90b" + integrity sha512-RjwdseshK9Mg8On5tyJZHtGD+J78ZnCnRaxeQDSiciKVQDUbfZcXhmld0VMxAwvcTnPEHZySGGewm467Fcpreg== dependencies: use-sync-external-store "^1.2.0" -mobx@6.12.0: - version "6.12.0" - resolved "https://registry.npmmirror.com/mobx/-/mobx-6.12.0.tgz" - integrity sha512-Mn6CN6meXEnMa0a5u6a5+RKrqRedHBhZGd15AWLk9O6uFY4KYHzImdt8JI8WODo1bjTSRnwXhJox+FCUZhCKCQ== +mobx@6.12.3: + version "6.12.3" + resolved "https://registry.npmmirror.com/mobx/-/mobx-6.12.3.tgz#b6a0fde4268116be602d50bffb32f1b90a8fb077" + integrity sha512-c8NKkO4R2lShkSXZ2Ongj1ycjugjzFFo/UswHBnS62y07DMcTc9Rvo03/3nRyszIvwPNljlkd4S828zIBv/piw== modify-values@^1.0.1: version "1.0.1" resolved "https://registry.npmmirror.com/modify-values/-/modify-values-1.0.1.tgz" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== -moment@^2.24.0, moment@^2.29.2, moment@^2.29.4: +moment@^2.24.0, moment@^2.29.2: version "2.29.4" resolved "https://registry.npmmirror.com/moment/-/moment-2.29.4.tgz" integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== +moment@^2.30.1: + version "2.30.1" + resolved "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" + integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== + monaco-editor-textmate@^4.0.0: version "4.0.0" resolved "https://registry.npmmirror.com/monaco-editor-textmate/-/monaco-editor-textmate-4.0.0.tgz" @@ -13455,6 +13699,35 @@ node-int64@^0.4.0: resolved "https://registry.npmmirror.com/node-int64/-/node-int64-0.4.0.tgz" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== +node-libs-browser-okam@^2.2.5: + version "2.2.5" + resolved "https://registry.npmmirror.com/node-libs-browser-okam/-/node-libs-browser-okam-2.2.5.tgz#743c52436a4c8d04b3f2466d552ab635606d9c1a" + integrity sha512-kD+WXACEThc6C5DA146KoCNbubjpXeYzXDrukvtXWr6MRzV3uvHCI0eb/GuugWVYnMoD4g3/uaIzvDYOpC4QWw== + dependencies: + assert-okam "^1.1.1" + browserify-zlib "^0.2.0" + buffer-okam "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events-okam "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process-okam "^0.11.10" + punycode-okam "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder-okam "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url-okam "^0.11.0" + util-okam "^0.11.0" + vm-browserify "^1.0.1" + node-libs-browser@2.2.1, node-libs-browser@^2.2.1: version "2.2.1" resolved "https://registry.npmmirror.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz" @@ -14431,6 +14704,14 @@ path-scurry@^1.10.1, path-scurry@^1.6.1: lru-cache "^9.1.1 || ^10.0.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-scurry@^1.11.0: + version "1.11.1" + resolved "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz" @@ -14981,6 +15262,15 @@ postcss@^8.4.21, postcss@^8.4.7: picocolors "^1.0.0" source-map-js "^1.0.2" +postcss@^8.4.27: + version "8.4.38" + resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" + integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.2.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz" @@ -15049,6 +15339,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process-okam@^0.11.10: + version "0.11.10" + resolved "https://registry.npmmirror.com/process-okam/-/process-okam-0.11.10.tgz#c2da27b44cd78684da664e38d58b3f74059688cd" + integrity sha512-p8e5nl6/OCeMalVb9dSojND5B9m/nq64WsyUfRmrTdLMKcNYcDN++/2I8WV1mTQDqrh2PQ6tIIb2A7/A38eSvw== + process-warning@^1.0.0: version "1.0.0" resolved "https://registry.npmmirror.com/process-warning/-/process-warning-1.0.0.tgz" @@ -15148,7 +15443,7 @@ proxy-addr@~2.0.7: proxy-from-env@^1.1.0: version "1.1.0" - resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== prr@~1.0.1: @@ -15198,6 +15493,11 @@ pumpify@^1.3.3: inherits "^2.0.3" pump "^2.0.0" +punycode-okam@^1.2.4: + version "1.4.1" + resolved "https://registry.npmmirror.com/punycode-okam/-/punycode-okam-1.4.1.tgz#e0404d4be30147fbee874e75d5bf3e75efb8efdc" + integrity sha512-e4mSfzGfrVBJmhjp+8PHjXIz5WrvEEWB2FT+RJ6YS/ozGttTcnocuj0CtMo3dujWYe2708bTd79zeIrKBtRzCg== + punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" resolved "https://registry.npmmirror.com/punycode/-/punycode-1.4.1.tgz" @@ -15232,6 +15532,13 @@ qs@^6.10.0, qs@^6.11.2, qs@^6.4.0: dependencies: side-channel "^1.0.4" +qs@^6.11.0: + version "6.12.1" + resolved "https://registry.npmmirror.com/qs/-/qs-6.12.1.tgz#39422111ca7cbdb70425541cba20c7d7b216599a" + integrity sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ== + dependencies: + side-channel "^1.0.6" + query-string@^6.13.6: version "6.14.1" resolved "https://registry.npmmirror.com/query-string/-/query-string-6.14.1.tgz" @@ -15302,6 +15609,16 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + raw-loader@^4.0.2: version "4.0.2" resolved "https://registry.npmmirror.com/raw-loader/-/raw-loader-4.0.2.tgz" @@ -16482,6 +16799,13 @@ rfdc@^1.3.0: resolved "https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== +rimraf@5.0.1: + version "5.0.1" + resolved "https://registry.npmmirror.com/rimraf/-/rimraf-5.0.1.tgz#0881323ab94ad45fec7c0221f27ea1a142f3f0d0" + integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== + dependencies: + glob "^10.2.5" + rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.npmmirror.com/rimraf/-/rimraf-2.7.1.tgz" @@ -16521,9 +16845,9 @@ rollup-plugin-visualizer@5.9.0: source-map "^0.7.4" yargs "^17.5.1" -rollup@^3.20.2: +rollup@^3.27.1: version "3.29.4" - resolved "https://registry.npmmirror.com/rollup/-/rollup-3.29.4.tgz" + resolved "https://registry.npmmirror.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981" integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== optionalDependencies: fsevents "~2.3.2" @@ -16729,6 +17053,11 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.2, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.6.2: + version "7.6.2" + resolved "https://registry.npmmirror.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" + integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== + send@0.18.0: version "0.18.0" resolved "https://registry.npmmirror.com/send/-/send-0.18.0.tgz" @@ -16798,6 +17127,18 @@ set-function-length@^1.1.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + set-function-name@^2.0.0, set-function-name@^2.0.1: version "2.0.1" resolved "https://registry.npmmirror.com/set-function-name/-/set-function-name-2.0.1.tgz" @@ -16890,6 +17231,16 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + signal-exit@3.0.7, signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz" @@ -17066,6 +17417,11 @@ source-map-js@^1.0.2: resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== + source-map-resolve@^0.5.0: version "0.5.3" resolved "https://registry.npmmirror.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz" @@ -17428,6 +17784,13 @@ string.prototype.trimstart@^1.0.7: define-properties "^1.2.0" es-abstract "^1.22.1" +string_decoder-okam@^1.0.0: + version "1.3.0" + resolved "https://registry.npmmirror.com/string_decoder-okam/-/string_decoder-okam-1.3.0.tgz#277bb20dd66d6bf6279c0d52b75a34b08e98c8c5" + integrity sha512-N5lJgLJ02sIs9xNyqPgIywlGaLUW6s5cYRpnmM3gbfhGA3sggW0+E2go26D7oZgEH7jHpXDe+ArDrBXeCaP9QA== + dependencies: + safe-buffer "~5.2.0" + string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz" @@ -18039,16 +18402,16 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" -tsx@^3.12.2: - version "3.14.0" - resolved "https://registry.npmmirror.com/tsx/-/tsx-3.14.0.tgz" - integrity sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg== +tsx@3.12.2: + version "3.12.2" + resolved "https://registry.npmmirror.com/tsx/-/tsx-3.12.2.tgz#1c8a4fa08a97739e6eedf0ad464bd8218e1a64f0" + integrity sha512-ykAEkoBg30RXxeOMVeZwar+JH632dZn9EUJVyJwhfag62k6UO/dIyJEV58YuLF6e5BTdV/qmbQrpkWqjq9cUnQ== dependencies: - esbuild "~0.18.20" - get-tsconfig "^4.7.2" - source-map-support "^0.5.21" + "@esbuild-kit/cjs-loader" "^2.4.1" + "@esbuild-kit/core-utils" "^3.0.0" + "@esbuild-kit/esm-loader" "^2.5.4" optionalDependencies: - fsevents "~2.3.3" + fsevents "~2.3.2" tty-browserify@0.0.0: version "0.0.0" @@ -18209,21 +18572,21 @@ uglify-js@^3.1.4: resolved "https://registry.npmmirror.com/uglify-js/-/uglify-js-3.17.4.tgz" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== -umi@^4.0.89: - version "4.0.89" - resolved "https://registry.npmmirror.com/umi/-/umi-4.0.89.tgz" - integrity sha512-bC62ctJ3wnymADnhE5nU7IZz4+XQ3MPWwoVW150OJazyAqEioZdjIZEBgB9pVfQEM819xMc6+eslnyuCNOQV+g== - dependencies: - "@babel/runtime" "7.23.2" - "@umijs/bundler-utils" "4.0.89" - "@umijs/bundler-webpack" "4.0.89" - "@umijs/core" "4.0.89" - "@umijs/lint" "4.0.89" - "@umijs/preset-umi" "4.0.89" - "@umijs/renderer-react" "4.0.89" - "@umijs/server" "4.0.89" - "@umijs/test" "4.0.89" - "@umijs/utils" "4.0.89" +umi@^4.2.3: + version "4.2.3" + resolved "https://registry.npmmirror.com/umi/-/umi-4.2.3.tgz#497d51eed187fae596acd55a41285eb65dfee79a" + integrity sha512-f5KyU3uZebsJqlwHNgbKLQDongHU+lHEy3bmIcFEDEkC8mXf02msNxwaNJ6sQIHL5yf0mRNTYRiKwVMEn2DwNQ== + dependencies: + "@babel/runtime" "7.23.6" + "@umijs/bundler-utils" "4.2.3" + "@umijs/bundler-webpack" "4.2.3" + "@umijs/core" "4.2.3" + "@umijs/lint" "4.2.3" + "@umijs/preset-umi" "4.2.3" + "@umijs/renderer-react" "4.2.3" + "@umijs/server" "4.2.3" + "@umijs/test" "4.2.3" + "@umijs/utils" "4.2.3" prettier-plugin-organize-imports "^3.2.2" prettier-plugin-packagejson "2.4.3" @@ -18489,6 +18852,14 @@ url-loader@^4.1.1: mime-types "^2.1.27" schema-utils "^3.0.0" +url-okam@^0.11.0: + version "0.11.1" + resolved "https://registry.npmmirror.com/url-okam/-/url-okam-0.11.1.tgz#fd1b309d26e2e1f6aaec31c784d1a0e759be28c8" + integrity sha512-AM6OVeZNwKiirK3IwKxHuopgjX1jB0F8srK9OlCXN+wdmTNg6vgnN9xyQ5abhxq8Oj/kTleLU8OCfZ1FaEW37w== + dependencies: + punycode "^1.4.1" + qs "^6.11.0" + url-parse@^1.5.3: version "1.5.10" resolved "https://registry.npmmirror.com/url-parse/-/url-parse-1.5.10.tgz" @@ -18537,6 +18908,13 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +util-okam@^0.11.0: + version "0.11.1" + resolved "https://registry.npmmirror.com/util-okam/-/util-okam-0.11.1.tgz#2bb241ed5b19c938082093f0a8a5988b2add105f" + integrity sha512-e2bG47F03vYx2MbA6znK6t6dwffnXGsVzh8BLpi0pcQ7dDRQf0zSAQ9IR7M+aoozALNibw8eCY53gEK8bBpSjg== + dependencies: + inherits "2.0.3" + util.promisify@1.0.0: version "1.0.0" resolved "https://registry.npmmirror.com/util.promisify/-/util.promisify-1.0.0.tgz" @@ -18545,6 +18923,13 @@ util.promisify@1.0.0: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" +util@0.10.3: + version "0.10.3" + resolved "https://registry.npmmirror.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ== + dependencies: + inherits "2.0.1" + util@^0.10.4: version "0.10.4" resolved "https://registry.npmmirror.com/util/-/util-0.10.4.tgz" @@ -18648,14 +19033,14 @@ vfile@^4.0.0: unist-util-stringify-position "^2.0.0" vfile-message "^2.0.0" -vite@4.3.1: - version "4.3.1" - resolved "https://registry.npmmirror.com/vite/-/vite-4.3.1.tgz" - integrity sha512-EPmfPLAI79Z/RofuMvkIS0Yr091T2ReUoXQqc5ppBX/sjFRhHKiPPF/R46cTdoci/XgeQpB23diiJxq5w30vdg== +vite@4.5.2: + version "4.5.2" + resolved "https://registry.npmmirror.com/vite/-/vite-4.5.2.tgz#d6ea8610e099851dad8c7371599969e0f8b97e82" + integrity sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w== dependencies: - esbuild "^0.17.5" - postcss "^8.4.21" - rollup "^3.20.2" + esbuild "^0.18.10" + postcss "^8.4.27" + rollup "^3.27.1" optionalDependencies: fsevents "~2.3.2" @@ -18753,6 +19138,14 @@ webidl-conversions@^7.0.0: resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz" integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== +webpack-5-chain@8.0.1: + version "8.0.1" + resolved "https://registry.npmmirror.com/webpack-5-chain/-/webpack-5-chain-8.0.1.tgz#dda9db48c19e4e01e535e84241131bcc777243d8" + integrity sha512-Tu1w80WA2Z+X6e7KzGy+cc0A0z+npVJA/fh55q2azMJ030gqz343Kx+yNAstDCeugsepmtDWY2J2IBRW/O+DEA== + dependencies: + deepmerge "^1.5.2" + javascript-stringify "^2.0.1" + webpack-dev-middleware@^3.7.3: version "3.7.3" resolved "https://registry.npmmirror.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz" @@ -18962,6 +19355,11 @@ worker-rpc@^0.1.0: dependencies: microevent.ts "~0.1.1" +workerpool@^9.1.1: + version "9.1.1" + resolved "https://registry.npmmirror.com/workerpool/-/workerpool-9.1.1.tgz#9ba4d534a79a5517c1e1b9d1014151516829be8d" + integrity sha512-EFoFTSEo9m4V4wNrwzVRjxnf/E/oBpOzcI/R5CIugJhl9RsCiq525rszo4AtqcjQQoqFdu2E3H82AnbtpaQHvg== + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz"