diff --git a/.eslintignore b/.eslintignore index 90aa2d111..f12dbc006 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,7 +1,6 @@ # 忽略目录 build/ -test/ -tests/ +fixtures/ node_modules/ dist/ out/ @@ -11,7 +10,6 @@ compiled/ coverage/ # 忽略测试文件 -/packages/*/__tests__ /packages/*/lib/ /packages/*/esm/ /packages/*/es2017/ diff --git a/.eslintrc.js b/.eslintrc.js index af0ac781e..bdfa702c0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -16,6 +16,7 @@ const commonRules = { 'no-multiple-empty-lines': 1, 'react/jsx-no-bind': 0, 'import/order': 1, + 'no-multi-assign': 0, }; module.exports = getESLintConfig('react-ts', { @@ -32,7 +33,9 @@ module.exports = getESLintConfig('react-ts', { 'id-length': 0, 'no-use-before-define': 0, 'no-unused-vars': 0, - '@typescript-eslint/no-unused-vars': 1, + '@typescript-eslint/no-unused-vars': ['warn', { + varsIgnorePattern: '[iI]gnored|createElement', + }], '@typescript-eslint/ban-ts-ignore': 0, '@typescript-eslint/no-confusing-void-expression': 0, '@typescript-eslint/promise-function-async': 0, diff --git a/examples/app-config/.browserslistrc b/examples/app-config/.browserslistrc new file mode 100644 index 000000000..7637baddc --- /dev/null +++ b/examples/app-config/.browserslistrc @@ -0,0 +1 @@ +chrome 55 \ No newline at end of file diff --git a/examples/app-config/ice.config.mts b/examples/app-config/ice.config.mts new file mode 100644 index 000000000..129fcfa67 --- /dev/null +++ b/examples/app-config/ice.config.mts @@ -0,0 +1,3 @@ +import { defineConfig } from '@ice/app'; + +export default defineConfig({}); diff --git a/examples/app-config/package.json b/examples/app-config/package.json new file mode 100644 index 000000000..afce34ef2 --- /dev/null +++ b/examples/app-config/package.json @@ -0,0 +1,28 @@ +{ + "name": "app-config", + "version": "1.0.0", + "scripts": { + "start": "ice start", + "build": "ice build", + "build:splitChunks": "ice build --config splitChunks.config.mts" + }, + "description": "", + "author": "", + "license": "MIT", + "dependencies": { + "@ice/app": "workspace:*", + "@ice/plugin-auth": "workspace:*", + "@ice/plugin-rax-compat": "workspace:*", + "@ice/runtime": "workspace:*", + "@uni/env": "^1.1.0", + "ahooks": "^3.3.8", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.2", + "speed-measure-webpack-plugin": "^1.5.0", + "webpack": "^5.73.0" + } +} diff --git a/examples/app-config/public/favicon.ico b/examples/app-config/public/favicon.ico new file mode 100644 index 000000000..a2605c57e Binary files /dev/null and b/examples/app-config/public/favicon.ico differ diff --git a/examples/app-config/src/app.tsx b/examples/app-config/src/app.tsx new file mode 100644 index 000000000..e125139bb --- /dev/null +++ b/examples/app-config/src/app.tsx @@ -0,0 +1,13 @@ +import { defineAppConfig } from 'ice'; + +export default defineAppConfig({ + app: { + rootId: 'app', + strict: true, + errorBoundary: true, + }, + router: { + type: 'browser', + basename: '/ice', + }, +}); \ No newline at end of file diff --git a/examples/app-config/src/document.tsx b/examples/app-config/src/document.tsx new file mode 100644 index 000000000..961b46c16 --- /dev/null +++ b/examples/app-config/src/document.tsx @@ -0,0 +1,22 @@ +import { Meta, Title, Links, Main, Scripts } from 'ice'; + +function Document() { + return ( + + + + + + + + <Links /> + </head> + <body> + <Main /> + <Scripts /> + </body> + </html> + ); +} + +export default Document; diff --git a/examples/app-config/src/global.css b/examples/app-config/src/global.css new file mode 100644 index 000000000..604282adc --- /dev/null +++ b/examples/app-config/src/global.css @@ -0,0 +1,3 @@ +body { + font-size: 14px; +} diff --git a/examples/app-config/src/pages/error.tsx b/examples/app-config/src/pages/error.tsx new file mode 100644 index 000000000..3d1338493 --- /dev/null +++ b/examples/app-config/src/pages/error.tsx @@ -0,0 +1,5 @@ +export default function Error() { + // @ts-ignore + window.test(); + return <>error</>; +} diff --git a/examples/app-config/src/pages/index.tsx b/examples/app-config/src/pages/index.tsx new file mode 100644 index 000000000..bb7281536 --- /dev/null +++ b/examples/app-config/src/pages/index.tsx @@ -0,0 +1,3 @@ +export default function Home() { + return <h1>home</h1>; +} diff --git a/examples/app-config/src/typings.d.ts b/examples/app-config/src/typings.d.ts new file mode 100644 index 000000000..b2780a236 --- /dev/null +++ b/examples/app-config/src/typings.d.ts @@ -0,0 +1,14 @@ +declare module '*.module.less' { + const classes: { [key: string]: string }; + export default classes; +} + +declare module '*.module.css' { + const classes: { [key: string]: string }; + export default classes; +} + +declare module '*.module.scss' { + const classes: { [key: string]: string }; + export default classes; +} diff --git a/examples/app-config/tsconfig.json b/examples/app-config/tsconfig.json new file mode 100644 index 000000000..7f2f2ffce --- /dev/null +++ b/examples/app-config/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compileOnSave": false, + "buildOnSave": false, + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "module": "esnext", + "target": "es6", + "jsx": "react-jsx", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "lib": ["es6", "dom"], + "sourceMap": true, + "allowJs": true, + "rootDir": "./", + "forceConsistentCasingInFileNames": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": false, + "importHelpers": true, + "strictNullChecks": true, + "suppressImplicitAnyIndexErrors": true, + "noUnusedLocals": true, + "skipLibCheck": true, + "paths": { + "@/*": ["./src/*"], + "ice": [".ice"] + } + }, + "include": ["src", ".ice", "ice.config.*"], + "exclude": ["node_modules", "build", "public"] +} \ No newline at end of file diff --git a/examples/basic-project/ice.config.mts b/examples/basic-project/ice.config.mts index 809efa536..e1f20aeb6 100644 --- a/examples/basic-project/ice.config.mts +++ b/examples/basic-project/ice.config.mts @@ -1,6 +1,7 @@ import { defineConfig } from '@ice/app'; import SpeedMeasurePlugin from 'speed-measure-webpack-plugin'; import auth from '@ice/plugin-auth'; +import custom from './plugin'; export default defineConfig({ publicPath: '/', @@ -21,6 +22,14 @@ export default defineConfig({ return webpackConfig; }, dropLogLevel: 'warn', - plugins: [auth()], + plugins: [ + auth(), + { + name: 'runtime-donot-exsist', + setup() {}, + runtime: './test', + }, + custom, + ], eslint: true, }); diff --git a/examples/basic-project/plugin.ts b/examples/basic-project/plugin.ts new file mode 100644 index 000000000..0efb803a4 --- /dev/null +++ b/examples/basic-project/plugin.ts @@ -0,0 +1,24 @@ +import fs from 'fs'; + +export default { + name: 'custom-plugin', + setup({ onGetConfig }) { + onGetConfig((config) => { + config.transformPlugins = [...(config.transformPlugins || []), { + name: 'custom-transform', + transformInclude(id) { + return !!id.match(/app.tsx$/); + }, + loadInclude(id) { + return !!id.match(/app.tsx$/); + }, + load(id) { + return fs.readFileSync(id, 'utf-8'); + }, + transform(code) { + return code; + }, + }]; + }); + }, +}; \ No newline at end of file diff --git a/examples/basic-project/src/app.tsx b/examples/basic-project/src/app.tsx index ec77cc76a..1d848aab5 100644 --- a/examples/basic-project/src/app.tsx +++ b/examples/basic-project/src/app.tsx @@ -20,11 +20,11 @@ if (isNode) { console.error('__IS_NODE__'); } -export const auth = defineAuthConfig(() => { +export const auth = defineAuthConfig((data) => { // fetch auth data return { initialAuth: { - admin: true, + admin: data?.auth?.admin, }, }; }); diff --git a/examples/basic-project/src/components/bar.tsx b/examples/basic-project/src/components/bar.tsx index 7861bf5cb..7aa2e8f87 100644 --- a/examples/basic-project/src/components/bar.tsx +++ b/examples/basic-project/src/components/bar.tsx @@ -1,6 +1,10 @@ +import style from './cssWithEscapedSymbols.module.css'; + +console.log('style', style); + export default function Bar() { return ( - <div> + <div className={style.test}> bar </div> ); diff --git a/examples/basic-project/src/components/cssWithEscapedSymbols.module.css b/examples/basic-project/src/components/cssWithEscapedSymbols.module.css new file mode 100644 index 000000000..2c2ffbc98 --- /dev/null +++ b/examples/basic-project/src/components/cssWithEscapedSymbols.module.css @@ -0,0 +1,114 @@ +.test { + background: red; +} + + ._test { + background: blue; +} + +.className { + background: red; +} + +#someId { + background: green; +} + +.className .subClass { + color: green; +} + +#someId .subClass { + color: blue; +} + +.-a0-34a___f { + color: red; +} + +.m_x_\@ { + margin-left: auto !important; + margin-right: auto !important; +} + +.B\&W\? { + margin-left: auto !important; + margin-right: auto !important; +} + +/* matches elements with class=":`(" */ +.\3A \`\( { + color: aqua; +} + +/* matches elements with class="1a2b3c" */ +.\31 a2b3c { + color: aliceblue; +} + +/* matches the element with id="#fake-id" */ +#\#fake-id { + color: antiquewhite; +} + +/* matches the element with id="-a-b-c-" */ +#-a-b-c- { + color: azure; +} + +/* matches the element with id="©" */ +#© { + color: black; +} + +.♥ { background: lime; } +.© { background: lime; } +.😍 { background: lime; } +.“‘’” { background: lime; } +.☺☃ { background: lime; } +.⌘⌥ { background: lime; } +.𝄞♪♩♫♬ { background: lime; } +.💩 { background: lime; } +.\? { background: lime; } +.\@ { background: lime; } +.\. { background: lime; } +.\3A \) { background: lime; } +.\3A \`\( { background: lime; } +.\31 23 { background: lime; } +.\31 a2b3c { background: lime; } +.\<p\> { background: lime; } +.\<\>\<\<\<\>\>\<\> { background: lime; } +.\+\+\+\+\+\+\+\+\+\+\[\>\+\+\+\+\+\+\+\>\+\+\+\+\+\+\+\+\+\+\>\+\+\+\>\+\<\<\<\<\-\]\>\+\+\.\>\+\.\+\+\+\+\+\+\+\.\.\+\+\+\.\>\+\+\.\<\<\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\.\>\.\+\+\+\.\-\-\-\-\-\-\.\-\-\-\-\-\-\-\-\.\>\+\.\>\. { background: lime; } +.\# { background: lime; } +.\#\# { background: lime; } +.\#\.\#\.\# { background: lime; } +.\_ { background: lime; } +.\{\} { background: lime; } +.\#fake\-id { background: lime; } +.foo\.bar { background: lime; } +.\3A hover { background: lime; } +.\3A hover\3A focus\3A active { background: lime; } +.\[attr\=value\] { background: lime; } +.f\/o\/o { background: lime; } +.f\\o\\o { background: lime; } +.f\*o\*o { background: lime; } +.f\!o\!o { background: lime; } +.f\'o\'o { background: lime; } +.f\~o\~o { background: lime; } +.f\+o\+o { background: lime; } + +.foo\/bar { + background: hotpink; +} + +.foo\\bar { + background: hotpink; +} + +.foo\/bar\/baz { + background: hotpink; +} + +.foo\\bar\\baz { + background: hotpink; +} diff --git a/examples/basic-project/src/pages/index.css b/examples/basic-project/src/pages/index.css new file mode 100644 index 000000000..c712d6d93 --- /dev/null +++ b/examples/basic-project/src/pages/index.css @@ -0,0 +1,3 @@ +h2 { + color: #000; +} \ No newline at end of file diff --git a/examples/basic-project/src/pages/index.module.less b/examples/basic-project/src/pages/index.module.less new file mode 100644 index 000000000..71f0de02a --- /dev/null +++ b/examples/basic-project/src/pages/index.module.less @@ -0,0 +1,3 @@ +.data { + margin-top: 10px; +} \ No newline at end of file diff --git a/examples/basic-project/src/pages/index.module.scss b/examples/basic-project/src/pages/index.module.scss new file mode 100644 index 000000000..71f0de02a --- /dev/null +++ b/examples/basic-project/src/pages/index.module.scss @@ -0,0 +1,3 @@ +.data { + margin-top: 10px; +} \ No newline at end of file diff --git a/examples/basic-project/src/pages/index.tsx b/examples/basic-project/src/pages/index.tsx index 649fc2d12..12dd58646 100644 --- a/examples/basic-project/src/pages/index.tsx +++ b/examples/basic-project/src/pages/index.tsx @@ -4,7 +4,10 @@ import { Link, useData, useAppData, useConfig } from 'ice'; import { useAppContext } from '@ice/runtime'; import { useRequest } from 'ahooks'; import type { AppData } from 'ice'; +import './index.css'; import styles from './index.module.css'; +import lessStyles from './index.module.less'; +import sassStyles from './index.module.scss'; const Bar = lazy(() => import('../components/bar')); @@ -33,8 +36,8 @@ export default function Home(props) { <Bar /> </Suspense> <div className={styles.data}> - <div>foo: {JSON.stringify(foo)}</div> - <div>users: {JSON.stringify(users)}</div> + <div className={lessStyles.data}>foo: {JSON.stringify(foo)}</div> + <div className={sassStyles.data}>users: {JSON.stringify(users)}</div> <div>userInfo: {JSON.stringify(userInfo)}</div> <div>data from: <span id="data-from">{data.from}</span></div> </div> diff --git a/examples/rax-inline-style/.browserslistrc b/examples/rax-inline-style/.browserslistrc new file mode 100644 index 000000000..7637baddc --- /dev/null +++ b/examples/rax-inline-style/.browserslistrc @@ -0,0 +1 @@ +chrome 55 \ No newline at end of file diff --git a/examples/rax-inline-style/ice.config.mts b/examples/rax-inline-style/ice.config.mts new file mode 100644 index 000000000..1eeca97c3 --- /dev/null +++ b/examples/rax-inline-style/ice.config.mts @@ -0,0 +1,12 @@ +import { defineConfig } from '@ice/app'; +import compatRax from '@ice/plugin-rax-compat'; + +export default defineConfig({ + publicPath: '/', + plugins: [compatRax({ + inlineStyle: true, + })], + server: { + bundle: true, + }, +}); diff --git a/examples/rax-inline-style/package.json b/examples/rax-inline-style/package.json new file mode 100644 index 000000000..adb81eb63 --- /dev/null +++ b/examples/rax-inline-style/package.json @@ -0,0 +1,28 @@ +{ + "name": "rax-project", + "version": "1.0.0", + "scripts": { + "start": "ice start", + "build": "ice build" + }, + "description": "", + "author": "", + "license": "MIT", + "dependencies": { + "@ice/app": "workspace:*", + "@ice/plugin-rax-compat": "workspace:*", + "@ice/runtime": "workspace:*", + "rax": "^1.2.2", + "rax-image": "^2.4.1", + "rax-is-valid-element": "^1.0.0", + "rax-text": "^2.2.0", + "rax-view": "^2.3.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.2", + "webpack": "^5.73.0" + } +} diff --git a/examples/rax-inline-style/public/favicon.ico b/examples/rax-inline-style/public/favicon.ico new file mode 100644 index 000000000..a2605c57e Binary files /dev/null and b/examples/rax-inline-style/public/favicon.ico differ diff --git a/examples/rax-inline-style/src/app.tsx b/examples/rax-inline-style/src/app.tsx new file mode 100644 index 000000000..1ceb78f30 --- /dev/null +++ b/examples/rax-inline-style/src/app.tsx @@ -0,0 +1,7 @@ +import { defineAppConfig } from 'ice'; + +export default defineAppConfig({ + app: { + rootId: 'app', + }, +}); diff --git a/examples/rax-inline-style/src/components/Logo/index.jsx b/examples/rax-inline-style/src/components/Logo/index.jsx new file mode 100644 index 000000000..908a755c7 --- /dev/null +++ b/examples/rax-inline-style/src/components/Logo/index.jsx @@ -0,0 +1,10 @@ +import { createElement } from 'rax'; +import Image from 'rax-image'; + +import styles from './index.module.less'; + +export default (props) => { + const { uri } = props; + const source = { uri }; + return <Image className={styles['logo']} source={source} />; +}; diff --git a/examples/rax-inline-style/src/components/Logo/index.module.less b/examples/rax-inline-style/src/components/Logo/index.module.less new file mode 100644 index 000000000..b84be53a9 --- /dev/null +++ b/examples/rax-inline-style/src/components/Logo/index.module.less @@ -0,0 +1,5 @@ +.logo { + width: 200rpx; + height: 180rpx; + margin-bottom: 20rpx; +} diff --git a/examples/rax-inline-style/src/components/Title/index.jsx b/examples/rax-inline-style/src/components/Title/index.jsx new file mode 100644 index 000000000..d109dd24b --- /dev/null +++ b/examples/rax-inline-style/src/components/Title/index.jsx @@ -0,0 +1,8 @@ +import { createElement } from 'rax'; +import Text from 'rax-text'; + +import styles from './index.module.css'; + +export default () => { + return <Text className={styles['title']}>Welcome to Your Rax App</Text>; +}; diff --git a/examples/rax-inline-style/src/components/Title/index.module.css b/examples/rax-inline-style/src/components/Title/index.module.css new file mode 100644 index 000000000..8c42cb167 --- /dev/null +++ b/examples/rax-inline-style/src/components/Title/index.module.css @@ -0,0 +1,5 @@ +.title { + font-size: 45rpx; + font-weight: bold; + margin: 20rpx 0; +} \ No newline at end of file diff --git a/examples/rax-inline-style/src/document.tsx b/examples/rax-inline-style/src/document.tsx new file mode 100644 index 000000000..e82d54323 --- /dev/null +++ b/examples/rax-inline-style/src/document.tsx @@ -0,0 +1,24 @@ +/* @jsx createElement */ +import { createElement } from 'rax'; +import { Meta, Title, Links, Main, Scripts } from 'ice'; + +function Document() { + return ( + <html> + <head> + <meta charSet="utf-8" /> + <meta name="description" content="ICE 3.0 Demo" /> + <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,viewport-fit=cover" /> + <Meta /> + <Title /> + <Links /> + </head> + <body> + <Main /> + <Scripts /> + </body> + </html> + ); +} + +export default Document; diff --git a/examples/rax-inline-style/src/global.css b/examples/rax-inline-style/src/global.css new file mode 100644 index 000000000..604282adc --- /dev/null +++ b/examples/rax-inline-style/src/global.css @@ -0,0 +1,3 @@ +body { + font-size: 14px; +} diff --git a/examples/rax-inline-style/src/pages/index.css b/examples/rax-inline-style/src/pages/index.css new file mode 100644 index 000000000..975de4a51 --- /dev/null +++ b/examples/rax-inline-style/src/pages/index.css @@ -0,0 +1,19 @@ +.title { + color: red; + margin-left: 10rpx; +} + +.data { + margin-top: 10px; +} + +.homeContainer { + align-items: center; + margin-top: 200rpx; +} + +.homeInfo { + font-size: 36rpx; + margin: 8rpx 0; + color: #555; +} diff --git a/examples/rax-inline-style/src/pages/index.jsx b/examples/rax-inline-style/src/pages/index.jsx new file mode 100644 index 000000000..6e80d78f1 --- /dev/null +++ b/examples/rax-inline-style/src/pages/index.jsx @@ -0,0 +1,30 @@ +import { createElement, useEffect, useRef } from 'rax'; +import View from 'rax-view'; +import Text from 'rax-text'; +import Logo from '@/components/Logo'; +import Title from '@/components/Title'; +import './index.css'; + +export default function Home() { + const ref = useRef(); + useEffect(() => { + if (ref.current) { + console.log('ref for View', ref); + } + }, []); + return ( + <View + ref={ref} + className="homeContainer" + style={{ + width: '750rpx', + }} + onAppear={() => { console.log('view appear'); }} + > + <Logo uri="//gw.alicdn.com/tfs/TB1MRC_cvb2gK0jSZK9XXaEgFXa-1701-1535.png" /> + <Title /> + <Text className="homeInfo">More information about Rax</Text> + <Text className="homeInfo">Visit https://rax.js.org</Text> + </View> + ); +} diff --git a/examples/rax-inline-style/src/typings.d.ts b/examples/rax-inline-style/src/typings.d.ts new file mode 100644 index 000000000..b2780a236 --- /dev/null +++ b/examples/rax-inline-style/src/typings.d.ts @@ -0,0 +1,14 @@ +declare module '*.module.less' { + const classes: { [key: string]: string }; + export default classes; +} + +declare module '*.module.css' { + const classes: { [key: string]: string }; + export default classes; +} + +declare module '*.module.scss' { + const classes: { [key: string]: string }; + export default classes; +} diff --git a/examples/rax-inline-style/tsconfig.json b/examples/rax-inline-style/tsconfig.json new file mode 100644 index 000000000..7f2f2ffce --- /dev/null +++ b/examples/rax-inline-style/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compileOnSave": false, + "buildOnSave": false, + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "module": "esnext", + "target": "es6", + "jsx": "react-jsx", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "lib": ["es6", "dom"], + "sourceMap": true, + "allowJs": true, + "rootDir": "./", + "forceConsistentCasingInFileNames": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": false, + "importHelpers": true, + "strictNullChecks": true, + "suppressImplicitAnyIndexErrors": true, + "noUnusedLocals": true, + "skipLibCheck": true, + "paths": { + "@/*": ["./src/*"], + "ice": [".ice"] + } + }, + "include": ["src", ".ice", "ice.config.*"], + "exclude": ["node_modules", "build", "public"] +} \ No newline at end of file diff --git a/examples/rax-project/ice.config.mts b/examples/rax-project/ice.config.mts index 95a7ba884..0f7692665 100644 --- a/examples/rax-project/ice.config.mts +++ b/examples/rax-project/ice.config.mts @@ -1,7 +1,11 @@ import { defineConfig } from '@ice/app'; import compatRax from '@ice/plugin-rax-compat'; +import jsxPlus from '@ice/plugin-jsx-plus'; export default defineConfig({ publicPath: '/', - plugins: [compatRax()], + plugins: [ + compatRax(), + jsxPlus(), + ], }); diff --git a/examples/rax-project/package.json b/examples/rax-project/package.json index adb81eb63..03180c02f 100644 --- a/examples/rax-project/package.json +++ b/examples/rax-project/package.json @@ -11,6 +11,8 @@ "dependencies": { "@ice/app": "workspace:*", "@ice/plugin-rax-compat": "workspace:*", + "@ice/plugin-jsx-plus": "workspace:*", + "@ice/appear": "workspace:*", "@ice/runtime": "workspace:*", "rax": "^1.2.2", "rax-image": "^2.4.1", @@ -25,4 +27,4 @@ "@types/react-dom": "^18.0.2", "webpack": "^5.73.0" } -} +} \ No newline at end of file diff --git a/examples/rax-project/src/pages/jsxplus.jsx b/examples/rax-project/src/pages/jsxplus.jsx new file mode 100644 index 000000000..b061d71fe --- /dev/null +++ b/examples/rax-project/src/pages/jsxplus.jsx @@ -0,0 +1,25 @@ +import { createElement } from 'rax'; + +export default function JSXPlusDemo() { + const list = [0, 1, 2, 3]; + const val = 'foo'; + return ( + // x-class + <div x-class={{ item: true, active: val }}> + {/* x-if */} + <div x-if="YES">Should Show</div> + <div x-if={false}>Should Hide</div> + + {/* x-for */} + {/* eslint-disable-next-line */} + <span x-for={item in list} key={item}> {item} </span> + + {/* Fragment */} + <> + <div>Fragment 1</div> + <div>Fragment 2</div> + <div>Fragment 3</div> + </> + </div> + ); +} diff --git a/examples/with-fusion/ice.config.mts b/examples/with-fusion/ice.config.mts index 678d05927..83b562155 100644 --- a/examples/with-fusion/ice.config.mts +++ b/examples/with-fusion/ice.config.mts @@ -1,11 +1,15 @@ import { defineConfig } from '@ice/app'; import fusion from '@ice/plugin-fusion'; +import cssAssetsLocal from '@ice/plugin-css-assets-local'; export default defineConfig({ - plugins: [fusion({ - importStyle: true, - theme: { - 'primary-color': '#89d', - }, - })], + plugins: [ + fusion({ + importStyle: true, + theme: { + 'primary-color': '#89d', + }, + }), + cssAssetsLocal(), + ], }); diff --git a/examples/with-fusion/package.json b/examples/with-fusion/package.json index 7eed0b8ef..55ccf2a42 100644 --- a/examples/with-fusion/package.json +++ b/examples/with-fusion/package.json @@ -10,14 +10,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.25.49", - "@ice/app": "workspace:*", - "@ice/plugin-fusion": "workspace:*", "@ice/runtime": "workspace:*", "react": "^18.0.0", "react-dom": "^18.0.0" }, "devDependencies": { "@types/react": "^18.0.0", - "@types/react-dom": "^18.0.2" + "@types/react-dom": "^18.0.2", + "@ice/app": "workspace:*", + "@ice/plugin-css-assets-local": "workspace:*", + "@ice/plugin-fusion": "workspace:*" } } diff --git a/examples/with-jest/ice.config.mts b/examples/with-jest/ice.config.mts new file mode 100644 index 000000000..129fcfa67 --- /dev/null +++ b/examples/with-jest/ice.config.mts @@ -0,0 +1,3 @@ +import { defineConfig } from '@ice/app'; + +export default defineConfig({}); diff --git a/examples/with-jest/jest-setup.ts b/examples/with-jest/jest-setup.ts new file mode 100644 index 000000000..7b0828bfa --- /dev/null +++ b/examples/with-jest/jest-setup.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom'; diff --git a/examples/with-jest/jest.config.mjs b/examples/with-jest/jest.config.mjs new file mode 100644 index 000000000..7bad10aec --- /dev/null +++ b/examples/with-jest/jest.config.mjs @@ -0,0 +1,7 @@ +import { defineJestConfig } from '@ice/app'; + +export default defineJestConfig({ + preset: 'ts-jest', + setupFilesAfterEnv: ['<rootDir>/jest-setup.ts'], + testEnvironment: 'jest-environment-jsdom', +}); diff --git a/examples/with-jest/package.json b/examples/with-jest/package.json new file mode 100644 index 000000000..4e3df5b2b --- /dev/null +++ b/examples/with-jest/package.json @@ -0,0 +1,27 @@ +{ + "name": "with-jest", + "version": "1.0.0", + "scripts": { + "start": "ice start", + "build": "ice build", + "test": "jest" + }, + "dependencies": { + "@ice/runtime": "workspace:*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@ice/app": "workspace:*", + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.3.0", + "@types/jest": "^29.0.0", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.2", + "@types/testing-library__jest-dom": "^5.14.5", + "jest": "^28.1.3", + "jest-environment-jsdom": "^29.0.2", + "ts-jest": "^28.0.8", + "typescript": "^4.8.2" + } +} \ No newline at end of file diff --git a/examples/with-jest/src/add.ts b/examples/with-jest/src/add.ts new file mode 100644 index 000000000..9a9a19394 --- /dev/null +++ b/examples/with-jest/src/add.ts @@ -0,0 +1,7 @@ +import log from '@/log'; + +export default function add(a: number, b: number) { + log(); + return a + b; +} + diff --git a/examples/with-jest/src/app.tsx b/examples/with-jest/src/app.tsx new file mode 100644 index 000000000..c1664902e --- /dev/null +++ b/examples/with-jest/src/app.tsx @@ -0,0 +1,3 @@ +import { defineAppConfig } from 'ice'; + +export default defineAppConfig({}); diff --git a/examples/with-jest/src/components/Header.tsx b/examples/with-jest/src/components/Header.tsx new file mode 100644 index 000000000..c6eb1b72c --- /dev/null +++ b/examples/with-jest/src/components/Header.tsx @@ -0,0 +1,6 @@ + +export default function Header() { + return ( + <h2 data-testid="title">Jest Test</h2> + ); +} \ No newline at end of file diff --git a/examples/with-jest/src/document.tsx b/examples/with-jest/src/document.tsx new file mode 100644 index 000000000..cc414afae --- /dev/null +++ b/examples/with-jest/src/document.tsx @@ -0,0 +1,23 @@ +import { Meta, Title, Links, Main, Scripts } from 'ice'; + +function Document() { + return ( + <html> + <head> + <meta charSet="utf-8" /> + <link rel="icon" href="/favicon.ico" /> + <meta name="description" content="with-jest" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <Meta /> + <Title /> + <Links /> + </head> + <body> + <Main /> + <Scripts /> + </body> + </html> + ); +} + +export default Document; diff --git a/examples/with-jest/src/log.ts b/examples/with-jest/src/log.ts new file mode 100644 index 000000000..27bb829db --- /dev/null +++ b/examples/with-jest/src/log.ts @@ -0,0 +1,3 @@ +export default function log() { + console.log('log'); +} \ No newline at end of file diff --git a/examples/with-jest/src/pages/index.tsx b/examples/with-jest/src/pages/index.tsx new file mode 100644 index 000000000..8f59483f7 --- /dev/null +++ b/examples/with-jest/src/pages/index.tsx @@ -0,0 +1,7 @@ +import Header from '../components/Header'; + +export default function Home() { + return ( + <Header /> + ); +} diff --git a/examples/with-jest/tests/Header.spec.tsx b/examples/with-jest/tests/Header.spec.tsx new file mode 100644 index 000000000..1af37b6e0 --- /dev/null +++ b/examples/with-jest/tests/Header.spec.tsx @@ -0,0 +1,7 @@ +import { render, screen } from '@testing-library/react'; +import Header from '../src/components/Header'; + +test('test Header component', () => { + render(<Header />); + expect(screen.getByTestId('title')).toHaveTextContent('Jest Test'); +}); diff --git a/examples/with-jest/tests/add.spec.ts b/examples/with-jest/tests/add.spec.ts new file mode 100644 index 000000000..e98d85150 --- /dev/null +++ b/examples/with-jest/tests/add.spec.ts @@ -0,0 +1,5 @@ +import add from '../src/add'; + +test('add', () => { + expect(add(1, 2)).toBe(3); +}); diff --git a/examples/with-jest/tsconfig.json b/examples/with-jest/tsconfig.json new file mode 100644 index 000000000..2f2a840cb --- /dev/null +++ b/examples/with-jest/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compileOnSave": false, + "buildOnSave": false, + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "module": "esnext", + "target": "es6", + "jsx": "react-jsx", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "lib": ["es6", "dom"], + "sourceMap": true, + "allowJs": true, + "rootDir": "./", + "forceConsistentCasingInFileNames": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": false, + "importHelpers": true, + "strictNullChecks": true, + "suppressImplicitAnyIndexErrors": true, + "noUnusedLocals": true, + "skipLibCheck": true, + "paths": { + "@/*": ["./src/*"], + "ice": [".ice"] + } + }, + "include": ["src", ".ice", "ice.config.*", "tests", "./jest-setup.ts"], + "exclude": ["node_modules", "build", "public"] +} \ No newline at end of file diff --git a/examples/with-pha/src/document.tsx b/examples/with-pha/src/document.tsx index 869d51d20..961b46c16 100644 --- a/examples/with-pha/src/document.tsx +++ b/examples/with-pha/src/document.tsx @@ -1,6 +1,6 @@ import { Meta, Title, Links, Main, Scripts } from 'ice'; -function Document(props) { +function Document() { return ( <html> <head> @@ -19,4 +19,4 @@ function Document(props) { ); } -export default Document; \ No newline at end of file +export default Document; diff --git a/examples/with-pha/src/pages/home.tsx b/examples/with-pha/src/pages/home.tsx index a2fd14527..473b28797 100644 --- a/examples/with-pha/src/pages/home.tsx +++ b/examples/with-pha/src/pages/home.tsx @@ -1,4 +1,4 @@ -export default function home() { +export default function Home() { return ( <> <h2>Home Page</h2> @@ -15,4 +15,4 @@ export function getConfig() { ], title: 'Home', }; -} \ No newline at end of file +} diff --git a/examples/with-plugin-request/.browserslistrc b/examples/with-plugin-request/.browserslistrc new file mode 100644 index 000000000..7637baddc --- /dev/null +++ b/examples/with-plugin-request/.browserslistrc @@ -0,0 +1 @@ +chrome 55 \ No newline at end of file diff --git a/examples/with-plugin-request/ice.config.mts b/examples/with-plugin-request/ice.config.mts new file mode 100644 index 000000000..b0076d018 --- /dev/null +++ b/examples/with-plugin-request/ice.config.mts @@ -0,0 +1,8 @@ +import { defineConfig } from '@ice/app'; +import request from '@ice/plugin-request'; + +export default defineConfig({ + plugins: [ + request(), + ], +}); diff --git a/examples/with-plugin-request/package.json b/examples/with-plugin-request/package.json new file mode 100644 index 000000000..3766a8347 --- /dev/null +++ b/examples/with-plugin-request/package.json @@ -0,0 +1,22 @@ +{ + "name": "with-plugin-request", + "version": "1.0.0", + "scripts": { + "start": "ice start", + "build": "ice build" + }, + "description": "ICE example with plugin-request", + "author": "ICE Team", + "license": "MIT", + "dependencies": { + "@ice/app": "workspace:*", + "@ice/plugin-request": "workspace:*", + "@ice/runtime": "workspace:*", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/react": "^18.0.17", + "@types/react-dom": "^18.0.6" + } +} diff --git a/examples/with-plugin-request/src/app.tsx b/examples/with-plugin-request/src/app.tsx new file mode 100644 index 000000000..fe245be42 --- /dev/null +++ b/examples/with-plugin-request/src/app.tsx @@ -0,0 +1,59 @@ +import { defineRequestConfig } from '@ice/plugin-request/esm/types'; +const requestConfig = { + // 可选的,全局设置 request 是否返回 response 对象,默认为 false + withFullResponse: false, + baseURL: '/api', + headers: {}, + // 其它 RequestConfig 参数 + + // 拦截器 + interceptors: { + request: { + onConfig: (config) => { + // 发送请求前:可以对 RequestConfig 做一些统一处理 + config.headers = { a: 1 }; + return config; + }, + onError: (error) => { + return Promise.reject(error); + }, + }, + response: { + onConfig: (response) => { + console.log(response); + // 请求成功:可以做全局的 toast 展示,或者对 response 做一些格式化 + if (response.data.status === 1) { + alert('请求失败'); + } + return response; + }, + onError: (error) => { + // MOCK DATA for `/api/user` + if (error.config.url === '/api/user') { + return new Promise((resolve) => { + setTimeout(() => { + error.response.data = { + name: 'ICE', + age: 26, + }; + resolve(error.response); + }, 1000); + }); + } + // 请求出错:服务端返回错误状态码 + console.log(error.response.data); + console.log(error.response.status); + console.log(error.response.headers); + return Promise.reject(error); + }, + }, + }, +}; + +export default { + app: { + rootId: 'app', + }, +}; + +export const request = defineRequestConfig(() => requestConfig); diff --git a/examples/with-plugin-request/src/document.tsx b/examples/with-plugin-request/src/document.tsx new file mode 100644 index 000000000..61e35a7ec --- /dev/null +++ b/examples/with-plugin-request/src/document.tsx @@ -0,0 +1,22 @@ +import { Meta, Title, Links, Main, Scripts } from 'ice'; + +function Document() { + return ( + <html> + <head> + <meta charSet="utf-8" /> + <meta name="description" content="ICE 3 Example for plugin request." /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <Meta /> + <Title /> + <Links /> + </head> + <body> + <Main /> + <Scripts /> + </body> + </html> + ); +} + +export default Document; diff --git a/examples/with-plugin-request/src/pages/home.tsx b/examples/with-plugin-request/src/pages/home.tsx new file mode 100644 index 000000000..3ed8d6a54 --- /dev/null +++ b/examples/with-plugin-request/src/pages/home.tsx @@ -0,0 +1,31 @@ +import { useEffect } from 'react'; +import { useRequest } from 'ice'; +import service from '../service'; +import styles from './index.module.css'; + +export default function Home() { + const { data, error, loading, request } = useRequest(service.getUser); + + useEffect(() => { + request(); + // eslint-disable-next-line + }, []); + + if (error) { + return <div>failed to load</div>; + } + if (!data || loading) { + return <div>loading...</div>; + } + return ( + <> + <h2 className={styles.title}>Name: {data.name} Age: {data.age}</h2> + </> + ); +} + +export function getConfig() { + return { + title: 'Home', + }; +} diff --git a/examples/with-plugin-request/src/pages/index.module.css b/examples/with-plugin-request/src/pages/index.module.css new file mode 100644 index 000000000..836f971af --- /dev/null +++ b/examples/with-plugin-request/src/pages/index.module.css @@ -0,0 +1,4 @@ +.title { + color: red; + margin-left: 10rpx; +} diff --git a/examples/with-plugin-request/src/pages/layout.tsx b/examples/with-plugin-request/src/pages/layout.tsx new file mode 100644 index 000000000..c9d99f4a1 --- /dev/null +++ b/examples/with-plugin-request/src/pages/layout.tsx @@ -0,0 +1,32 @@ +import { Outlet } from 'ice'; + +export default () => { + return ( + <div> + <h1>ICE 3.0 Layout</h1> + <Outlet /> + </div> + ); +}; + +export function getConfig() { + return { + title: 'Layout', + meta: [ + { + name: 'layout-color', + content: '#f00', + }, + ], + }; +} + +export function getData() { + return new Promise((resolve) => { + setTimeout(() => { + resolve({ + layout: true, + }); + }, 1 * 100); + }); +} diff --git a/examples/with-plugin-request/src/service.ts b/examples/with-plugin-request/src/service.ts new file mode 100644 index 000000000..98f22460d --- /dev/null +++ b/examples/with-plugin-request/src/service.ts @@ -0,0 +1,27 @@ +import { request } from 'ice'; + +const service = { + async getUser() { + return await request('/api/user'); + }, + + async getRepo(id) { + return await request(`/api/repo/${id}`); + }, + + async getDetail(params) { + const data = await request({ + url: '/api/detail', + params, + }); + + return data.map(item => { + return { + ...item, + price: item.oldPrice, + text: item.status === '1' ? '确定' : '取消', + }; + }); + }, +}; +export default service; diff --git a/examples/with-plugin-request/src/typings.d.ts b/examples/with-plugin-request/src/typings.d.ts new file mode 100644 index 000000000..b2780a236 --- /dev/null +++ b/examples/with-plugin-request/src/typings.d.ts @@ -0,0 +1,14 @@ +declare module '*.module.less' { + const classes: { [key: string]: string }; + export default classes; +} + +declare module '*.module.css' { + const classes: { [key: string]: string }; + export default classes; +} + +declare module '*.module.scss' { + const classes: { [key: string]: string }; + export default classes; +} diff --git a/examples/with-plugin-request/tsconfig.json b/examples/with-plugin-request/tsconfig.json new file mode 100644 index 000000000..7f2f2ffce --- /dev/null +++ b/examples/with-plugin-request/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compileOnSave": false, + "buildOnSave": false, + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "module": "esnext", + "target": "es6", + "jsx": "react-jsx", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "lib": ["es6", "dom"], + "sourceMap": true, + "allowJs": true, + "rootDir": "./", + "forceConsistentCasingInFileNames": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": false, + "importHelpers": true, + "strictNullChecks": true, + "suppressImplicitAnyIndexErrors": true, + "noUnusedLocals": true, + "skipLibCheck": true, + "paths": { + "@/*": ["./src/*"], + "ice": [".ice"] + } + }, + "include": ["src", ".ice", "ice.config.*"], + "exclude": ["node_modules", "build", "public"] +} \ No newline at end of file diff --git a/examples/with-store/ice.config.mts b/examples/with-store/ice.config.mts index 902f5727e..e68918f5c 100644 --- a/examples/with-store/ice.config.mts +++ b/examples/with-store/ice.config.mts @@ -3,6 +3,8 @@ import store from '@ice/plugin-store'; export default defineConfig({ plugins: [ - store(), + store({ + resetPageState: true, + }), ], }); diff --git a/examples/with-vitest/ice.config.mts b/examples/with-vitest/ice.config.mts new file mode 100644 index 000000000..129fcfa67 --- /dev/null +++ b/examples/with-vitest/ice.config.mts @@ -0,0 +1,3 @@ +import { defineConfig } from '@ice/app'; + +export default defineConfig({}); diff --git a/examples/with-vitest/package.json b/examples/with-vitest/package.json new file mode 100644 index 000000000..fc06b36df --- /dev/null +++ b/examples/with-vitest/package.json @@ -0,0 +1,26 @@ +{ + "name": "with-jest", + "version": "1.0.0", + "scripts": { + "start": "ice start", + "build": "ice build", + "test": "vitest" + }, + "dependencies": { + "@ice/runtime": "workspace:*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@ice/app": "workspace:*", + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.3.0", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.2", + "@types/testing-library__jest-dom": "^5.14.5", + "@vitejs/plugin-react": "^1.3.2", + "jsdom": "^20.0.0", + "typescript": "^4.8.2", + "vitest": "^0.15.2" + } +} \ No newline at end of file diff --git a/examples/with-vitest/src/add.ts b/examples/with-vitest/src/add.ts new file mode 100644 index 000000000..9a9a19394 --- /dev/null +++ b/examples/with-vitest/src/add.ts @@ -0,0 +1,7 @@ +import log from '@/log'; + +export default function add(a: number, b: number) { + log(); + return a + b; +} + diff --git a/examples/with-vitest/src/app.tsx b/examples/with-vitest/src/app.tsx new file mode 100644 index 000000000..c1664902e --- /dev/null +++ b/examples/with-vitest/src/app.tsx @@ -0,0 +1,3 @@ +import { defineAppConfig } from 'ice'; + +export default defineAppConfig({}); diff --git a/examples/with-vitest/src/components/Header.tsx b/examples/with-vitest/src/components/Header.tsx new file mode 100644 index 000000000..b2d884cce --- /dev/null +++ b/examples/with-vitest/src/components/Header.tsx @@ -0,0 +1,6 @@ + +export default function Header() { + return ( + <div data-testid="title">Vitest Test</div> + ); +} \ No newline at end of file diff --git a/examples/with-vitest/src/document.tsx b/examples/with-vitest/src/document.tsx new file mode 100644 index 000000000..cc414afae --- /dev/null +++ b/examples/with-vitest/src/document.tsx @@ -0,0 +1,23 @@ +import { Meta, Title, Links, Main, Scripts } from 'ice'; + +function Document() { + return ( + <html> + <head> + <meta charSet="utf-8" /> + <link rel="icon" href="/favicon.ico" /> + <meta name="description" content="with-jest" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <Meta /> + <Title /> + <Links /> + </head> + <body> + <Main /> + <Scripts /> + </body> + </html> + ); +} + +export default Document; diff --git a/examples/with-vitest/src/log.ts b/examples/with-vitest/src/log.ts new file mode 100644 index 000000000..27bb829db --- /dev/null +++ b/examples/with-vitest/src/log.ts @@ -0,0 +1,3 @@ +export default function log() { + console.log('log'); +} \ No newline at end of file diff --git a/examples/with-vitest/src/pages/index.tsx b/examples/with-vitest/src/pages/index.tsx new file mode 100644 index 000000000..01df1a2cd --- /dev/null +++ b/examples/with-vitest/src/pages/index.tsx @@ -0,0 +1,6 @@ + +export default function Home() { + return ( + <div>Vitest Test</div> + ); +} diff --git a/examples/with-vitest/tests/Header.spec.tsx b/examples/with-vitest/tests/Header.spec.tsx new file mode 100644 index 000000000..ce7f234ba --- /dev/null +++ b/examples/with-vitest/tests/Header.spec.tsx @@ -0,0 +1,8 @@ +import { test, expect } from 'vitest'; +import { render, screen } from '@testing-library/react'; +import Header from '../src/components/Header'; + +test('test Header component', () => { + render(<Header />); + expect(screen.getByTestId('title')).toHaveTextContent('Vitest Test'); +}); diff --git a/examples/with-vitest/tests/add.spec.ts b/examples/with-vitest/tests/add.spec.ts new file mode 100644 index 000000000..3a6f1a26f --- /dev/null +++ b/examples/with-vitest/tests/add.spec.ts @@ -0,0 +1,6 @@ +import { test, expect } from 'vitest'; +import add from '../src/add'; + +test('add', () => { + expect(add(1, 2)).toBe(3); +}); diff --git a/examples/with-vitest/tsconfig.json b/examples/with-vitest/tsconfig.json new file mode 100644 index 000000000..5274ab7cf --- /dev/null +++ b/examples/with-vitest/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compileOnSave": false, + "buildOnSave": false, + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "module": "esnext", + "target": "es6", + "jsx": "react-jsx", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "lib": ["es6", "dom"], + "sourceMap": true, + "allowJs": true, + "rootDir": "./", + "forceConsistentCasingInFileNames": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": false, + "importHelpers": true, + "strictNullChecks": true, + "suppressImplicitAnyIndexErrors": true, + "noUnusedLocals": true, + "skipLibCheck": true, + "paths": { + "@/*": ["./src/*"], + "ice": [".ice"] + } + }, + "include": ["src", ".ice", "ice.config.*", "tests", "./vitest-setup.ts"], + "exclude": ["node_modules", "build", "public"] +} \ No newline at end of file diff --git a/examples/with-vitest/vitest-setup.ts b/examples/with-vitest/vitest-setup.ts new file mode 100644 index 000000000..b210af530 --- /dev/null +++ b/examples/with-vitest/vitest-setup.ts @@ -0,0 +1,4 @@ +import matchers from '@testing-library/jest-dom/matchers'; +import { expect } from 'vitest'; + +expect.extend(matchers); diff --git a/examples/with-vitest/vitest.config.mjs b/examples/with-vitest/vitest.config.mjs new file mode 100644 index 000000000..352a02725 --- /dev/null +++ b/examples/with-vitest/vitest.config.mjs @@ -0,0 +1,10 @@ +import { defineVitestConfig } from '@ice/app'; +import react from '@vitejs/plugin-react'; + +export default defineVitestConfig({ + plugins: [react()], + test: { + environment: 'jsdom', + setupFiles: ['./vitest-setup.ts'], + }, +}); diff --git a/package.json b/package.json index 80a172ce8..2f1f25e64 100644 --- a/package.json +++ b/package.json @@ -15,13 +15,13 @@ "build": "pnpm run clean && pnpm -r --filter=./packages/* run build", "prebundle": "cd packages/bundles && pnpm build", "clean": "rimraf packages/*/esm", - "dependency:check": "esmo ./scripts/dependencyCheck.ts", - "version": "esmo ./scripts/tagVersion.ts", - "version:check": "esmo ./scripts/versionCheck.ts", + "dependency:check": "tsx ./scripts/dependencyCheck.ts", + "version": "tsx ./scripts/tagVersion.ts", + "version:check": "tsx ./scripts/versionCheck.ts", "lint": "eslint --cache --ext .js,.jsx,.ts,.tsx ./", - "publish:alpha": "PUBLISH_TYPE=alpha esmo ./scripts/publishPackageWithDistTag.ts", - "publish:beta": "PUBLISH_TYPE=beta esmo ./scripts/publishPackageWithDistTag.ts", - "publish:release": "PUBLISH_TYPE=release VERSION_PREFIX=rc esmo ./scripts/publishPackageWithDistTag.ts", + "publish:alpha": "PUBLISH_TYPE=alpha tsx ./scripts/publishPackageWithDistTag.ts", + "publish:beta": "PUBLISH_TYPE=beta tsx ./scripts/publishPackageWithDistTag.ts", + "publish:release": "PUBLISH_TYPE=release VERSION_PREFIX=rc tsx ./scripts/publishPackageWithDistTag.ts", "cov": "vitest run --coverage", "test": "vitest" }, @@ -34,15 +34,15 @@ "@types/fs-extra": "^9.0.13", "@types/glob": "^7.2.0", "@types/node": "^17.0.45", - "@types/semver": "^7.3.11", + "@types/semver": "^7.3.12", "@vercel/ncc": "^0.33.4", + "@vitest/coverage-c8": "^0.23.1", "c8": "^7.12.0", "chalk": "^4.1.2", "chokidar": "^3.5.3", "dependency-check": "^4.1.0", "dts-bundle": "^0.7.3", - "eslint": "^8.21.0", - "esno": "^0.14.1", + "eslint": "^8.22.0", "execa": "^6.1.0", "find-up": "^5.0.0", "fs-extra": "^10.1.0", @@ -59,6 +59,7 @@ "rimraf": "^3.0.2", "semver": "^7.3.7", "stylelint": "^14.10.0", + "tsx": "^3.9.0", "typescript": "^4.7.4", "vitest": "^0.15.2" }, diff --git a/packages/appear/CHANGELOG.md b/packages/appear/CHANGELOG.md new file mode 100644 index 000000000..d1ba3bd2a --- /dev/null +++ b/packages/appear/CHANGELOG.md @@ -0,0 +1,5 @@ +# @ice/appear + +## v0.1.0 + +- [feat] support VisibilityChange. \ No newline at end of file diff --git a/packages/appear/README.md b/packages/appear/README.md new file mode 100644 index 000000000..432db13ed --- /dev/null +++ b/packages/appear/README.md @@ -0,0 +1,24 @@ +# @ice/appear + +React component for appear and disappear. + +## Usage + +```bash +npm i @ice/appear +``` + +```jsx +import VisibilityChange from '@ice/appear'; + +export default function Home() { + return <VisibilityChange + onAppear={() => { + console.log('onAppear') + }} + onDisappear={() => { + console.log('ondisAppear') + }} + >show something</VisibilityChange> +} +``` diff --git a/packages/appear/package.json b/packages/appear/package.json new file mode 100644 index 000000000..bf6761d16 --- /dev/null +++ b/packages/appear/package.json @@ -0,0 +1,23 @@ +{ + "name": "@ice/appear", + "version": "0.1.0", + "description": "", + "main": "./esm/index.js", + "types": "./esm/index.d.ts", + "scripts": { + "watch": "tsc -w", + "build": "tsc", + "prepublishOnly": "npm run build" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependencies": { + "react": "^18", + "react-dom": "^18" + } +} \ No newline at end of file diff --git a/packages/appear/src/index.tsx b/packages/appear/src/index.tsx new file mode 100644 index 000000000..a7b06ac2f --- /dev/null +++ b/packages/appear/src/index.tsx @@ -0,0 +1,39 @@ +import { Children, useRef, useEffect, useCallback } from 'react'; +import { isFunction } from './type'; +import { observerElement, VisibilityChangeEvent } from './visibility'; + +function VisibilityChange(props: any) { + const { + onAppear, + onDisappear, + children, + } = props; + + const ref = useRef(null); + + const listen = useCallback((eventName: string, handler: Function) => { + const { current } = ref; + // Rax components will set custom ref by useImperativeHandle. + // So We should get eventTarget by _nativeNode. + // https://github.com/raxjs/rax-components/blob/master/packages/rax-textinput/src/index.tsx#L151 + if (current && isFunction(handler)) { + const eventTarget = current._nativeNode || current; + observerElement(eventTarget as HTMLElement); + eventTarget.addEventListener(eventName, handler); + } + return () => { + const { current } = ref; + if (current) { + const eventTarget = current._nativeNode || current; + eventTarget.removeEventListener(eventName, handler); + } + }; + }, [ref]); + + useEffect(() => listen(VisibilityChangeEvent.appear, onAppear), [ref, onAppear, listen]); + useEffect(() => listen(VisibilityChangeEvent.disappear, onDisappear), [ref, onDisappear, listen]); + + return Children.only({ ...children, ref }); +} + +export default VisibilityChange; diff --git a/packages/rax-compat/src/intersection-observer.ts b/packages/appear/src/intersection-observer.ts similarity index 97% rename from packages/rax-compat/src/intersection-observer.ts rename to packages/appear/src/intersection-observer.ts index 73c2ceffa..ef61953f1 100644 --- a/packages/rax-compat/src/intersection-observer.ts +++ b/packages/appear/src/intersection-observer.ts @@ -1,3 +1,4 @@ +// @ts-nocheck /** * An IntersectionObserver registry. This registry exists to hold a strong * reference to IntersectionObserver instances currently observing a target @@ -165,7 +166,7 @@ export default class IntersectionObserver { if (!Array.isArray(threshold)) threshold = [threshold]; return threshold.sort().filter((t, i, a) => { - if (typeof t != 'number' || isNaN(t) || t < 0 || t > 1) { + if (typeof t != 'number' || Number.isNaN(t) || t < 0 || t > 1) { throw new Error('threshold must be a number between 0 and 1 inclusively'); } return t !== a[i - 1]; @@ -515,12 +516,12 @@ function throttle(fn, timeout) { * @param {Node} node The DOM node to add the event handler to. * @param {string} event The event name. * @param {Function} fn The event handler to add. - * @param {boolean} opt_useCapture Optionally adds the even to the capture + * @param {boolean} useCapture Optionally adds the even to the capture * phase. Note: this only works in modern browsers. */ -function addEvent(node, event, fn, opt_useCapture) { +function addEvent(node, event, fn, useCapture) { if (typeof node.addEventListener == 'function') { - node.addEventListener(event, fn, opt_useCapture || false); + node.addEventListener(event, fn, useCapture || false); } else if (typeof node.attachEvent == 'function') { node.attachEvent(`on${event}`, fn); } @@ -532,12 +533,12 @@ function addEvent(node, event, fn, opt_useCapture) { * @param {Node} node The DOM node to remove the event handler from. * @param {string} event The event name. * @param {Function} fn The event handler to remove. - * @param {boolean} opt_useCapture If the event handler was added with this + * @param {boolean} useCapture If the event handler was added with this * flag set to true, it should be set to true here in order to remove it. */ -function removeEvent(node, event, fn, opt_useCapture) { +function removeEvent(node, event, fn, useCapture) { if (typeof node.removeEventListener == 'function') { - node.removeEventListener(event, fn, opt_useCapture || false); + node.removeEventListener(event, fn, useCapture || false); } else if (typeof node.detatchEvent == 'function') { node.detatchEvent(`on${event}`, fn); } diff --git a/packages/appear/src/type.ts b/packages/appear/src/type.ts new file mode 100644 index 000000000..31715de31 --- /dev/null +++ b/packages/appear/src/type.ts @@ -0,0 +1,3 @@ +export function isFunction(obj: any): obj is Function { + return typeof obj === 'function'; +} \ No newline at end of file diff --git a/packages/rax-compat/src/visibility.ts b/packages/appear/src/visibility.ts similarity index 95% rename from packages/rax-compat/src/visibility.ts rename to packages/appear/src/visibility.ts index 6c7b8a20e..ba9ac5629 100644 --- a/packages/rax-compat/src/visibility.ts +++ b/packages/appear/src/visibility.ts @@ -1,9 +1,9 @@ // Handle appear and disappear event. // Fork from https://github.com/raxjs/appear-polyfill -// @ts-ignore +// @ts-nocheck import PolyfilledIntersectionObserver from './intersection-observer'; -enum VisibilityChangeEvent { +export enum VisibilityChangeEvent { appear = 'appear', disappear = 'disappear', } @@ -72,7 +72,7 @@ function handleIntersect(entries: IntersectionObserverEntry[]) { } = entry; // No `top` value in polyfill. const currentY = boundingClientRect.y || boundingClientRect.top; - const beforeY = parseInt(target.getAttribute('data-before-current-y')) || currentY; + const beforeY = parseInt(target.getAttribute('data-before-current-y'), 10) || currentY; // is in view if ( @@ -92,7 +92,7 @@ function handleIntersect(entries: IntersectionObserverEntry[]) { ) { target.setAttribute('data-appeared', 'false'); target.setAttribute('data-has-disappeared', 'true'); - target.dispatchEvent(createEvent(VisibilityChangeEvent.appear, { + target.dispatchEvent(createEvent(VisibilityChangeEvent.disappear, { direction: currentY > beforeY ? VisibilityChangeDirection.up : VisibilityChangeDirection.down, })); } diff --git a/packages/appear/tests/visibilityChange.test.tsx b/packages/appear/tests/visibilityChange.test.tsx new file mode 100644 index 000000000..38b378b08 --- /dev/null +++ b/packages/appear/tests/visibilityChange.test.tsx @@ -0,0 +1,22 @@ +import { it, describe } from 'vitest'; +import { render } from '@testing-library/react'; +import React from 'react'; +import VisibilityChange from '../src/index'; + +describe('visibilytyChange', () => { + it('appear', () => { + return new Promise(resolve => { + function App() { + return (<VisibilityChange + onAppear={() => { + resolve(); + }} + > + <span>content</span> + </VisibilityChange>); + } + + render(<App />); + }); + }); +}); diff --git a/packages/appear/tsconfig.json b/packages/appear/tsconfig.json new file mode 100644 index 000000000..ec4381e7d --- /dev/null +++ b/packages/appear/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "baseUrl": "./", + "rootDir": "src", + "outDir": "esm" + }, + "allowJs": true, + "include": [ + "src" + ] +} \ No newline at end of file diff --git a/packages/bundles/package.json b/packages/bundles/package.json index 15e482113..c8aebc342 100644 --- a/packages/bundles/package.json +++ b/packages/bundles/package.json @@ -10,11 +10,13 @@ ], "scripts": { "watch": "tsc -w", - "build": "esmo scripts/build.ts && tsc" + "build": "tsx scripts/build.ts && tsc" }, "main": "./esm/index.js", "type": "module", "dependencies": { + "ansi-html-community": "^0.0.8", + "html-entities": "^2.3.2", "@swc/core": "1.2.210", "caniuse-lite": "^1.0.30001332", "chokidar": "3.5.3", @@ -22,7 +24,10 @@ "jest-worker": "27.5.1", "less": "4.1.2", "postcss": "8.4.12", - "sass": "1.50.0" + "sass": "1.50.0", + "react-refresh": "0.14.0", + "core-js-pure": "^3.8.1", + "error-stack-parser": "^2.0.6" }, "devDependencies": { "@types/cacache": "^15.0.1", @@ -41,7 +46,7 @@ "fs-extra": "^10.0.0", "less-loader": "10.2.0", "lodash": "4.17.21", - "mini-css-extract-plugin": "2.6.0", + "mini-css-extract-plugin": "2.6.1", "ora": "5.4.1", "postcss-loader": "6.2.1", "postcss-modules": "4.3.1", @@ -50,12 +55,39 @@ "postcss-preset-env": "7.4.3", "sass-loader": "12.6.0", "tapable": "2.2.1", - "terser": "5.12.1", - "terser-webpack-plugin": "5.3.1", + "terser": "5.14.2", + "terser-webpack-plugin": "5.3.5", "typescript": "^4.6.4", - "webpack": "5.73.0", + "webpack": "5.74.0", "webpack-bundle-analyzer": "4.5.0", - "webpack-dev-server": "4.8.1", - "webpack-sources": "3.2.3" + "webpack-dev-server": "4.10.0", + "webpack-sources": "3.2.3", + "unplugin": "0.9.5", + "bonjour-service": "^1.0.13", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "portfinder": "^1.0.28", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.0.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.21", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.4.2", + "globby": "13.1.2", + "@pmmmwh/react-refresh-webpack-plugin": "0.5.7", + "loader-utils": "^2.0.0", + "source-map": "0.8.0-beta.0", + "find-up": "5.0.0", + "common-path-prefix": "3.0.0" } } diff --git a/packages/bundles/scripts/build.ts b/packages/bundles/scripts/build.ts index 92159b87e..26a4c2e91 100644 --- a/packages/bundles/scripts/build.ts +++ b/packages/bundles/scripts/build.ts @@ -26,6 +26,7 @@ interface Options { declaration?: boolean; bundleName?: string; emptyDir?: boolean; + skipCompile?: boolean; matchCopyFiles?: (data: { resolvePath: string; resolveId: string; @@ -35,7 +36,7 @@ interface Options { export async function packDependency(options: Options): Promise<void> { const { pkgName, file, rootDir, target, externals, matchCopyFiles, patch, emptyDir = true, - bundleName = 'index.js', minify = true, declaration = true } = options; + bundleName = 'index.js', minify = true, declaration = true, skipCompile } = options; console.log(chalk.green(`start pack ${pkgName || file}`)); const targetPath = path.join(rootDir, target); @@ -48,58 +49,60 @@ export async function packDependency(options: Options): Promise<void> { }); fs.ensureDirSync(targetPath); - const { code, assets } = await ncc(packEntry, { - cache: false, - externals, - minify, - target: 'es5', - assetsBuilds: false, - customEmit(filePath: string, opts: {id: string}) { - const { id } = opts; - if (matchCopyFiles && matchCopyFiles({ - resolvePath: filePath, - resolveId: id, - })) { - filesToCopy.push(require.resolve(filePath, { - paths: [path.dirname(id)], - })); + if (!skipCompile) { + const { code, assets } = await ncc(packEntry, { + cache: false, + externals, + minify, + target: 'es5', + assetsBuilds: false, + customEmit(filePath: string, opts: {id: string}) { + const { id } = opts; + if (matchCopyFiles && matchCopyFiles({ + resolvePath: filePath, + resolveId: id, + })) { + filesToCopy.push(require.resolve(filePath, { + paths: [path.dirname(id)], + })); - return `'./${path.basename(filePath)}'`; + return `'./${path.basename(filePath)}'`; + } + }, + }); + for (const assetKey of Object.keys(assets)) { + const asset = assets[assetKey]; + const data = asset.source; + const fileTarget = path.join(targetPath, assetKey); + fs.ensureDirSync(path.dirname(fileTarget)); + fs.writeFileSync(fileTarget, data); + } + // copy files + for (const fileToCopy of filesToCopy) { + let content = fs.readFileSync(fileToCopy, 'utf-8'); + for (const key of Object.keys(externals)) { + content = content.replace( + new RegExp(`require\\(['"]${key}['"]\\)`, 'gm'), + `require('${externals[key]}')`, + ); + content = content.replace( + new RegExp(`require\\(['"]${key}/package(.json)?['"]\\)`, 'gm'), + `require('${externals[key]}/package.json')`, + ); } - }, - }); - for (const assetKey of Object.keys(assets)) { - const asset = assets[assetKey]; - const data = asset.source; - const fileTarget = path.join(targetPath, assetKey); - fs.ensureDirSync(path.dirname(fileTarget)); - fs.writeFileSync(fileTarget, data); - } - // copy files - for (const fileToCopy of filesToCopy) { - let content = fs.readFileSync(fileToCopy, 'utf-8'); - for (const key of Object.keys(externals)) { - content = content.replace( - new RegExp(`require\\(['"]${key}['"]\\)`, 'gm'), - `require('${externals[key]}')`, - ); - content = content.replace( - new RegExp(`require\\(['"]${key}/package(.json)?['"]\\)`, 'gm'), - `require('${externals[key]}/package.json')`, + const copyTarget = path.join(targetPath, path.basename(fileToCopy)); + console.log(chalk.green(`fileToCopy ${copyTarget}`)); + fs.writeFileSync( + copyTarget, + content, + 'utf-8', ); } - const copyTarget = path.join(targetPath, path.basename(fileToCopy)); - console.log(chalk.green(`fileToCopy ${copyTarget}`)); - fs.writeFileSync( - copyTarget, - content, - 'utf-8', - ); + // write code to package + const outfile = path.join(targetPath, bundleName); + fs.ensureDirSync(path.dirname(outfile)); + fs.writeFileSync(path.join(targetPath, bundleName), code, 'utf-8'); } - // write code to package - const outfile = path.join(targetPath, bundleName); - fs.ensureDirSync(path.dirname(outfile)); - fs.writeFileSync(path.join(targetPath, bundleName), code, 'utf-8'); if (pkgName) { const packageRoot = path.dirname( findUp.sync('package.json', { diff --git a/packages/bundles/scripts/tasks.ts b/packages/bundles/scripts/tasks.ts index 628e9b548..7ca7e437e 100644 --- a/packages/bundles/scripts/tasks.ts +++ b/packages/bundles/scripts/tasks.ts @@ -1,6 +1,7 @@ import path from 'path'; import { fileURLToPath } from 'url'; import fs from 'fs-extra'; +import { globbySync } from 'globby'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -18,17 +19,28 @@ export const taskExternals = { postcss: 'postcss', '@swc/core': '@swc/core', 'jest-worker': 'jest-worker', - terser: '@ice/bundles/compiled/terser', - tapable: '@ice/bundles/compiled/tapable', - cssnano: '@ice/bundles/compiled/cssnano', - // depend by webpack - 'terser-webpack-plugin': '@ice/bundles/compiled/terser-webpack-plugin', - webpack: '@ice/bundles/compiled/webpack', - 'schema-utils': '@ice/bundles/compiled/schema-utils', - lodash: '@ice/bundles/compiled/lodash', - 'postcss-preset-env': '@ice/bundles/compiled/postcss-preset-env', }; +const commonDeps = ['terser', 'tapable', 'cssnano', 'terser-webpack-plugin', 'webpack', 'schema-utils', +'lodash', 'postcss-preset-env', 'loader-utils', 'find-up', 'common-path-prefix']; + +const webpackDevServerDeps = ['bonjour-service', 'colorette', 'compression', 'connect-history-api-fallback', +'default-gateway', 'express', 'graceful-fs', 'http-proxy-middleware', +'ipaddr.js', 'open', 'p-retry', 'portfinder', 'rimraf', 'selfsigned', 'serve-index', +'sockjs', 'spdy', 'webpack-dev-middleware', 'ws']; + +commonDeps.concat(webpackDevServerDeps).forEach(dep => taskExternals[dep] = `@ice/bundles/compiled/${dep}`); + +function replaceDeps(code: string, deps: string[]) { + return deps.reduce((acc, curr) => { + return acc + // cjs + .replace(new RegExp(`require\\(["']${curr}["']\\)`, 'g'), `require("${`@ice/bundles/compiled/${curr}`}")`) + // esm + .replace(new RegExp(`from ["']${curr}["']`, 'g'), `from "${`@ice/bundles/compiled/${curr}`}"`); + }, code); +} + export function filterExternals(externals: Record<string, string>, keys: string[]) { const filterExternals = {}; Object.keys(externals).forEach((externalKey) => { @@ -45,8 +57,26 @@ const tasks = [ 'less-loader', 'postcss-loader', 'sass-loader', 'css-loader', 'postcss-preset-env', 'postcss-nested', 'postcss-modules', 'postcss-plugin-rpx2vw', 'webpack-bundle-analyzer', 'es-module-lexer', 'terser', - 'eslint-webpack-plugin', 'copy-webpack-plugin', 'cacache', 'ora', + 'eslint-webpack-plugin', 'copy-webpack-plugin', 'cacache', 'ora', 'unplugin', + // Dependencies of react-refresh-webpack-plugin. + 'loader-utils', 'source-map', 'find-up', 'common-path-prefix', + // Dependencies of webpack-dev-server. + ...webpackDevServerDeps, ].map((pkgName) => ({ pkgName })), + { + pkgName: 'unplugin', + declaration: false, + emptyDir: false, + file: 'node_modules/unplugin/dist/webpack/loaders/transform.js', + bundleName: 'webpack/loaders/transform.js', + }, + { + pkgName: 'unplugin', + declaration: false, + emptyDir: false, + file: 'node_modules/unplugin/dist/webpack/loaders/load.js', + bundleName: 'webpack/loaders/load.js', + }, { // pack main package pkgName: 'fork-ts-checker-webpack-plugin', @@ -74,6 +104,19 @@ const tasks = [ return resolvePath.includes('./utils') && resolveId.includes('css-minimizer-webpack-plugin/dist'); }, }, + { + pkgName: 'mini-css-extract-plugin', + skipCompile: true, + patch: () => { + // copy packages + const pkgPath = path.join(__dirname, '../node_modules/mini-css-extract-plugin'); + const targetPath = path.join(__dirname, '../compiled/mini-css-extract-plugin'); + const entryPath = path.join(targetPath, 'dist/index.js'); + fs.copySync(path.join(pkgPath, 'dist'), path.join(targetPath, 'dist')); + fs.copyFileSync(path.join(targetPath, 'index.d.ts'), path.join(targetPath, 'dist/index.d.ts')); + fs.writeFileSync(entryPath, fs.readFileSync(entryPath, 'utf-8').replace('schema-utils', '@ice/bundles/compiled/schema-utils/index.js')); + }, + }, { pkgName: 'terser-webpack-plugin', matchCopyFiles: (data: { resolvePath: string; resolveId: string }): boolean => { @@ -81,6 +124,47 @@ const tasks = [ return resolvePath.endsWith('./utils') || resolvePath.endsWith('.json'); }, }, + { + pkgName: 'webpack-dev-server', + skipCompile: true, + patch: () => { + // Copy webpack-dev-server while all dependencies has been packed. + const pkgPath = path.join(__dirname, '../node_modules/webpack-dev-server'); + const filePaths = globbySync(['**/*'], { cwd: pkgPath, ignore: ['node_modules', 'types', 'bin'] }); + filePaths.forEach((filePath) => { + fs.ensureDirSync(path.join(__dirname, `../compiled/webpack-dev-server/${path.dirname(filePath)}`)); + const sourcePath = path.join(pkgPath, filePath); + const targetPath = path.join(__dirname, `../compiled/webpack-dev-server/${filePath}`); + if (path.extname(filePath) === '.js') { + const fileContent = fs.readFileSync(sourcePath, 'utf8'); + fs.writeFileSync(targetPath, replaceDeps(fileContent, webpackDevServerDeps.concat(commonDeps))); + } else { + fs.copyFileSync(sourcePath, targetPath); + } + }); + }, + }, + { + pkgName: '@pmmmwh/react-refresh-webpack-plugin', + skipCompile: true, + patch: () => { + // Copy @pmmmwh/react-refresh-webpack-plugin while all dependencies has been packed. + const pkgPath = path.join(__dirname, '../node_modules/@pmmmwh/react-refresh-webpack-plugin'); + const filePaths = globbySync(['**/*'], { cwd: pkgPath, ignore: ['node_modules', 'types'] }); + filePaths.forEach((filePath) => { + fs.ensureDirSync(path.join(__dirname, `../compiled/@pmmmwh/react-refresh-webpack-plugin/${path.dirname(filePath)}`)); + const sourcePath = path.join(pkgPath, filePath); + const targetPath = path.join(__dirname, `../compiled/@pmmmwh/react-refresh-webpack-plugin/${filePath}`); + if (path.extname(filePath) === '.js') { + const fileContent = fs.readFileSync(sourcePath, 'utf8'); + // Add source-map for react-refresh-webpack-plugin, while other dependencies should pack it. + fs.writeFileSync(targetPath, replaceDeps(fileContent, commonDeps.concat('source-map'))); + } else { + fs.copyFileSync(sourcePath, targetPath); + } + }); + }, + }, { file: './webpack/bundle', pkgName: 'webpack', diff --git a/packages/ice/bin/ice-cli.mjs b/packages/ice/bin/ice-cli.mjs index 7caac50cd..4000793d4 100755 --- a/packages/ice/bin/ice-cli.mjs +++ b/packages/ice/bin/ice-cli.mjs @@ -56,18 +56,6 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); service.run(); }); - program - .command('test') - .description('run tests with jest') - .allowUnknownOption() // allow jest config - .option('--mode <mode>', 'set mode', 'test') - .option('--config <config>', 'use custom config') - .option('--rootDir <rootDir>', 'project root directory', cwd) - .action(async ({ rootDir, ...commandArgs }) => { - process.env.NODE_ENV = 'test'; - await createService({ rootDir, command: 'test', commandArgs }); - }); - program.parse(process.argv); const proc = program.runningCommand; diff --git a/packages/ice/package.json b/packages/ice/package.json index 828061fe0..f03fc95a3 100644 --- a/packages/ice/package.json +++ b/packages/ice/package.json @@ -50,7 +50,7 @@ "dotenv": "^16.0.0", "dotenv-expand": "^8.0.3", "ejs": "^3.1.6", - "esbuild": "^0.14.23", + "esbuild": "^0.14.51", "esbuild-register": "^3.3.2", "fast-glob": "^3.2.11", "find-up": "^5.0.0", @@ -68,8 +68,7 @@ "sass": "^1.49.9", "semver": "^7.3.5", "temp": "^0.9.4", - "trusted-cert": "^1.1.3", - "webpack-dev-server": "^4.7.4" + "trusted-cert": "^1.1.3" }, "devDependencies": { "@types/babel__generator": "^7.6.4", @@ -83,9 +82,11 @@ "@types/sass": "^1.43.1", "@types/temp": "^0.9.1", "chokidar": "^3.5.3", - "react": "^18.0.0", - "unplugin": "^0.9.5", - "webpack": "^5.73.0" + "jest": "^29.0.2", + "react": "^18.2.0", + "unplugin": "^0.9.0", + "webpack": "^5.73.0", + "webpack-dev-server": "^4.7.4" }, "peerDependencies": { "react": ">=18.0.0", diff --git a/packages/ice/src/commands/build.ts b/packages/ice/src/commands/build.ts index b7edadc1c..a7a5775ed 100644 --- a/packages/ice/src/commands/build.ts +++ b/packages/ice/src/commands/build.ts @@ -13,6 +13,7 @@ import { RUNTIME_TMP_DIR, SERVER_OUTPUT_DIR } from '../constant.js'; import generateHTML from '../utils/generateHTML.js'; import emptyDir from '../utils/emptyDir.js'; import getServerEntry from '../utils/getServerEntry.js'; +import { getRoutePathsFromCache } from '../utils/getRoutePaths.js'; const build = async ( context: Context<Config>, @@ -20,11 +21,12 @@ const build = async ( taskConfigs: TaskConfig<Config>[]; serverCompiler: ServerCompiler; spinner: ora.Ora; + dataCache: Map<string, string>; getAppConfig: GetAppConfig; getRoutesConfig: GetRoutesConfig; }, ) => { - const { taskConfigs, serverCompiler, spinner, getAppConfig, getRoutesConfig } = options; + const { taskConfigs, serverCompiler, spinner, getAppConfig, getRoutesConfig, dataCache } = options; const { applyHook, commandArgs, command, rootDir, userConfig } = context; const webpackConfigs = taskConfigs.map(({ config }) => getWebpackConfig({ config, @@ -50,6 +52,7 @@ const build = async ( spinner, applyHook, hooksAPI, + dataCache, }); const { ssg, ssr, server: { format } } = userConfig; // compile server bundle @@ -94,9 +97,11 @@ const build = async ( { preBundle: format === 'esm' && (ssr || ssg), swc: { - // Remove components and getData when ssg and ssr both `false`. - removeExportExprs: (!ssg && !ssr) ? ['default', 'getData', 'getServerData', 'getStaticData'] : [], + keepExports: (!ssg && !ssr) ? ['getConfig'] : null, keepPlatform: 'node', + getRoutePaths: () => { + return getRoutePathsFromCache(dataCache); + }, }, }, ); diff --git a/packages/ice/src/commands/start.ts b/packages/ice/src/commands/start.ts index 2de7f3dc9..2de9e0732 100644 --- a/packages/ice/src/commands/start.ts +++ b/packages/ice/src/commands/start.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import WebpackDevServer from 'webpack-dev-server'; +import WebpackDevServer from '@ice/bundles/compiled/webpack-dev-server/lib/Server.js'; import type { Configuration } from 'webpack-dev-server'; import type { Context, TaskConfig } from 'build-scripts'; import lodash from '@ice/bundles/compiled/lodash/index.js'; @@ -18,6 +18,7 @@ import ServerCompilerPlugin from '../webpack/ServerCompilerPlugin.js'; import ReCompilePlugin from '../webpack/ReCompilePlugin.js'; import getServerEntry from '../utils/getServerEntry.js'; import getRouterBasename from '../utils/getRouterBasename.js'; +import { getRoutePathsFromCache } from '../utils/getRoutePaths.js'; const { merge } = lodash; @@ -56,6 +57,7 @@ const start = async ( webpack, runtimeTmpDir: RUNTIME_TMP_DIR, })); + // Compile server entry after the webpack compilation. const outputDir = webpackConfigs[0].output.path; const { ssg, ssr, server: { format } } = userConfig; @@ -77,9 +79,11 @@ const start = async ( { preBundle: format === 'esm' && (ssr || ssg), swc: { - // Remove components and getData when document only. - removeExportExprs: (!ssg && !ssr) ? ['default', 'getData', 'getServerData', 'getStaticData'] : [], + keepExports: (!ssg && !ssr) ? ['getConfig'] : null, keepPlatform: 'node', + getRoutePaths: () => { + return getRoutePathsFromCache(dataCache); + }, }, }, ], @@ -161,6 +165,7 @@ const start = async ( hooksAPI, spinner, devPath, + dataCache, }); const devServer = new WebpackDevServer(devServerConfig, compiler); devServer.startCallback(() => { diff --git a/packages/ice/src/commands/test.ts b/packages/ice/src/commands/test.ts new file mode 100644 index 000000000..f8d634d44 --- /dev/null +++ b/packages/ice/src/commands/test.ts @@ -0,0 +1,20 @@ +import type { Context, TaskConfig } from 'build-scripts'; +import type { Config } from '@ice/types'; +import type ora from '@ice/bundles/compiled/ora/index.js'; + +function test( + context: Context<Config>, + options: { + taskConfigs: TaskConfig<Config>[]; + spinner: ora.Ora; + }, +) { + const { taskConfigs, spinner } = options; + spinner.stop(); + return { + taskConfigs, + context, + }; +} + +export default test; diff --git a/packages/ice/src/config.ts b/packages/ice/src/config.ts index 816dd3f40..f6d65ea70 100644 --- a/packages/ice/src/config.ts +++ b/packages/ice/src/config.ts @@ -140,10 +140,13 @@ const userConfig = [ }, { name: 'minify', - validation: 'boolean', + validation: 'boolean|string|object', setConfig: (config: Config, minify: UserConfig['minify'], context: UserConfigContext<Config>) => { - if (typeof minify === 'boolean') { + if (typeof minify === 'boolean' || typeof minify === 'string') { config.minify = minify; + } else if (minify && typeof minify === 'object') { + config.minify = minify.type; + config.minimizerOptions = minify.options; } else { // minify code in build, while disable minify in dev config.minify = context.command === 'build'; @@ -179,7 +182,7 @@ const userConfig = [ { name: 'compileDependencies', validation: 'array|boolean', - defaultValue: process.env.NODE_ENV === 'development' ? false : [/node_modules\/*/], + getDefaultValue: () => (process.env.NODE_ENV === 'development' ? false : [/node_modules\/*/]), setConfig: (config: Config, customValue: UserConfig['compileDependencies']) => { let compileRegex: RegExp | false; if (customValue === true) { diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index faa344347..6152c7fad 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -13,6 +13,7 @@ import { createServerCompiler } from './service/serverCompiler.js'; import createWatch from './service/watchSource.js'; import start from './commands/start.js'; import build from './commands/build.js'; +import test from './commands/test.js'; import mergeTaskConfig from './utils/mergeTaskConfig.js'; import getWatchEvents from './getWatchEvents.js'; import { setEnv, updateRuntimeEnv, getCoreEnvKeys } from './utils/runtimeEnv.js'; @@ -93,10 +94,23 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt const runtimeModules = getRuntimeModules(plugins); // register web - ctx.registerTask('web', getWebTask({ rootDir, command })); + ctx.registerTask('web', getWebTask({ rootDir, command, dataCache })); // register config - ['userConfig', 'cliOption'].forEach((configType) => ctx.registerConfig(configType, config[configType])); + ['userConfig', 'cliOption'].forEach((configType) => { + // Support getDefaultValue for config, make easier for get default value in different mode. + const configData = config[configType].map(({ getDefaultValue, ...resetConfig }) => { + if (getDefaultValue && typeof getDefaultValue === 'function') { + return { + ...resetConfig, + defaultValue: getDefaultValue(), + }; + } + return resetConfig; + }); + + ctx.registerConfig(configType, configData); + }); let taskConfigs = await ctx.setup(); @@ -210,7 +224,7 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt reCompileRouteConfig, dataCache, appConfig, - devPath: (routePaths[0] || '').replace(/^[\/\\]/, ''), + devPath: (routePaths[0] || '').replace(/^[/\\]/, ''), spinner: buildSpinner, }); } else if (command === 'build') { @@ -220,6 +234,12 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt taskConfigs, serverCompiler, spinner: buildSpinner, + dataCache, + }); + } else if (command === 'test') { + return await test(ctx, { + taskConfigs, + spinner: buildSpinner, }); } } catch (err) { diff --git a/packages/ice/src/esbuild/cssModules.ts b/packages/ice/src/esbuild/cssModules.ts index adb4954a7..069a69082 100644 --- a/packages/ice/src/esbuild/cssModules.ts +++ b/packages/ice/src/esbuild/cssModules.ts @@ -6,7 +6,6 @@ import { less, sass, postcss } from '@ice/bundles'; import type { Plugin, PluginBuild, OnResolveArgs, OnResolveResult, OnLoadArgs, OnLoadResult } from 'esbuild'; const cssModulesStyleFilter = /\.module\.(css|sass|scss|less)$/; -const CSS_LOADER_NAMESPACE = 'css-loader-namespace'; const STYLE_HANDLER_NAMESPACE = 'style-handler-namespace'; type GenerateScopedNameFunction = (name: string, filename: string, css: string) => string; @@ -27,38 +26,20 @@ const cssModulesPlugin = (options: PluginOptions): Plugin => { build.onResolve({ filter: cssModulesStyleFilter }, onResolve); build.onLoad({ filter: /.*/, namespace: STYLE_HANDLER_NAMESPACE }, onStyleLoad(options)); - - build.onLoad({ filter: /.*/, namespace: CSS_LOADER_NAMESPACE }, onCSSLoad); }, }; }; async function onResolve(args: OnResolveArgs): Promise<OnResolveResult> { - const { namespace, resolveDir } = args; + const { resolveDir } = args; const absolutePath = path.resolve(resolveDir, args.path); - // This is the import in the `STYLE_HANDLER_NAMESPACE` namespace. - // Put the path in the `CSS_LOADER_NAMESPACE` namespace to tell esbuild to load the css file. - if (namespace === STYLE_HANDLER_NAMESPACE) { - return { - path: absolutePath, - namespace: CSS_LOADER_NAMESPACE, - }; - } - // Otherwise, generate css and put it in the `STYLE_HANDLER_NAMESPACE` namespace to handle css file + // Generate css and put it in the `STYLE_HANDLER_NAMESPACE` namespace to handle css file return { path: absolutePath, namespace: STYLE_HANDLER_NAMESPACE, }; } -async function onCSSLoad(args: OnLoadArgs): Promise<OnLoadResult> { - const data = (await fse.readFile(args.path)).toString(); - return { - contents: data, - loader: 'css', - }; -} - /** * parse less/scss/css-modules to css */ diff --git a/packages/ice/src/esbuild/ignore.ts b/packages/ice/src/esbuild/ignore.ts new file mode 100644 index 000000000..6cad91d14 --- /dev/null +++ b/packages/ice/src/esbuild/ignore.ts @@ -0,0 +1,47 @@ +import type { Plugin, PluginBuild } from 'esbuild'; + +interface IgnorePattern { + resourceRegExp: RegExp; + contextRegExp?: RegExp; +} + +const igonrePlugin = (ignores: IgnorePattern[] = []): Plugin => { + return { + name: 'esbuild-ignore', + setup(build: PluginBuild) { + if (!Array.isArray(ignores)) { + return; + } + + for (const ignorePattern of ignores) { + build.onResolve({ filter: ignorePattern.resourceRegExp }, args => { + if (ignorePattern.contextRegExp) { + if (args.resolveDir.match(ignorePattern.contextRegExp)) { + return { + path: args.path, + namespace: 'ignore', + }; + } else { + return { + path: args.path, + }; + } + } + + return { + path: args.path, + namespace: 'ignore', + }; + }); + } + + build.onLoad({ filter: /.*/, namespace: 'ignore' }, async () => { + return { + contents: '', + }; + }); + }, + }; +}; + +export default igonrePlugin; diff --git a/packages/ice/src/esbuild/transformPipe.ts b/packages/ice/src/esbuild/transformPipe.ts index 5e1ccf6c0..56d787abc 100644 --- a/packages/ice/src/esbuild/transformPipe.ts +++ b/packages/ice/src/esbuild/transformPipe.ts @@ -103,11 +103,12 @@ const transformPipe = (options: PluginOptions = {}): Plugin => { const loader = guessLoader(id); const transformedResult = await plugins.reduce(async (prevData, plugin) => { const { contents } = await prevData; - const { transform, transformInclude } = plugin; - if (!transformInclude || transformInclude?.(id)) { - let sourceCode = contents; - let sourceMap = null; - if (plugin.load) { + const { transform, transformInclude, loadInclude } = plugin; + let sourceCode = contents; + let sourceMap = null; + + if (plugin.load) { + if (!loadInclude || loadInclude?.(id)) { const result = await plugin.load.call(pluginContext, id); if (typeof result === 'string') { sourceCode = result; @@ -116,6 +117,9 @@ const transformPipe = (options: PluginOptions = {}): Plugin => { sourceMap = result.map; } } + } + + if (!transformInclude || transformInclude?.(id)) { if (!sourceCode) { // Caution: 'utf8' assumes the input file is not in binary. // If you want your plugin handle binary files, make sure to execute `plugin.load()` first. diff --git a/packages/ice/src/index.ts b/packages/ice/src/index.ts index a1aaa4160..6a50d91db 100644 --- a/packages/ice/src/index.ts +++ b/packages/ice/src/index.ts @@ -5,3 +5,5 @@ export function defineConfig(config: UserConfig) { } export type { UserConfig }; + +export * from './test/index.js'; diff --git a/packages/ice/src/polyfills/react.js b/packages/ice/src/polyfills/react.js deleted file mode 100644 index 933ca5040..000000000 --- a/packages/ice/src/polyfills/react.js +++ /dev/null @@ -1,2 +0,0 @@ -import * as React from 'react'; -export { React }; diff --git a/packages/ice/src/requireHook.ts b/packages/ice/src/requireHook.ts index aad031e7a..a1f8b52cc 100644 --- a/packages/ice/src/requireHook.ts +++ b/packages/ice/src/requireHook.ts @@ -35,7 +35,6 @@ export function getHookFiles() { }); return [ - // ['webpack-dev-server', '@builder/pack/deps/webpack-dev-server'], ['webpack', `${webpackDir}webpack-lib`], ['webpack/lib/webpack', `${webpackDir}webpack-lib`], ['webpack/lib/webpack.js', `${webpackDir}webpack-lib`], diff --git a/packages/ice/src/service/config.ts b/packages/ice/src/service/config.ts index 760959d37..18cc3834e 100644 --- a/packages/ice/src/service/config.ts +++ b/packages/ice/src/service/config.ts @@ -44,7 +44,6 @@ class Config { const { error } = await esbuildCompiler({ entryPoints: [entry], format: 'esm', - inject: [], outfile, plugins: [removeTopLevelCode(keepExports, transformInclude)], }); diff --git a/packages/ice/src/service/runtimeGenerator.ts b/packages/ice/src/service/runtimeGenerator.ts index ccfad710b..7100dcf9c 100644 --- a/packages/ice/src/service/runtimeGenerator.ts +++ b/packages/ice/src/service/runtimeGenerator.ts @@ -44,11 +44,11 @@ export function generateExports(exportList: ExportData[]) { const specifiers = isDefaultImport ? [specifier] : specifier; const symbol = type ? ';' : ','; importStatements.push(`import ${type ? 'type ' : ''}${isDefaultImport ? specifier : `{ ${specifier.join(', ')} }`} from '${source}';`); - exportStatements = specifiers.map((specifierStr) => { + specifiers.forEach((specifierStr) => { if (exportAlias && exportAlias[specifierStr]) { - return `${exportAlias[specifierStr]}: ${specifierStr}${symbol}`; + exportStatements.push(`${exportAlias[specifierStr]}: ${specifierStr}${symbol}`); } else { - return `${specifierStr}${symbol}`; + exportStatements.push(`${specifierStr}${symbol}`); } }); }); diff --git a/packages/ice/src/service/serverCompiler.ts b/packages/ice/src/service/serverCompiler.ts index fd0d15dcd..fb6c0e426 100644 --- a/packages/ice/src/service/serverCompiler.ts +++ b/packages/ice/src/service/serverCompiler.ts @@ -1,5 +1,4 @@ import * as path from 'path'; -import { fileURLToPath } from 'url'; import { createHash } from 'crypto'; import * as fs from 'fs'; import consola from 'consola'; @@ -12,6 +11,7 @@ import { getCompilerPlugins } from '@ice/webpack-config'; import escapeLocalIdent from '../utils/escapeLocalIdent.js'; import cssModulesPlugin from '../esbuild/cssModules.js'; import aliasPlugin from '../esbuild/alias.js'; +import ignorePlugin from '../esbuild/ignore.js'; import createAssetsPlugin from '../esbuild/assets.js'; import { ASSETS_MANIFEST, CACHE_DIR, SERVER_OUTPUT_DIR } from '../constant.js'; import emptyCSSPlugin from '../esbuild/emptyCSS.js'; @@ -24,8 +24,6 @@ import { scanImports } from './analyze.js'; import type { DepsMetaData } from './preBundleCJSDeps.js'; import preBundleCJSDeps from './preBundleCJSDeps.js'; -const __dirname = path.dirname(fileURLToPath(import.meta.url)); - interface Options { rootDir: string; task: TaskConfig<Config>; @@ -112,7 +110,7 @@ export function createServerCompiler(options: Options) { // enable JSX syntax in .js files by default for compatible with migrate project // while it is not recommended loader: { '.js': 'jsx' }, - inject: [path.resolve(__dirname, '../polyfills/react.js')], + jsx: 'automatic', sourcemap: typeof sourceMap === 'boolean' // Transform sourceMap for esbuild. ? sourceMap : (sourceMap.includes('inline') ? 'inline' : !!sourceMap), @@ -127,6 +125,7 @@ export function createServerCompiler(options: Options) { externalDependencies: externalDependencies ?? !server.bundle, format, }), + server?.ignores && ignorePlugin(server.ignores), cssModulesPlugin({ extract: false, generateLocalIdentName: function (name: string, filename: string) { diff --git a/packages/ice/src/service/webpackCompiler.ts b/packages/ice/src/service/webpackCompiler.ts index 9998acdbc..0c5fd716d 100644 --- a/packages/ice/src/service/webpackCompiler.ts +++ b/packages/ice/src/service/webpackCompiler.ts @@ -27,6 +27,7 @@ async function webpackCompiler(options: { getAppConfig: GetAppConfig; getRoutesConfig: GetRoutesConfig; }; + dataCache: Map<string, string>; }) { const { taskConfigs, @@ -39,6 +40,7 @@ async function webpackCompiler(options: { spinner, devPath, rootDir, + dataCache, } = options; const { serverCompiler } = hooksAPI; await applyHook(`before.${command}.run`, { @@ -49,7 +51,7 @@ async function webpackCompiler(options: { ...hooksAPI, }); // Add webpack plugin of data-loader - webpackConfigs[0].plugins.push(new DataLoaderPlugin({ serverCompiler, rootDir })); + webpackConfigs[0].plugins.push(new DataLoaderPlugin({ serverCompiler, rootDir, dataCache })); // Add default plugins for spinner webpackConfigs[0].plugins.push((compiler: Compiler) => { diff --git a/packages/ice/src/tasks/web/index.ts b/packages/ice/src/tasks/web/index.ts index 92e07a1bf..ea3ca7310 100644 --- a/packages/ice/src/tasks/web/index.ts +++ b/packages/ice/src/tasks/web/index.ts @@ -1,8 +1,9 @@ import * as path from 'path'; import type { Config } from '@ice/types'; import { CACHE_DIR, RUNTIME_TMP_DIR } from '../../constant.js'; +import { getRoutePathsFromCache } from '../../utils/getRoutePaths.js'; -const getWebTask = ({ rootDir, command }): Config => { +const getWebTask = ({ rootDir, command, dataCache }): Config => { // basic task config of web task const defaultLogging = command === 'start' ? 'summary' : 'summary assets'; return { @@ -19,10 +20,14 @@ const getWebTask = ({ rootDir, command }): Config => { // getData is built by data-loader removeExportExprs: ['getData', 'getServerData', 'getStaticData'], keepPlatform: 'web', + getRoutePaths: () => { + return getRoutePathsFromCache(dataCache); + }, }, assetsManifest: true, fastRefresh: command === 'start', logging: process.env.WEBPACK_LOGGING || defaultLogging, + minify: command === 'build', }; }; diff --git a/packages/ice/src/test/defineJestConfig.ts b/packages/ice/src/test/defineJestConfig.ts new file mode 100644 index 000000000..a443dab06 --- /dev/null +++ b/packages/ice/src/test/defineJestConfig.ts @@ -0,0 +1,51 @@ +import * as path from 'path'; +import type { Config as JestConfig } from 'jest'; +import fse from 'fs-extra'; +import type { Config } from '@ice/types'; +import lodash from '@ice/bundles/compiled/lodash/index.js'; +import getTaskConfig from './getTaskConfig.js'; + +const { merge } = lodash; + +type UserConfig = JestConfig | (() => Promise<JestConfig>); + +export default function defineJestConfig(userConfig: UserConfig): () => Promise<JestConfig> { + return async () => { + // Support jest configuration (object or function) Ref: https://jestjs.io/docs/configuration + let customConfig: JestConfig; + if (typeof userConfig === 'function') { + customConfig = await userConfig(); + } else { + customConfig = userConfig; + } + + const defaultConfig = await getDefaultConfig(); + + return merge(defaultConfig, customConfig); + }; +} + +async function getDefaultConfig(): JestConfig { + const taskConfig = await getTaskConfig(); + const { config: { alias = {} } } = taskConfig; + + const moduleNameMapper = generateModuleNameMapper(alias); + + return { + moduleNameMapper, + }; +} + +function generateModuleNameMapper(alias: Config['alias']) { + const moduleNameMapper = {}; + for (const key in alias) { + const aliasPath = alias[key]; + if (aliasPath === false) { + continue; + } + const isDir = path.isAbsolute(aliasPath) && fse.lstatSync(aliasPath).isDirectory(); + moduleNameMapper[`^${key}${isDir ? '/(.*)' : ''}`] = `${aliasPath}${isDir ? '/$1' : ''}`; + } + + return moduleNameMapper; +} diff --git a/packages/ice/src/test/defineVitestConfig.ts b/packages/ice/src/test/defineVitestConfig.ts new file mode 100644 index 000000000..6028bc549 --- /dev/null +++ b/packages/ice/src/test/defineVitestConfig.ts @@ -0,0 +1,31 @@ +import type { UserConfigExport, ConfigEnv, UserConfig } from 'vitest/config'; +import lodash from '@ice/bundles/compiled/lodash/index.js'; +import getTaskConfig from './getTaskConfig.js'; + +const { merge } = lodash; + +export default function defineVitestConfig(userConfig: UserConfigExport): UserConfigExport { + return async (env: ConfigEnv) => { + // Support vitest configuration (object or function) Ref: https://github.com/vitest-dev/vitest/blob/e5c40cff0925c3c12d8cdfa59f5649d3562668ce/packages/vitest/src/config.ts#L3 + let customConfig: UserConfig; + if (typeof userConfig === 'function') { + customConfig = await userConfig(env); + } else { + customConfig = await userConfig; + } + + const defaultConfig = await getDefaultConfig(); + + return merge(defaultConfig, customConfig); + }; +} + +async function getDefaultConfig() { + const taskConfig = await getTaskConfig(); + const { config: { alias = {} } } = taskConfig; + return { + resolve: { + alias, + }, + }; +} diff --git a/packages/ice/src/test/getTaskConfig.ts b/packages/ice/src/test/getTaskConfig.ts new file mode 100644 index 000000000..91fd83243 --- /dev/null +++ b/packages/ice/src/test/getTaskConfig.ts @@ -0,0 +1,14 @@ +import createService from '../createService.js'; +import type test from '../commands/test.js'; + +export default async function getTaskConfig() { + const rootDir = process.cwd(); + const { run } = await createService({ + rootDir, + command: 'test', + commandArgs: {}, + }); + const { taskConfigs } = (await run()) as ReturnType<typeof test>; + const webTaskConfig = taskConfigs.find((taskConfig) => taskConfig.name === 'web'); + return webTaskConfig; +} diff --git a/packages/ice/src/test/index.ts b/packages/ice/src/test/index.ts new file mode 100644 index 000000000..4f0c72b73 --- /dev/null +++ b/packages/ice/src/test/index.ts @@ -0,0 +1,2 @@ +export { default as defineJestConfig } from './defineJestConfig.js'; +export { default as defineVitestConfig } from './defineVitestConfig.js'; diff --git a/packages/ice/src/utils/getRoutePaths.ts b/packages/ice/src/utils/getRoutePaths.ts index af0bbe94f..5f40626b0 100644 --- a/packages/ice/src/utils/getRoutePaths.ts +++ b/packages/ice/src/utils/getRoutePaths.ts @@ -21,4 +21,16 @@ function getRoutePaths(routes: RouteObject[], parentPath = ''): string[] { return pathList; } +export function getRoutePathsFromCache(dataCache: Map<string, string>): string[] { + const routes = dataCache.get('routes'); + + const routeManifest = JSON.parse(routes)?.routeManifest || {}; + const routeFiles = Object.keys(routeManifest).map((key) => { + const { file } = routeManifest[key]; + return `src/pages/${file}`; + }); + + return routeFiles; +} + export default getRoutePaths; diff --git a/packages/ice/src/webpack/DataLoaderPlugin.ts b/packages/ice/src/webpack/DataLoaderPlugin.ts index ec0efa5de..b900e28f3 100644 --- a/packages/ice/src/webpack/DataLoaderPlugin.ts +++ b/packages/ice/src/webpack/DataLoaderPlugin.ts @@ -4,6 +4,7 @@ import type { ServerCompiler } from '@ice/types/esm/plugin.js'; import type { Compiler } from 'webpack'; import webpack from '@ice/bundles/compiled/webpack/index.js'; import { RUNTIME_TMP_DIR } from '../constant.js'; +import { getRoutePathsFromCache } from '../utils/getRoutePaths.js'; const pluginName = 'DataLoaderPlugin'; const { RawSource } = webpack.sources; @@ -11,13 +12,17 @@ const { RawSource } = webpack.sources; export default class DataLoaderPlugin { private serverCompiler: ServerCompiler; private rootDir: string; + private dataCache: Map<string, string>; + public constructor(options: { serverCompiler: ServerCompiler; rootDir: string; + dataCache: Map<string, string>; }) { - const { serverCompiler, rootDir } = options; + const { serverCompiler, rootDir, dataCache } = options; this.serverCompiler = serverCompiler; this.rootDir = rootDir; + this.dataCache = dataCache; } public apply(compiler: Compiler) { @@ -34,11 +39,13 @@ export default class DataLoaderPlugin { target: 'esnext', entryPoints: [filePath], write: false, - inject: [], }, { swc: { - removeExportExprs: ['default', 'getConfig', 'getServerData', 'getStaticData'], + keepExports: ['getData', 'getAppData'], keepPlatform: 'web', + getRoutePaths: () => { + return getRoutePathsFromCache(this.dataCache); + }, }, preBundle: false, externalDependencies: false, diff --git a/packages/ice/templates/core/entry.client.ts.ejs b/packages/ice/templates/core/entry.client.ts.ejs index 14f5fb191..2e1923fe6 100644 --- a/packages/ice/templates/core/entry.client.ts.ejs +++ b/packages/ice/templates/core/entry.client.ts.ejs @@ -2,7 +2,6 @@ import { runClientApp, getAppConfig } from '@ice/runtime'; import * as app from '@/app'; import runtimeModules from './runtimeModules'; import routes from './routes'; -import Document from '@/document'; const getRouterBasename = () => { const appConfig = getAppConfig(app); @@ -13,7 +12,6 @@ runClientApp({ app, runtimeModules, routes, - Document, basename: getRouterBasename(), hydrate: <%- hydrate %>, memoryRouter: <%- memoryRouter || false %>, diff --git a/packages/ice/tests/fixtures/preAnalyze/app.ts b/packages/ice/tests/fixtures/preAnalyze/app.ts index 3f2ced768..307b1120f 100644 --- a/packages/ice/tests/fixtures/preAnalyze/app.ts +++ b/packages/ice/tests/fixtures/preAnalyze/app.ts @@ -1,13 +1,13 @@ import type { AppConfig } from 'ice'; import { runApp } from 'ice'; import { request, type Request } from 'ice'; -import page from '@/page'; import url from './a.png'; +import page from '@/page'; console.log(url); runApp({ request, page, -} as AppConfig) +} as AppConfig); export default () => { }; \ No newline at end of file diff --git a/packages/ice/tests/fixtures/removeCode/if.ts b/packages/ice/tests/fixtures/removeCode/if.ts index 431b4b862..a9853fefd 100644 --- a/packages/ice/tests/fixtures/removeCode/if.ts +++ b/packages/ice/tests/fixtures/removeCode/if.ts @@ -1,4 +1,4 @@ -var a = 1; +let a = 1; if (true) { a = 2; } diff --git a/packages/ice/tests/fixtures/removeCode/vars.ts b/packages/ice/tests/fixtures/removeCode/vars.ts index bfb814f71..22bbd3b44 100644 --- a/packages/ice/tests/fixtures/removeCode/vars.ts +++ b/packages/ice/tests/fixtures/removeCode/vars.ts @@ -4,10 +4,10 @@ import c from 'c'; import d from 'd'; const [e, f, ...rest] = a; -const {h, j} = b; +const { h, j } = b; const [x, ...m] = c; const zz = 'x'; -const {k, l, ...s} = d; +const { k, l, ...s } = d; export function getConfig() { return { diff --git a/packages/ice/tests/fixtures/removeCode/while.ts b/packages/ice/tests/fixtures/removeCode/while.ts index abc8e1707..992a78675 100644 --- a/packages/ice/tests/fixtures/removeCode/while.ts +++ b/packages/ice/tests/fixtures/removeCode/while.ts @@ -1,5 +1,5 @@ -var j = 2; -var i = 2; +let j = 2; +let i = 2; while (j < 3) { j++; } diff --git a/packages/ice/tests/formatWebpackMessages.test.ts b/packages/ice/tests/formatWebpackMessages.test.ts new file mode 100644 index 000000000..fc02a7c26 --- /dev/null +++ b/packages/ice/tests/formatWebpackMessages.test.ts @@ -0,0 +1,71 @@ +import { expect, it, describe } from 'vitest'; +import formatWebpackMessages from '../src/utils/formatWebpackMessages'; + +describe('webpack message formatting', () => { + it('format syntax error', () => { + const result = formatWebpackMessages({ + errors: [{ message: 'Syntax error: Unterminated JSX contents (8:13)' }, { message: 'Module error' }], + warnings: [], + }); + expect(result.errors.length).toBe(1); + }); + + it('formats aliased unknown export 1', () => { + const result = formatWebpackMessages({ + errors: [{ message: 'export \'bar\' (imported as \'bar2\') was not found in \'./AppUnknownExport\'' }], + warnings: [], + }); + expect(result.errors[0]).toBe('Attempted import error: \'bar\' is not exported from \'./AppUnknownExport\' (imported as \'bar2\').'); + }); + + it('formats cannot find module sass', () => { + const result = formatWebpackMessages({ + errors: [{ message: '\nCannot find module.import sass from \'sass\'' }], + warnings: [], + }); + expect(result.errors[0]).toBe('To import Sass files, you first need to install sass.\nRun `npm install sass` or `yarn add sass` inside your workspace.'); + }); + + it('formats module no found', () => { + const result = formatWebpackMessages({ + errors: [{ message: '\nModule not found: Cannot find file: \'./ThisFileSouldNotExist\' in \'./src\'' }], + warnings: [], + }); + expect(result.errors[0]).toBe('Cannot find file: \'./ThisFileSouldNotExist\' in \'./src\''); + }); + + it('remove leading newline', () => { + const result = formatWebpackMessages({ + errors: [{ message: 'line1\n\n\n\nline3' }], + warnings: [], + }); + expect(result.errors[0]).toBe('line1\n\nline3'); + }); + + it('nested message', () => { + const result = formatWebpackMessages({ + // @ts-ignore + errors: [[{ message: 'line1' }, { message: 'line2\nline3' }]], + warnings: [], + }); + expect(result.errors[0]).toBe('line2\nline3'); + }); + + it('string message', () => { + const result = formatWebpackMessages({ + // @ts-ignore + errors: ['line2\nline3'], + warnings: [], + }); + expect(result.errors[0]).toBe('line2\nline3'); + }); + + it('eslint error', () => { + const result = formatWebpackMessages({ + errors: [{ message: 'Line 4:13: Parsing error: \'b\' is not defined no-undef' }], + warnings: [], + }); + expect(result.errors[0]).toBe('Syntax error: \'b\' is not defined no-undef (4:13)'); + }); +}); + diff --git a/packages/ice/tests/generator.test.ts b/packages/ice/tests/generator.test.ts index 5535cc0de..cf33efca7 100644 --- a/packages/ice/tests/generator.test.ts +++ b/packages/ice/tests/generator.test.ts @@ -9,7 +9,7 @@ describe('generateExports', () => { type: false, }]); expect(importStr).toBe('import Router from \'react-router\';'); - expect(exportStr).toBe('Router,') + expect(exportStr).toBe('Router,'); }); it('type export', () => { const { importStr, exportStr } = generateExports([{ @@ -18,7 +18,7 @@ describe('generateExports', () => { type: true, }]); expect(importStr).toBe('import type Router from \'react-router\';'); - expect(exportStr).toBe('Router;') + expect(exportStr).toBe('Router;'); }); it('named exports', () => { const { importStr, exportStr } = generateExports([{ @@ -34,7 +34,7 @@ describe('generateExports', () => { source: 'react-helmet', specifier: 'Helmet', exportAlias: { - 'Helmet': 'Head', + Helmet: 'Head', }, }]); expect(importStr).toBe('import Helmet from \'react-helmet\';'); @@ -52,40 +52,20 @@ const defaultExportData = [{ describe('checkExportData', () => { it('basic usage', () => { - try { - checkExportData(defaultExportData, { source: 'react-dom', specifier: 'react-dom' }, 'test-api'); - expect(true).toBe(true); - } catch (err) { - expect(true).toBe(false); - } + checkExportData(defaultExportData, { source: 'react-dom', specifier: 'react-dom' }, 'test-api'); }); it('duplicate named export', () => { - try { - checkExportData(defaultExportData, defaultExportData[0], 'test-api'); - expect(true).toBe(false); - } catch (err) { - expect(true).toBe(true); - } - }) + expect(() => checkExportData(defaultExportData, defaultExportData[0], 'test-api')).toThrow(); + }); it('duplicate exports', () => { - try { - checkExportData(defaultExportData, defaultExportData, 'test-api'); - expect(true).toBe(false); - } catch (err) { - expect(true).toBe(true); - } - }) + expect(() => checkExportData(defaultExportData, defaultExportData, 'test-api')).toThrow(); + }); it('duplicate default export', () => { - try { - checkExportData(defaultExportData, { source: 'react-dom', specifier: 'Switch' }, 'test-api'); - expect(true).toBe(false); - } catch (err) { - expect(true).toBe(true); - } - }) + expect(() => checkExportData(defaultExportData, { source: 'react-dom', specifier: 'Switch' }, 'test-api')).toThrow(); + }); }); describe('removeExportData', () => { @@ -102,4 +82,4 @@ describe('removeExportData', () => { const removed = removeExportData(defaultExportData, ['react-router', 'react-helmet']); expect(removed.length).toBe(0); }); -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/packages/ice/tests/openBrowser.test.ts b/packages/ice/tests/openBrowser.test.ts new file mode 100644 index 000000000..fb8a64d90 --- /dev/null +++ b/packages/ice/tests/openBrowser.test.ts @@ -0,0 +1,12 @@ +import { expect, it, describe } from 'vitest'; +import openBrowser from '../src/utils/openBrowser'; + +describe('openBrowser in node', () => { + it('open localhost', () => { + process.env.BROWSER = 'none'; + const result = openBrowser('http://localhost/'); + expect(result).toBe(false); + }); + + // TODO simulate open browser in node +}); \ No newline at end of file diff --git a/packages/ice/tests/preAnalyze.test.ts b/packages/ice/tests/preAnalyze.test.ts index b640ff22b..65860355d 100644 --- a/packages/ice/tests/preAnalyze.test.ts +++ b/packages/ice/tests/preAnalyze.test.ts @@ -1,6 +1,6 @@ -import { expect, it, describe } from 'vitest'; import * as path from 'path'; import { fileURLToPath } from 'url'; +import { expect, it, describe } from 'vitest'; import { analyzeImports, getImportPath, resolveId, type Alias } from '../src/service/analyze'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -17,7 +17,7 @@ describe('resolveId', () => { expect(id).toBe('/.ice/runApp/test'); }); it('alias: { ice$: \'/.ice/runApp\'}; id: ice/test', () => { - const alias = { 'ice$': '/.ice/runApp' }; + const alias = { ice$: '/.ice/runApp' }; const id = resolveId('ice/test', alias); expect(id).toBe('ice/test'); }); @@ -27,7 +27,7 @@ describe('resolveId', () => { expect(id).toBe(false); }); it('alias: { foundnamejs: \'/user/folder\'}; id: foundnamejs', () => { - const alias = { 'foundnamejs': '/user/folder' }; + const alias = { foundnamejs: '/user/folder' }; const id = resolveId('foundnamejs', alias); expect(id).toBe('/user/folder'); }); @@ -46,7 +46,7 @@ describe('getImportPath', () => { expect(filePath.replace(/^[A-Za-z]:/, '')).toBe('/rootDir/page.js'); }); it('import from alias', () => { - const filePath = getImportPath('ice', '/rootDir/test.ts', { ice: '/rootDir/component.tsx'}); + const filePath = getImportPath('ice', '/rootDir/test.ts', { ice: '/rootDir/component.tsx' }); expect(filePath).toBe('/rootDir/component.tsx'); }); it('import node_module dependency', () => { @@ -57,7 +57,7 @@ describe('getImportPath', () => { describe('analyzeImports', () => { it('basic usage', async () => { - const entryFile = path.join(__dirname, './fixtures/preAnalyze/app.ts'); + const entryFile = path.join(__dirname, './fixtures/preAnalyze/app.ts'); const analyzeSet = await analyzeImports([entryFile], { analyzeRelativeImport: true, alias: { @@ -65,5 +65,5 @@ describe('analyzeImports', () => { }, }); expect([...(analyzeSet || [])]).toStrictEqual(['runApp', 'request', 'store']); - }) + }); }); \ No newline at end of file diff --git a/packages/ice/tests/preBundleCJSDeps.test.ts b/packages/ice/tests/preBundleCJSDeps.test.ts index 65a81db94..3d528b754 100644 --- a/packages/ice/tests/preBundleCJSDeps.test.ts +++ b/packages/ice/tests/preBundleCJSDeps.test.ts @@ -1,7 +1,7 @@ -import { afterAll, expect, it } from 'vitest'; import * as path from 'path'; -import fse from 'fs-extra'; import { fileURLToPath } from 'url'; +import { afterAll, expect, it } from 'vitest'; +import fse from 'fs-extra'; import preBundleCJSDeps from '../src/service/preBundleCJSDeps'; import { scanImports } from '../src/service/analyze'; @@ -16,7 +16,7 @@ it('prebundle cjs deps', async () => { depsInfo: deps, cacheDir, alias, - taskConfig: { mode: 'production' } + taskConfig: { mode: 'production' }, }); expect(fse.pathExistsSync(path.join(cacheDir, 'deps', 'react.js'))).toBeTruthy(); diff --git a/packages/ice/tests/removeTopLevelCode.test.ts b/packages/ice/tests/removeTopLevelCode.test.ts index 5ed015e20..ab8619258 100644 --- a/packages/ice/tests/removeTopLevelCode.test.ts +++ b/packages/ice/tests/removeTopLevelCode.test.ts @@ -3,7 +3,7 @@ import * as fs from 'fs'; import { fileURLToPath } from 'url'; import { expect, it, describe } from 'vitest'; import { parse, type ParserOptions } from '@babel/parser'; -import traverse from '@babel/traverse' +import traverse from '@babel/traverse'; import generate from '@babel/generator'; import removeTopLevelCodePlugin from '../src/utils/babelPluginRemoveCode'; @@ -19,7 +19,7 @@ const parserOptions: ParserOptions = { 'classPrivateMethods', 'typescript', 'decorators-legacy', - ] + ], }; describe('remove top level code', () => { @@ -27,19 +27,19 @@ describe('remove top level code', () => { const ast = parse(fs.readFileSync(path.join(__dirname, './fixtures/removeCode/export-specifier.ts'), 'utf-8'), parserOptions); traverse(ast, removeTopLevelCodePlugin(['getConfig'])); const content = generate(ast).code; - expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe(`const getConfig = () => {};export { getConfig };`); + expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe('const getConfig = () => {};export { getConfig };'); }); it('remove variable export', () => { const ast = parse(fs.readFileSync(path.join(__dirname, './fixtures/removeCode/export-variable.ts'), 'utf-8'), parserOptions); traverse(ast, removeTopLevelCodePlugin(['getConfig'])); const content = generate(ast).code; - expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe(`export const getConfig = () => {};`); + expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe('export const getConfig = () => {};'); }); it('remove function export', () => { const ast = parse(fs.readFileSync(path.join(__dirname, './fixtures/removeCode/function-exports.ts'), 'utf-8'), parserOptions); traverse(ast, removeTopLevelCodePlugin(['getConfig'])); const content = generate(ast).code; - expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe(`export function getConfig() {}`); + expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe('export function getConfig() {}'); }); it('remove if statement', () => { const ast = parse(fs.readFileSync(path.join(__dirname, './fixtures/removeCode/if.ts'), 'utf-8'), parserOptions); @@ -51,7 +51,7 @@ describe('remove top level code', () => { const ast = parse(fs.readFileSync(path.join(__dirname, './fixtures/removeCode/import.ts'), 'utf-8'), parserOptions); traverse(ast, removeTopLevelCodePlugin(['getConfig'])); const content = generate(ast).code; - expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe(`export function getConfig() { return { a: 1 };}`); + expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe('export function getConfig() { return { a: 1 };}'); }); it('remove IIFE code', () => { const ast = parse(fs.readFileSync(path.join(__dirname, './fixtures/removeCode/iife.ts'), 'utf-8'), parserOptions); @@ -76,14 +76,14 @@ describe('remove top level code', () => { const ast = parse(fs.readFileSync(path.join(__dirname, './fixtures/removeCode/vars.ts'), 'utf-8'), parserOptions); traverse(ast, removeTopLevelCodePlugin(['getConfig'])); const content = generate(ast).code; - expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe(`import c from 'c';import d from 'd';const [x] = c;const { k} = d;export function getConfig() { return { x, k };}`); + expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe('import c from \'c\';import d from \'d\';const [x] = c;const { k} = d;export function getConfig() { return { x, k };}'); }); it('keep export default', () => { const ast = parse(fs.readFileSync(path.join(__dirname, './fixtures/removeCode/export-default.ts'), 'utf-8'), parserOptions); traverse(ast, removeTopLevelCodePlugin(['default'])); const content = generate(ast).code; - expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe(`const a = 1;export default a;`); + expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe('const a = 1;export default a;'); }); it('remove expression statement', () => { @@ -92,4 +92,4 @@ describe('remove top level code', () => { const content = generate(ast).code; expect(content.replace(/\n/g, '').replace(/\s+/g, ' ')).toBe(''); }); -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/packages/ice/tests/scan.test.ts b/packages/ice/tests/scan.test.ts index fbc07d5de..48cb3bf44 100644 --- a/packages/ice/tests/scan.test.ts +++ b/packages/ice/tests/scan.test.ts @@ -1,6 +1,6 @@ -import { expect, it, describe } from 'vitest'; import * as path from 'path'; import { fileURLToPath } from 'url'; +import { expect, it, describe } from 'vitest'; import { scanImports } from '../src/service/analyze'; import formatPath from '../src/utils/formatPath'; @@ -30,7 +30,7 @@ describe('scan import', () => { it('scan with depImports', async () => { const deps = await scanImports( [path.join(__dirname, './fixtures/scan/app.ts')], - { alias, rootDir, depImports: { '@ice/runtime': { name: '@ice/runtime' }, react: { name: 'react' } } } + { alias, rootDir, depImports: { '@ice/runtime': { name: '@ice/runtime' }, react: { name: 'react' } } }, ); expect(deps['@ice/runtime'].name).toEqual('@ice/runtime'); expect(deps['@ice/runtime'].pkgPath).toBeUndefined(); diff --git a/packages/ice/tests/transformImport.test.ts b/packages/ice/tests/transformImport.test.ts index ad57033f5..1d165b149 100644 --- a/packages/ice/tests/transformImport.test.ts +++ b/packages/ice/tests/transformImport.test.ts @@ -1,13 +1,13 @@ -import { afterAll, expect, it } from 'vitest'; import * as path from 'path'; -import fse from 'fs-extra'; import { fileURLToPath } from 'url'; +import { afterAll, expect, it } from 'vitest'; +import fse from 'fs-extra'; +import esbuild from 'esbuild'; +import { createUnplugin } from 'unplugin'; import preBundleCJSDeps from '../src/service/preBundleCJSDeps'; import { scanImports } from '../src/service/analyze'; -import esbuild from 'esbuild'; import transformImport from '../src/esbuild/transformImport'; import aliasPlugin from '../src/esbuild/alias'; -import { createUnplugin } from 'unplugin'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const alias = { '@': path.join(__dirname, './fixtures/scan') }; @@ -22,7 +22,7 @@ it('transform module import', async () => { depsInfo: deps, cacheDir, alias, - taskConfig: { mode: 'production' } + taskConfig: { mode: 'production' }, }); const transformImportPlugin = createUnplugin(() => transformImport(metadata, path.join(outdir, 'server'))).esbuild; await esbuild.build({ diff --git a/packages/jsx-runtime/src/index.ts b/packages/jsx-runtime/src/index.ts index f27cd69b3..50dcabc44 100644 --- a/packages/jsx-runtime/src/index.ts +++ b/packages/jsx-runtime/src/index.ts @@ -26,7 +26,7 @@ function isObject(obj: any): obj is object { } // Support rpx unit. -function hijackElementProps(props: { style?: object } | object): object { +export function hijackElementProps(props: { style?: object } | object): object { if (props && STYLE in props) { const { style } = props; if (isObject(style)) { diff --git a/packages/jsx-runtime/tests/hijackElememt.test.ts b/packages/jsx-runtime/tests/hijackElememt.test.ts new file mode 100644 index 000000000..7fdeff8e4 --- /dev/null +++ b/packages/jsx-runtime/tests/hijackElememt.test.ts @@ -0,0 +1,22 @@ +import { expect, it, describe } from 'vitest'; +import { hijackElementProps } from '../src/'; + +describe('hijack element', () => { + it('hijackElementProps basic', () => { + const props = hijackElementProps({ data: '', number: 1, fontSize: '12rpx' }); + expect(props).toStrictEqual({ + data: '', number: 1, fontSize: '12rpx', + }); + }); + + it('hijackElementProps style', () => { + const props = hijackElementProps({ style: { fontSize: 14, height: '12px', with: '12rpx' } }); + expect(props).toStrictEqual({ + style: { + fontSize: 14, + height: '12px', + with: '1.6vw', + }, + }); + }); +}); \ No newline at end of file diff --git a/packages/plugin-auth/CHANGELOG.md b/packages/plugin-auth/CHANGELOG.md index 0b58a1a09..60cfdf357 100644 --- a/packages/plugin-auth/CHANGELOG.md +++ b/packages/plugin-auth/CHANGELOG.md @@ -1,3 +1,5 @@ # Changelog -## 1.0.0 \ No newline at end of file +## 1.0.0-rc.3 + +- [feat] support initialize auth by app data. \ No newline at end of file diff --git a/packages/plugin-auth/src/runtime/index.tsx b/packages/plugin-auth/src/runtime/index.tsx index b448f24e3..59d0682b5 100644 --- a/packages/plugin-auth/src/runtime/index.tsx +++ b/packages/plugin-auth/src/runtime/index.tsx @@ -5,9 +5,9 @@ import { AuthProvider, useAuth } from './Auth.js'; import type { InjectProps } from './Auth.js'; const runtime: RuntimePlugin = async ({ appContext, useConfig, addProvider, addWrapper }) => { - const { appExport } = appContext; + const { appExport, appData } = appContext; const authConfig: AuthConfig = (typeof appExport.auth === 'function' - ? (await appExport.auth()) : appExport.auth) || {}; + ? (await appExport.auth(appData)) : appExport.auth) || {}; const initialAuth = authConfig.initialAuth || {}; const AuthProviderWrapper: AppProvider = ({ children }) => { const [state, setState] = React.useState<AuthType>(initialAuth); diff --git a/packages/plugin-auth/src/types.ts b/packages/plugin-auth/src/types.ts index 4f0f6a9d8..77e134834 100644 --- a/packages/plugin-auth/src/types.ts +++ b/packages/plugin-auth/src/types.ts @@ -9,7 +9,7 @@ export interface AuthConfig { export type AuthType = Record<string, boolean>; export type ContextType = [AuthType, React.Dispatch<React.SetStateAction<AuthType>>]; -export type Auth = () => Promise<AuthConfig> | AuthConfig; +export type Auth = (data?: any) => Promise<AuthConfig> | AuthConfig; export function defineAuthConfig(fn: Auth) { return fn; diff --git a/packages/plugin-css-assets-local/CHANGELOG.md b/packages/plugin-css-assets-local/CHANGELOG.md new file mode 100644 index 000000000..3ef0834bf --- /dev/null +++ b/packages/plugin-css-assets-local/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 1.0.0 + +- feat: init plugin diff --git a/packages/plugin-css-assets-local/README.md b/packages/plugin-css-assets-local/README.md new file mode 100644 index 000000000..ef0fa24d3 --- /dev/null +++ b/packages/plugin-css-assets-local/README.md @@ -0,0 +1,50 @@ +# @ice/plugin-css-assets-local + +A plugin for localize css assets resource. + +## Install + +```bash +npm i -D @ice/plugin-css-assets-local +``` + +## Usage + +Add plugin to your `ice.config.mts`: + +```ts +// ice.config.mts +import { defineConfig } from '@ice/app'; +import cssAssetsLocal from '@ice/plugin-css-assets-local'; + +export default defineConfig({ + plugins: [ + cssAssetsLocal(), + ], +}); +``` + +After running `npm run build`, you can see the assets resource will be downloaded to the local disk. + +## Options + +### `outputPath` + +The assets resource output path. + +- Type: `string` +- Default: `assets` + +### `relativeCssPath` + +The asset paths relative to the css file path. + +- Type: `string` +- Default: `../` + +### `enableInDev` + +Whether enable the plugin in dev or not. + +- Type: `boolean` +- Default: `false` \ No newline at end of file diff --git a/packages/plugin-css-assets-local/package.json b/packages/plugin-css-assets-local/package.json new file mode 100644 index 000000000..a268f5a0d --- /dev/null +++ b/packages/plugin-css-assets-local/package.json @@ -0,0 +1,34 @@ +{ + "name": "@ice/plugin-css-assets-local", + "version": "1.0.0", + "license": "MIT", + "repository": { + "type": "http", + "url": "https://github.com/ice-lab/ice-next/tree/master/packages/plugin-css-assets-local" + }, + "type": "module", + "files": [ + "esm", + "!esm/**/*.map" + ], + "main": "./esm/index.js", + "types": "./esm/index.d.ts", + "exports": { + ".": { + "types": "./esm/index.d.ts", + "import": "./esm/index.js", + "default": "./esm/index.js" + } + }, + "dependencies": { + "extract-css-assets-webpack-plugin": "^0.2.10", + "consola": "^2.15.3" + }, + "devDependencies": { + "@ice/types": "^1.0.0" + }, + "scripts": { + "watch": "tsc -w", + "build": "tsc" + } +} \ No newline at end of file diff --git a/packages/plugin-css-assets-local/src/index.ts b/packages/plugin-css-assets-local/src/index.ts new file mode 100644 index 000000000..de01b10a8 --- /dev/null +++ b/packages/plugin-css-assets-local/src/index.ts @@ -0,0 +1,52 @@ +import type { Plugin } from '@ice/types'; +// @ts-expect-error cjs module error +import ExtractCssAssetsWebpackPlugin from 'extract-css-assets-webpack-plugin'; +import consola from 'consola'; + +interface PluginOptions { + /** + * The assets path. + * + * Default value: `assets` + */ + outputPath?: string; + /** + * The asset paths relative to the css file path. + * + * Default value: `../` + */ + relativeCssPath?: string; + /** + * + * Whether enable the plugin in dev or not. + * + * Default value: `false` + */ + enableInDev?: boolean; +} + +const plugin: Plugin<PluginOptions> = (options = {}) => ({ + name: '@ice/plugin-css-assets-local', + setup: ({ onGetConfig, context: { command } }) => { + const { + outputPath = 'assets', + relativeCssPath = '../', + enableInDev = false, + } = options; + // it is increase dev build time by set default activeCommands ['build'] + const activeCommands = enableInDev ? ['start', 'build'] : ['build']; + if (activeCommands.indexOf(command) > -1) { + consola.info('\n[plugin-css-assets-local] Automatically download network resources, please wait patiently.'); + onGetConfig((config) => { + config.plugins ??= []; + config.plugins.push(new ExtractCssAssetsWebpackPlugin({ + outputPath, + relativeCssPath, + forceLocal: true, + })); + }); + } + }, +}); + +export default plugin; diff --git a/packages/plugin-css-assets-local/tsconfig.json b/packages/plugin-css-assets-local/tsconfig.json new file mode 100644 index 000000000..972f3542f --- /dev/null +++ b/packages/plugin-css-assets-local/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "baseUrl": "./", + "rootDir": "src", + "outDir": "esm", + "jsx": "react" + }, + "include": ["src"] +} \ No newline at end of file diff --git a/packages/plugin-jsx-plus/CHANGELOG.md b/packages/plugin-jsx-plus/CHANGELOG.md new file mode 100644 index 000000000..cad780cd5 --- /dev/null +++ b/packages/plugin-jsx-plus/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 1.0.0 + +Initial implementation. diff --git a/packages/plugin-jsx-plus/README.md b/packages/plugin-jsx-plus/README.md new file mode 100644 index 000000000..35fe3483a --- /dev/null +++ b/packages/plugin-jsx-plus/README.md @@ -0,0 +1,35 @@ +# `plugin-jsx-plus` + +This plugin adds support for JSX+ syntax to the icejs 3. + +## Definition of JSX Plus +https://github.com/jsx-plus/jsx-plus + +## Usage + +```js +import { defineConfig } from '@ice/app'; +import jsxplus from '@ice/plugin-jsx-plus'; + +export default defineConfig({ + plugins: [ + jsxplus({ + // options + }), + ], +}); +``` + +## Options + +- `include`: `(string | RegExp)[]` + - Files to be included. + - Default: the project `src` directory. +- `exclude`: `(string | RegExp)[]` + - Files to be excluded. + - Default: `[]` +- `extensions`: `string[]` + - File extensions to be processed. + - Default: `['.jsx', '.tsx']` + +> If `include` and `exclude` are both set, `exclude` will be priority executed. diff --git a/packages/plugin-jsx-plus/package.json b/packages/plugin-jsx-plus/package.json new file mode 100644 index 000000000..4ad691b4a --- /dev/null +++ b/packages/plugin-jsx-plus/package.json @@ -0,0 +1,53 @@ +{ + "name": "@ice/plugin-jsx-plus", + "version": "1.0.0", + "description": "", + "license": "MIT", + "type": "module", + "exports": { + ".": { + "types": "./esm/index.d.ts", + "import": "./esm/index.js", + "default": "./esm/index.js" + }, + "./types": { + "types": "./esm/types.d.ts", + "import": "./esm/types.js", + "default": "./esm/types.js" + }, + "./esm/types": { + "types": "./esm/types.d.ts", + "import": "./esm/types.js", + "default": "./esm/types.js" + } + }, + "main": "./esm/index.js", + "types": "./esm/index.d.ts", + "files": [ + "esm", + "!esm/**/*.map" + ], + "devDependencies": { + "@ice/types": "^1.0.0", + "@types/react": "^18.0.20", + "@types/react-dom": "^18.0.6" + }, + "repository": { + "type": "http", + "url": "https://github.com/ice-lab/ice-next/tree/master/packages/plugin-jsx-plus" + }, + "scripts": { + "watch": "tsc -w", + "build": "tsc" + }, + "dependencies": { + "@babel/core": "^7.19.1", + "babel-plugin-transform-jsx-class": "^0.1.3", + "babel-plugin-transform-jsx-condition": "^0.1.2", + "babel-plugin-transform-jsx-fragment": "^0.1.4", + "babel-plugin-transform-jsx-list": "^0.1.2", + "babel-plugin-transform-jsx-memo": "^0.1.4", + "babel-plugin-transform-jsx-slot": "^0.1.2", + "babel-runtime-jsx-plus": "^0.1.5" + } +} diff --git a/packages/plugin-jsx-plus/src/index.ts b/packages/plugin-jsx-plus/src/index.ts new file mode 100644 index 000000000..77317a4c7 --- /dev/null +++ b/packages/plugin-jsx-plus/src/index.ts @@ -0,0 +1,139 @@ +import path from 'path'; +import { createRequire } from 'module'; +import type { Plugin } from '@ice/types'; +import { transformSync } from '@babel/core'; + +const require = createRequire(import.meta.url); +const runtimePackage = 'babel-runtime-jsx-plus'; +const runtimePackagePath = require.resolve(runtimePackage); + +const babelPlugins = [ + 'babel-plugin-transform-jsx-list', + 'babel-plugin-transform-jsx-condition', + 'babel-plugin-transform-jsx-memo', + 'babel-plugin-transform-jsx-slot', + ['babel-plugin-transform-jsx-fragment', { moduleName: 'react' }], + 'babel-plugin-transform-jsx-class', +]; + +const babelTransformOptions = { + babelrc: false, + configFile: false, + parserOpts: { + sourceType: 'module', + allowAwaitOutsideFunction: true, + // ts syntax had already been transformed by swc plugin. + plugins: [ + 'jsx', + 'importMeta', + 'topLevelAwait', + 'classProperties', + 'classPrivateMethods', + ], + generatorOpts: { + decoratorsBeforeExport: true, + }, + }, + plugins: [], +}; + +babelPlugins.forEach((plugin) => { + if (typeof plugin === 'string') { + babelTransformOptions.plugins.push(require.resolve(plugin)); + } else if (Array.isArray(plugin)) { + const pluginName = plugin[0] as string; + const pluginOption = plugin[1]; + babelTransformOptions.plugins.push([require.resolve(pluginName), pluginOption]); + } +}); + +export function idFilter(options: JSXPlusOptions, id: string): boolean { + const extFilter = (id) => options.extensions.some((ext) => id.endsWith(ext)); + + if (options.exclude) { + for (const pattern of options.exclude) { + if (typeof pattern === 'string') { + if (id.indexOf(pattern) > -1) { + return false; + } + } else if (pattern instanceof RegExp && pattern.test(id)) { + return false; + } + } + } + + if (options.include) { + for (const pattern of options.include) { + if (typeof pattern === 'string') { + if (id.indexOf(pattern) > -1) { + return extFilter(id); + } + } else if (pattern instanceof RegExp && pattern.test(id)) { + return extFilter(id); + } + } + } + + return false; +} + +export interface JSXPlusOptions { + include?: (string | RegExp)[]; + exclude?: (string | RegExp)[]; + extensions?: string[]; +} + +const plugin: Plugin<JSXPlusOptions> = (options: JSXPlusOptions = {}) => ({ + name: '@ice/plugin-jsx-plus', + setup: ({ onGetConfig, context }) => { + // Default include all files in `src`. + if (!options.include) { + const sourceDir = path.join(context.rootDir, 'src'); + options.include = [sourceDir]; + } + + // Default include all files with `.tsx` and `.jsx` extensions. + if (!options.extensions) { + options.extensions = ['.tsx', '.jsx']; + } + + function jsxPlusTransformer(source, id) { + if (idFilter(options, id)) { + try { + const options = Object.assign({ + filename: id, + sourceFileName: id, + }, babelTransformOptions); + if (/\.tsx?$/.test(id)) { + // When routes file is a typescript file, add ts parser plugins. + options.parserOpts.plugins.push('typescript'); + options.parserOpts.plugins.push('decorators-legacy'); // allowing decorators by default + } + + const { code, map } = transformSync(source, options); + return { code, map }; + } catch (compileError) { + console.error(compileError); + return { code: source, map: null }; + } + } + return { code: source, map: null }; + } + + onGetConfig((config) => { + // Add runtime alias. + if (!config.alias) { + config.alias = {}; + } + config.alias[runtimePackage] = runtimePackagePath; + + // Apply babel jsx plus transformer. + if (!config.transforms) { + config.transforms = []; + } + config.transforms.push(jsxPlusTransformer); + }); + }, +}); + +export default plugin; diff --git a/packages/plugin-jsx-plus/src/types.ts b/packages/plugin-jsx-plus/src/types.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/plugin-jsx-plus/tests/jsxplus.test.ts b/packages/plugin-jsx-plus/tests/jsxplus.test.ts new file mode 100644 index 000000000..57451f5ae --- /dev/null +++ b/packages/plugin-jsx-plus/tests/jsxplus.test.ts @@ -0,0 +1,85 @@ +import { expect, it, describe } from 'vitest'; +import { default as jsxPlus, idFilter } from '../src'; + +describe('JSX Plus Plugin', () => { + describe('Id filter', () => { + it('default', () => { + expect(idFilter({}, '/bar/a.tsx')).toBeFalsy(); + }); + + it('include', () => { + const options = { + include: [/bar/, 'foo'], + extensions: ['.jsx', '.tsx'], + }; + + expect(idFilter(options, '/bar/a.tsx')).toBeTruthy(); + expect(idFilter(options, '/foo/a.tsx')).toBeTruthy(); + }); + + it('exclude', () => { + expect(idFilter({ + exclude: ['foo'], + include: [/bar/], + extensions: ['.jsx', '.tsx'], + }, '/foo/bar/a.tsx')).toBeFalsy(); + + expect(idFilter({ + exclude: [/foo/], + include: [/bar/], + extensions: ['.jsx', '.tsx'], + }, '/foo/bar/a.tsx')).toBeFalsy(); + }); + + it('extensions', () => { + const options = { + include: [/bar/], + extensions: ['.jsx', '.tsx', '.custom.ext'], + }; + expect(idFilter(options, '/foo/bar/a.tsx.custom.ext')).toBeTruthy(); + }); + }); + + describe('Plugin', () => { + it('default', () => { + const plugin = jsxPlus({ + include: ['foo'], + }); + // @ts-ignore + expect(plugin.name).toBe('@ice/plugin-jsx-plus'); + const fakeConfig = {}; + function onGetConfig(fn) { + fn(fakeConfig); + } + const context = { + rootDir: '/foo/bar', + }; + // @ts-ignore + plugin.setup({ onGetConfig, context }); + expect(fakeConfig['alias']['babel-runtime-jsx-plus']).toBeDefined(); + expect(Array.isArray(fakeConfig['transforms'])).toBeTruthy(); + expect(fakeConfig['transforms'].length).toBe(1); + }); + + it('transformer', () => { + const plugin = jsxPlus({ + include: ['foo'], + }); + const fakeConfig = {}; + function onGetConfig(fn) { + fn(fakeConfig); + } + const context = { + rootDir: '/foo/bar', + }; + // @ts-ignore + plugin.setup({ onGetConfig, context }); + + const transformer = fakeConfig['transforms'][0]; + const ret = transformer('<div x-if={false} />', '/foo/bar/a.tsx'); + expect(ret.code).toBe(`import { createCondition as __create_condition__ } from "babel-runtime-jsx-plus"; + +__create_condition__([[() => false, () => <div />]]);`); + }); + }); +}); diff --git a/packages/plugin-jsx-plus/tsconfig.json b/packages/plugin-jsx-plus/tsconfig.json new file mode 100644 index 000000000..972f3542f --- /dev/null +++ b/packages/plugin-jsx-plus/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "baseUrl": "./", + "rootDir": "src", + "outDir": "esm", + "jsx": "react" + }, + "include": ["src"] +} \ No newline at end of file diff --git a/packages/plugin-pha/package.json b/packages/plugin-pha/package.json index e20d0e313..380832d8b 100644 --- a/packages/plugin-pha/package.json +++ b/packages/plugin-pha/package.json @@ -23,7 +23,7 @@ }, "devDependencies": { "@ice/types": "^1.0.0", - "esbuild": "^0.14.23", + "esbuild": "^0.14.51", "webpack": "^5.73.0", "webpack-dev-server": "^4.9.2" }, diff --git a/packages/plugin-pha/src/index.ts b/packages/plugin-pha/src/index.ts index 49834d2aa..d674cf683 100644 --- a/packages/plugin-pha/src/index.ts +++ b/packages/plugin-pha/src/index.ts @@ -58,7 +58,6 @@ const plugin: Plugin<PluginOptions> = (options) => ({ format: 'esm', outfile, minify, - inject: [], }); return `${outfile}`; }; diff --git a/packages/plugin-pha/tests/fixtures/if.ts b/packages/plugin-pha/tests/fixtures/if.ts index 431b4b862..a9853fefd 100644 --- a/packages/plugin-pha/tests/fixtures/if.ts +++ b/packages/plugin-pha/tests/fixtures/if.ts @@ -1,4 +1,4 @@ -var a = 1; +let a = 1; if (true) { a = 2; } diff --git a/packages/plugin-pha/tests/fixtures/vars.ts b/packages/plugin-pha/tests/fixtures/vars.ts index bfb814f71..22bbd3b44 100644 --- a/packages/plugin-pha/tests/fixtures/vars.ts +++ b/packages/plugin-pha/tests/fixtures/vars.ts @@ -4,10 +4,10 @@ import c from 'c'; import d from 'd'; const [e, f, ...rest] = a; -const {h, j} = b; +const { h, j } = b; const [x, ...m] = c; const zz = 'x'; -const {k, l, ...s} = d; +const { k, l, ...s } = d; export function getConfig() { return { diff --git a/packages/plugin-pha/tests/fixtures/while.ts b/packages/plugin-pha/tests/fixtures/while.ts index abc8e1707..992a78675 100644 --- a/packages/plugin-pha/tests/fixtures/while.ts +++ b/packages/plugin-pha/tests/fixtures/while.ts @@ -1,5 +1,5 @@ -var j = 2; -var i = 2; +let j = 2; +let i = 2; while (j < 3) { j++; } diff --git a/packages/plugin-pha/tests/manifestHelper.test.ts b/packages/plugin-pha/tests/manifestHelper.test.ts index 458337861..9891813a6 100644 --- a/packages/plugin-pha/tests/manifestHelper.test.ts +++ b/packages/plugin-pha/tests/manifestHelper.test.ts @@ -49,12 +49,12 @@ describe('rewrite app worker url', () => { appWorker: { url: 'pha-worker.js', source: 'test', - } + }, })).toMatchObject({ appWorker: { url: 'app-worker.js', source: 'test', - } + }, }); }); @@ -62,7 +62,7 @@ describe('rewrite app worker url', () => { expect(rewriteAppWorker({})).toMatchObject({ appWorker: { url: 'app-worker.js', - } + }, }); }); }); @@ -78,11 +78,11 @@ describe('transform config keys', () => { { pageHeader: { includedSafeArea: true, - } - } - ] + }, + }, + ], }, - { isRoot: true } + { isRoot: true }, ); expect(manifestJSON.name).toStrictEqual('name'); expect(manifestJSON.offline_resources).toStrictEqual(['//g.alicdn.com/.*']); @@ -115,7 +115,7 @@ describe('transform config keys', () => { }, ], }, - { isRoot: true } + { isRoot: true }, ); expect(manifestJSON?.data_prefetch?.length).toBe(1); expect(manifestJSON?.data_prefetch![0].data).toMatchObject({ @@ -154,11 +154,11 @@ describe('transform config keys', () => { text: 'text-name', icon: '', activeIcon: '', - } + }, ], }, }, - { isRoot: true } + { isRoot: true }, ); expect(manifestJSON.tab_bar).toBeTruthy(); @@ -189,7 +189,7 @@ describe('transform config keys', () => { }, ], }, - { isRoot: true } + { isRoot: true }, ); expect(manifestJSON?.pages?.length).toBe(2); expect(manifestJSON?.pages![0].data_prefetch).toMatchObject([ @@ -209,7 +209,7 @@ describe('transform config keys', () => { { a: 123, }, - { isRoot: false } + { isRoot: false }, ); expect(manifestJSON).toMatchObject({ a: 123 }); @@ -220,7 +220,7 @@ describe('transform config keys', () => { { a: 123, }, - { isRoot: true } + { isRoot: true }, ); expect(manifestJSON).toMatchObject({}); @@ -233,7 +233,7 @@ describe('transform config keys', () => { 'U-Tag': '${storage.uTag}', }, }, - { isRoot: false } + { isRoot: false }, ); expect(manifestJSON).toMatchObject({ request_headers: { 'U-Tag': '${storage.uTag}' } }); }); @@ -293,7 +293,7 @@ describe('parse manifest', async () => { 'home', 'about', 'app/nest', - '404' + '404', ], }; const manifest = await parseManifest(phaManifest, { @@ -403,7 +403,7 @@ describe('parse manifest', async () => { } catch (err) { expect(true).toBe(true); } - }) + }); it('url failed with new URL', async () => { const phaManifest = { @@ -417,7 +417,7 @@ describe('parse manifest', async () => { }); expect(manifest.tab_bar?.url).toBe('{{xxx}}/tabBar'); expect(manifest.tab_bar?.name).toBe('{{xxx}}'); - }) + }); it('should not inject html when tabHeader & tabBar have url field', async () => { const phaManifest = { @@ -426,14 +426,14 @@ describe('parse manifest', async () => { pageHeader: { source: 'pages/Header', url: 'https://m.taobao.com', - } - } + }, + }, ], tabBar: { custom: true, source: 'pages/CustomTabBar', items: ['home', 'frame1'], - } + }, }; const manifest = await parseManifest(phaManifest, { @@ -477,8 +477,8 @@ describe('get multiple manifest', async () => { 'app/nest', { url: 'https://m.taobao.com', - } - ] + }, + ], }, 'about', ], diff --git a/packages/plugin-rax-compat/package.json b/packages/plugin-rax-compat/package.json index 0bbc0d14d..669dadcf9 100644 --- a/packages/plugin-rax-compat/package.json +++ b/packages/plugin-rax-compat/package.json @@ -17,7 +17,12 @@ "!esm/**/*.map" ], "dependencies": { + "@babel/core": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.18.9", + "@ice/bundles": "^0.1.0", + "babel-plugin-transform-jsx-stylesheet": "1.0.6", "consola": "^2.15.3", + "css": "^2.2.1", "lodash.merge": "^4.6.2", "rax-compat": "^0.1.0", "stylesheet-loader": "^0.9.1" diff --git a/packages/plugin-rax-compat/src/index.ts b/packages/plugin-rax-compat/src/index.ts index bd7c6e4ac..067690aee 100644 --- a/packages/plugin-rax-compat/src/index.ts +++ b/packages/plugin-rax-compat/src/index.ts @@ -1,11 +1,17 @@ +import fs from 'fs'; +import path from 'path'; import { createRequire } from 'module'; import type { Plugin } from '@ice/types'; import type { RuleSetRule } from 'webpack'; import consola from 'consola'; import merge from 'lodash.merge'; +import { transformSync } from '@babel/core'; +import styleSheetLoader from './transform-styles.js'; const require = createRequire(import.meta.url); +const jsRegex = /\.(jsx?|tsx?|mjs)$/; + const alias = { // Add rax compat packages. rax: require.resolve('rax-compat'), @@ -29,6 +35,22 @@ const ruleSetStylesheet = { ], }; +const ruleSetStylesheetForLess = { + test: /\.less$/i, + use: [ + { + loader: require.resolve('stylesheet-loader'), + options: {}, + }, + { + loader: require.resolve('@ice/bundles/compiled/less-loader'), + options: { + lessOptions: { javascriptEnabled: true }, + }, + }, + ], +}; + let warnOnce = false; export interface CompatRaxOptions { @@ -37,7 +59,9 @@ export interface CompatRaxOptions { const plugin: Plugin<CompatRaxOptions> = (options = {}) => ({ name: '@ice/plugin-rax-compat', - setup: ({ onGetConfig }) => { + setup: ({ onGetConfig, context }) => { + const { userConfig } = context; + onGetConfig((config) => { // Reset jsc.transform.react.runtime to classic. config.swcOptions = merge(config.swcOptions || {}, { @@ -53,36 +77,186 @@ const plugin: Plugin<CompatRaxOptions> = (options = {}) => ({ }, }, }); + + if (!config.server) { + config.server = {}; + } + const originalOptions = config.server.buildOptions; + config.server.buildOptions = (options) => ({ + ...(originalOptions ? originalOptions(options) : options), + jsx: 'transform', + jsxFactory: 'createElement', + jsxFragment: 'Fragment', + }); + Object.assign(config.alias, alias); + if (options.inlineStyle) { if (!warnOnce) { consola.warn('Enabling inline style is not recommended.\n It is recommended to use CSS modules (as default). Only allow old projects to migrate and use.'); warnOnce = true; } + + if (userConfig.ssr || userConfig.ssg) { + config.server.buildOptions = applyStylesheetLoaderForServer(config.server.buildOptions); + } + config.configureWebpack ??= []; - config.configureWebpack.unshift((config) => { - const { rules } = config.module || {}; - if (Array.isArray(rules)) { - for (let i = 0, l = rules.length; i < l; i++) { - const rule: RuleSetRule | any = rules[i]; - // Find the css rule, that default to CSS Modules. - if (rule.test && rule.test.source.indexOf('.css') > -1) { - rule.test = /\.module\.css$/i; - rules[i] = { - test: /\.css$/i, - oneOf: [ - rule, - ruleSetStylesheet, - ], - }; - } - } - } - return config; - }); + config.configureWebpack.unshift(styleSheetLoaderForClient); + config.transforms = [ + ...(config.transforms || []), + getClassNameToStyleTransformer(userConfig.syntaxFeatures || {}), + ]; } }); }, }); +/** + * Transform StyleSheet selector to style in JSX Elements. + * <div className="header" /> => <div style={styleSheet.header} /> + * @param config + */ +function getClassNameToStyleTransformer(syntaxFeatures) { + const { exportDefaultFrom } = syntaxFeatures; + + const plugins: (string | Array<string | object>)[] = [ + [require.resolve('babel-plugin-transform-jsx-stylesheet'), { + retainClassName: true, + }], + ]; + + if (exportDefaultFrom) { + plugins.push(require.resolve('@babel/plugin-proposal-export-default-from')); + } + + return async (sourceCode, id) => { + // js file transform with rax-platform-loader and babel-plugin-transform-jsx-stylesheet + if (id.includes('node_modules') && id.includes('react')) { + return; + } + + if (jsRegex.test(id)) { + const parserPlugins = [ + 'jsx', + 'importMeta', + 'topLevelAwait', + 'classProperties', + 'classPrivateMethods', + ]; + + if (/\.tsx?$/.test(id)) { + // when routes file is a typescript file, + // add ts parser plugins + parserPlugins.push('typescript'); + parserPlugins.push('decorators-legacy'); // allowing decorators by default + } + + const { code, map } = transformSync(sourceCode, { + babelrc: false, + configFile: false, + filename: id, + parserOpts: { + sourceType: 'module', + allowAwaitOutsideFunction: true, + // ts syntax had already been transformed by swc plugin. + plugins: parserPlugins, + }, + generatorOpts: { + decoratorsBeforeExport: true, + }, + sourceFileName: id, + plugins, + }); + + return { + code, + map, + }; + } + }; +} + +/** + * StyleSheet Loader for CSR. + * Transform css files to inline style by webpack loader. + */ +const styleSheetLoaderForClient = (config) => { + const { rules } = config.module || {}; + if (Array.isArray(rules)) { + for (let i = 0, l = rules.length; i < l; i++) { + const rule: RuleSetRule | any = rules[i]; + // Find the css rule, that default to CSS Modules. + if (rule.test && rule.test instanceof RegExp && rule.test.source.indexOf('.css') > -1) { + rules[i] = { + test: /\.css$/i, + oneOf: [ + ruleSetStylesheet, + ], + }; + } + + // Find and replace the less rule + if (rule.test && rule.test instanceof RegExp && rule.test.source.indexOf('.less') > -1) { + rules[i] = { + test: /\.less$/i, + oneOf: [ + ruleSetStylesheetForLess, + ], + }; + } + } + } + return config; +}; + +/** + * StyleSheet Loader for Server. + * @param config + */ +function applyStylesheetLoaderForServer(preBuildOptions) { + return (buildOptions) => { + const currentOptions = preBuildOptions?.(buildOptions) || buildOptions; + + // Remove esbuild-empty-css while use inline style. + currentOptions.plugins = currentOptions.plugins?.filter(({ name }) => name !== 'esbuild-empty-css'); + const cssModuleIndex = currentOptions.plugins?.findIndex(({ name }) => name === 'esbuild-css-modules'); + + // Add custom transform for server compile. + currentOptions.plugins?.splice(cssModuleIndex as number, 0, inlineStylePlugin()); + + currentOptions.treeShaking = true; + return currentOptions; + }; +} + +/** + * Transform css files to inline style by esbuild. + * @returns + */ +const inlineStylePlugin = () => { + return { + name: 'esbuild-inline-style', + setup: (build) => { + build.onResolve({ filter: /\.(css|sass|scss|less)$/ }, (args) => { + const absolutePath = path.resolve(args.resolveDir, args.path); + return { + path: absolutePath, + namespace: 'css-content', + }; + }); + + build.onLoad({ filter: /.*/, namespace: 'css-content' }, async (args) => { + const cssContent = fs.readFileSync(args.path, 'utf8'); + const content = await styleSheetLoader(cssContent, args.path.includes('.less') ? 'less' : 'css'); + + return { + contents: content, + loader: 'js', + }; + }); + }, + }; +}; + export default plugin; diff --git a/packages/plugin-rax-compat/src/transform-styles.ts b/packages/plugin-rax-compat/src/transform-styles.ts new file mode 100644 index 000000000..86372e336 --- /dev/null +++ b/packages/plugin-rax-compat/src/transform-styles.ts @@ -0,0 +1,203 @@ +import { createRequire } from 'module'; +import css from 'css'; +import transformerModule from 'stylesheet-loader/lib/transformer.js'; +import globalCSSVariable from 'stylesheet-loader/lib/globalCSSVariable.js'; +import { getErrorMessages, getWarnMessages, resetMessage } from 'stylesheet-loader/lib/promptMessage.js'; +import { isPrefersColorScheme, processPrefersColorScheme } from 'stylesheet-loader/lib/processPrefersColorScheme.js'; +import { less, postcss } from '@ice/bundles'; + +const require = createRequire(import.meta.url); + +const RULE = 'rule'; +const FONT_FACE_RULE = 'font-face'; +const MEDIA_RULE = 'media'; +const QUOTES_REG = /['|"]/g; +// example "color: var(--name);" search string "var(" and ")" +const VAR_KEY_VAL_REG = /"(.*?)"\s*:\s*"var\((.*)\)"/g; +const GLOBAL_CSS_VAR = '__CSSVariables'; +const CSS_VAR_NAME = ':root'; + +// @ts-ignore +const transformer = transformerModule.default; + +async function styleSheetLoader(source, type = 'css') { + let cssContent = source; + if (type === 'less') { + // compact for @import "~bootstrap/less/bootstrap"; + cssContent = cssContent.replace(/@import "~/g, '@import "'); + cssContent = (await less.render(cssContent)).css; + } + + const newContent = await postcss([require('@ice/bundles/compiled/postcss-plugin-rpx2vw/index.js')({ unitPrecision: 4 })]).process(cssContent).css; + const { stylesheet } = css.parse(newContent); + + if (stylesheet.parsingErrors.length) { + throw new Error('StyleSheet Parsing Error occured.'); + } + + // getOptions can return null if no query passed. + const parsedQuery = {}; + + const parsedData = parse(parsedQuery, stylesheet); + + return genStyleContent(parsedData, parsedQuery); +} + +// export for test case +const parse = (parsedQuery, stylesheet) => { + const styles = {}; + const fontFaceRules = []; + const mediaRules = []; + const { transformDescendantCombinator } = parsedQuery; + + stylesheet.rules.forEach((rule) => { + let style = {}; + + // normal rule + if (rule.type === RULE) { + style = transformer.convert(rule, parsedQuery); + + rule.selectors.forEach((selector) => { + let sanitizedSelector = transformer.sanitizeSelector( + selector, transformDescendantCombinator, rule.position, parsedQuery.log, + ); + if (sanitizedSelector) { + // handle pseudo class + const pseudoIndex = sanitizedSelector.indexOf(':'); + if (pseudoIndex > -1 && !parsedQuery.theme) { + const pseudoStyle = {}; + const pseudoName = selector.slice(pseudoIndex + 1); + sanitizedSelector = sanitizedSelector.slice(0, pseudoIndex); + + Object.keys(style).forEach((prop) => { + pseudoStyle[prop + pseudoName] = style[prop]; + }); + + style = pseudoStyle; + } + // eslint-disable-next-line eqeqeq + if (sanitizedSelector == CSS_VAR_NAME && parsedQuery.theme) { + sanitizedSelector = GLOBAL_CSS_VAR; + } + + styles[sanitizedSelector] = Object.assign(styles[sanitizedSelector] || {}, style); + } + }); + } + + // font face rule + if (rule.type === FONT_FACE_RULE) { + const font = {}; + rule.declarations.forEach((declaration) => { + font[declaration.property] = declaration.value; + }); + fontFaceRules.push(font); + } + + // media rule + if (rule.type === MEDIA_RULE) { + mediaRules.push({ + key: rule.media, + data: parse(parsedQuery, rule).styles, + }); + } + }); + + return { + styles, + fontFaceRules, + mediaRules, + }; +}; + +const genStyleContent = (parsedData, parsedQuery) => { + const { fontFaceRules, mediaRules } = parsedData; + const styles = processPrefersColorScheme(mediaRules, parsedData.styles, parsedQuery.taskName); + + const fontFaceContent = getFontFaceContent(fontFaceRules); + const mediaContent = getMediaContent(mediaRules, parsedQuery); + const warnMessageOutput = parsedQuery.log ? getWarnMessageOutput() : ''; + resetMessage(); + return `${parsedQuery.theme ? globalCSSVariable({ styles, globalCSSVarName: GLOBAL_CSS_VAR }) : ''} + var _styles = ${stringifyData(styles, parsedQuery.theme)}; +${fontFaceContent} +${mediaContent} +${warnMessageOutput} + module.exports = _styles; + `; +}; + +const getWarnMessageOutput = () => { + const errorMessages = getErrorMessages(); + const warnMessages = getWarnMessages(); + let output = ''; + + if (errorMessages) { + output += ` + if (process.env.NODE_ENV !== 'production') { + console.error('${errorMessages}'); + } + `; + } + if (warnMessages) { + output += ` + if (process.env.NODE_ENV !== 'production') { + console.warn('${warnMessages}'); + } + `; + } + + return output; +}; + +const getMediaContent = (mediaRules, parsedQuery) => { + let content = ''; + + mediaRules.forEach((rule) => { + // Weex no need to process prefers-color-scheme media + if (parsedQuery.taskName !== 'weex' || !isPrefersColorScheme(rule.key)) { + content += ` + if (window.matchMedia && window.matchMedia('${rule.key}').matches) { + var ruleData = ${stringifyData(rule.data)}; + for(var key in ruleData) { + _styles[key] = Object.assign(_styles[key] || {}, ruleData[key]); + } + } + `; + } + }); + + return content; +}; + +// export for test case +const getFontFaceContent = (rules) => { + let content = ''; + + if (rules.length > 0) { + content += ` + if (typeof FontFace === 'function') { + `; + } + + rules.forEach((rule, index) => { + content += ` + var fontFace${index} = new FontFace('${rule['font-family'].replace(QUOTES_REG, '')}', '${rule.src.replace(QUOTES_REG, '"')}'); + document.fonts.add(fontFace${index}); + `; + }); + + if (rules.length > 0) { + content += ` + } + `; + } + return content; +}; + +const stringifyData = (data, theme?: string) => { + const str = JSON.stringify(data, undefined, ' '); + return theme ? str.replace(VAR_KEY_VAL_REG, 'get $1(){return __getValue("$2")}') : str; +}; + +export default styleSheetLoader; \ No newline at end of file diff --git a/packages/plugin-request/CHANGELOG.md b/packages/plugin-request/CHANGELOG.md new file mode 100644 index 000000000..fbc07028e --- /dev/null +++ b/packages/plugin-request/CHANGELOG.md @@ -0,0 +1,5 @@ +# CHANGELOG + +## 1.0.0 + +- The initial version of the plugin. diff --git a/packages/plugin-request/README.md b/packages/plugin-request/README.md new file mode 100644 index 000000000..47af38ca8 --- /dev/null +++ b/packages/plugin-request/README.md @@ -0,0 +1,66 @@ +# ICE Request Plugin + +## Usage + +Install from npm. + +```bash +$ npm i @ice/plugin-request -S +``` + +Add plugin. + +```js title="ice.config.mts" +import { defineConfig } from '@ice/app'; +import request from '@ice/plugin-request'; + +export default defineConfig({ + plugins: [ + request(), + ], +}); +``` + +## API + +### request + +```js title="service.ts" +import { request } from 'ice'; + +export async function getUser(id) { + return await request(`/api/user/${id}`); +} +``` + +### useRequest + +```js title="home.tsx" +import { useEffect } from 'react'; +import { useRequest } from 'ice'; + +export default function Home() { + const { + data, + error, + loading, + request + } = useRequest(service.getUser); + + useEffect(() => { + request(); + }, []); + + if (error) { + return <div>failed to load</div>; + } + if (!data || loading) { + return <div>loading...</div>; + } + return ( + <h2 className={styles.title}> + Name: {data.name} Age: {data.age} + </h2> + ); +} +``` diff --git a/packages/plugin-request/package.json b/packages/plugin-request/package.json new file mode 100644 index 000000000..759810465 --- /dev/null +++ b/packages/plugin-request/package.json @@ -0,0 +1,72 @@ +{ + "name": "@ice/plugin-request", + "version": "1.0.0", + "description": "Request plugin for ice.", + "license": "MIT", + "type": "module", + "exports": { + ".": { + "types": "./esm/index.d.ts", + "import": "./esm/index.js", + "default": "./esm/index.js" + }, + "./runtime": { + "types": "./esm/runtime.d.ts", + "import": "./esm/runtime.js", + "default": "./esm/runtime.js" + }, + "./hooks": { + "types": "./esm/hooks.d.ts", + "import": "./esm/hooks.js", + "default": "./esm/hooks.js" + }, + "./request": { + "types": "./esm/request.d.ts", + "import": "./esm/request.js", + "default": "./esm/request.js" + }, + "./types": { + "types": "./esm/types.d.ts", + "import": "./esm/types.js", + "default": "./esm/types.js" + }, + "./esm/types": { + "types": "./esm/types.d.ts", + "import": "./esm/types.js", + "default": "./esm/types.js" + }, + "./esm/runtime": { + "types": "./esm/runtime.d.ts", + "import": "./esm/runtime.js", + "default": "./esm/runtime.js" + } + }, + "main": "./esm/index.js", + "types": "./esm/index.d.ts", + "files": [ + "esm", + "!esm/**/*.map" + ], + "dependencies": { + "ahooks": "^3.0.0", + "axios": "^0.27.2" + }, + "devDependencies": { + "@ice/types": "^1.0.0", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "regenerator-runtime": "^0.13.9" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "repository": { + "type": "http", + "url": "https://github.com/ice-lab/ice-next/tree/master/packages/plugin-request" + }, + "scripts": { + "watch": "tsc -w", + "build": "tsc" + } +} diff --git a/packages/plugin-request/src/hooks.ts b/packages/plugin-request/src/hooks.ts new file mode 100644 index 000000000..3bc2f77aa --- /dev/null +++ b/packages/plugin-request/src/hooks.ts @@ -0,0 +1,42 @@ +import { useRequest as useAhooksRequest } from 'ahooks'; +import type { Options, Result, Service, Plugin } from 'ahooks/lib/useRequest/src/types'; +import type { AxiosRequestConfig } from 'axios'; +import request from './request.js'; + +interface RequestResult<R, P extends any[]> extends Result<R, P> { + request: (...args: P) => Promise<R>; +} + +function useRequest<TData, TParams extends any[]>( + service: AxiosRequestConfig | Service<TData, TParams>, + options?: Options<TData, TParams>, + plugins?: Plugin<TData, TParams>[]) { + let s: Service<TData, TParams>; + if (isFunction(service)) { + s = service as Service<TData, TParams>; + } else { + const options = service as AxiosRequestConfig; + s = async (...extraOptions: TParams) => { + const response = await request({ ...options, ...extraOptions }); + return response.data as TData; + }; + } + const req = useAhooksRequest(s, { + // Note: + // ahooks/useRequest manual default to true. + // ICE3/useRequest Default to manual request. + manual: true, + ...options, + }, plugins); + return { + ...req, + // Modify ahooks' useRequest `run` as `request` + request: req.run, + } as RequestResult<TData, TParams>; +} + +export default useRequest; + +function isFunction(fn: any): fn is Function { + return typeof fn === 'function'; +} diff --git a/packages/plugin-request/src/index.ts b/packages/plugin-request/src/index.ts new file mode 100644 index 000000000..dad9cd6de --- /dev/null +++ b/packages/plugin-request/src/index.ts @@ -0,0 +1,37 @@ +import { fileURLToPath } from 'url'; +import path from 'path'; +import type { Plugin } from '@ice/types'; +import type { Request, Interceptors, InterceptorRequest, InterceptorResponse } from './types'; + +// @ts-ignore +// eslint-disable-next-line +interface PluginRequestOptions {} + +const plugin: Plugin<PluginRequestOptions | void> = () => ({ + name: 'plugin-request', + setup: ({ generator }) => { + // Add useRequest export for 'ice'. + // import { useRequest } from 'ice'; + generator.addExport({ + specifier: 'useRequest', + source: '@ice/plugin-request/hooks', + type: false, + }); + // import { request } from 'ice'; + generator.addExport({ + specifier: 'request', + source: '@ice/plugin-request/request', + type: false, + }); + }, + runtime: path.join(path.dirname(fileURLToPath(import.meta.url)), 'runtime.js'), +}); + +export type { + Request, + Interceptors, + InterceptorRequest, + InterceptorResponse, + PluginRequestOptions, +}; +export default plugin; diff --git a/packages/plugin-request/src/request.ts b/packages/plugin-request/src/request.ts new file mode 100644 index 000000000..19427ba05 --- /dev/null +++ b/packages/plugin-request/src/request.ts @@ -0,0 +1,124 @@ +import type { AxiosRequestConfig, CancelTokenStatic, CancelStatic } from 'axios'; +import axios from 'axios'; + +// https://github.com/axios/axios#request-config +const DEFAULT_CONFIG = {}; + +const axiosInstances = { + default: axios.create(DEFAULT_CONFIG), +}; + +/** + * Create an axios instance. + * @param instanceName + */ +export function createAxiosInstance(instanceName?: string) { + if (instanceName) { + if (axiosInstances[instanceName]) { + return axiosInstances; + } + axiosInstances[instanceName] = axios.create(DEFAULT_CONFIG); + } + return axiosInstances; +} + +export function setAxiosInstance(requestConfig, axiosInstance) { + const { interceptors = {}, ...requestOptions } = requestConfig; + Object.keys(requestOptions).forEach(key => { + axiosInstance.defaults[key] = requestOptions[key]; + }); + + function isExist(handlers, [fulfilled, rejected]) { + return handlers.some(item => item.fulfilled === fulfilled && item.rejected === rejected); + } + + // Add request interceptor. + if (interceptors.request) { + const [fulfilled, rejected] = [ + interceptors.request.onConfig || function (config) { return config; }, + interceptors.request.onError || function (error) { return Promise.reject(error); }, + ]; + if (isExist(axiosInstance.interceptors.request.handlers, [fulfilled, rejected])) return; + axiosInstance.interceptors.request.use(fulfilled, rejected); + } + + // Add response interceptor. + if (interceptors.response) { + const [fulfilled, rejected] = [ + interceptors.response.onConfig || function (response) { return response; }, + interceptors.response.onError || function (error) { return Promise.reject(error); }, + ]; + if (isExist(axiosInstance.interceptors.response.handlers, [fulfilled, rejected])) return; + axiosInstance.interceptors.response.use(fulfilled, rejected); + } +} + +interface RequestConfig extends AxiosRequestConfig { + instanceName?: string; + withFullResponse?: boolean; +} + +export interface RequestProps { + get: <T = any>(url: string, config?: RequestConfig) => Promise<T>; + delete: <T = any>(url: string, config?: RequestConfig) => Promise<T>; + head: <T = any>(url: string, config?: RequestConfig) => Promise<T>; + options: <T = any>(url: string, config?: RequestConfig) => Promise<T>; + post: <T = any>(url: string, data?: any, config?: RequestConfig) => Promise<T>; + put: <T = any>(url: string, data?: any, config?: RequestConfig) => Promise<T>; + patch: <T = any>(url: string, data?: any, config?: RequestConfig) => Promise<T>; +} + +interface Request extends RequestProps { + <T = any>(options: RequestConfig): Promise<T>; + <T = any>(url: string, config?: RequestConfig): Promise<T>; + Cancel: CancelStatic; + CancelToken: CancelTokenStatic; + isCancel: (value: any) => boolean; +} + +/** + * Request, return response.data | response + * @param options Reference: https://github.com/axios/axios#request-config + */ +const request = async function <T = any>(options): Promise<T> { + try { + const instanceName = options.instanceName ? options.instanceName : 'default'; + const axiosInstance = createAxiosInstance()[instanceName]; + if (!(typeof axiosInstance === 'function')) { + throw new Error(`unknown ${instanceName} in request method`); + } + const response = await axiosInstance(options); + if (axiosInstance.defaults.withFullResponse || options.withFullResponse) { + return response; + } + return response.data; + } catch (error) { + console.error(error); + throw error; + } +}; + +// Provide aliases for supported request methods +['delete', 'get', 'head', 'options'].forEach((method) => { + request[method] = function <T = any>(url, config) { + return request<T>(Object.assign(config || {}, { + method, + url, + })); + }; +}); + +['post', 'put', 'patch'].forEach((method) => { + request[method] = function <T = any>(url, data, config) { + return request<T>(Object.assign(config || {}, { + method, + url, + data, + })); + }; +}); + +request.CancelToken = axios.CancelToken; +request.isCancel = axios.isCancel; + +export default request as Request; diff --git a/packages/plugin-request/src/runtime.ts b/packages/plugin-request/src/runtime.ts new file mode 100644 index 000000000..70926373c --- /dev/null +++ b/packages/plugin-request/src/runtime.ts @@ -0,0 +1,24 @@ +import type { RuntimePlugin } from '@ice/types'; +import { createAxiosInstance, setAxiosInstance } from './request.js'; +import type { RequestConfig } from './types'; + +const runtime: RuntimePlugin = async ({ appContext }) => { + const { appExport } = appContext; + const requestConfig: RequestConfig = (typeof appExport.request === 'function' ? await appExport.request() : appExport.request) || {}; + + // Support multi configs. + if (Array.isArray(requestConfig)) { + requestConfig.forEach(requestItem => { + const instanceName = requestItem.instanceName ? requestItem.instanceName : 'default'; + if (instanceName) { + const axiosInstance = createAxiosInstance(instanceName)[instanceName]; + setAxiosInstance(requestItem, axiosInstance); + } + }); + } else { + const axiosInstance = createAxiosInstance().default; + setAxiosInstance(requestConfig, axiosInstance); + } +}; + +export default runtime; diff --git a/packages/plugin-request/src/types.ts b/packages/plugin-request/src/types.ts new file mode 100644 index 000000000..57b9bd23f --- /dev/null +++ b/packages/plugin-request/src/types.ts @@ -0,0 +1,32 @@ +import type { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'; + +export interface InterceptorRequest<T = AxiosRequestConfig> { + onConfig?: (config: T) => T | Promise<T>; + onError?: (error: AxiosError) => Promise<void>; +} + +export interface InterceptorResponse<K = AxiosResponse> { + onConfig?: (response: K) => K | Promise<K>; + onError?: (error: AxiosError) => Promise<void>; +} + +export interface Interceptors { + request?: InterceptorRequest<AxiosRequestConfig>; + response?: InterceptorResponse<AxiosResponse>; +} + +interface CustomRequest extends AxiosRequestConfig { + instanceName?: string; + withFullResponse?: boolean; + interceptors?: Interceptors; +} + +export type Request = CustomRequest | CustomRequest[]; +export type RequestConfig = Request | object; + +export function defineRequestConfig(configOrDefineConfig: RequestConfig | (() => RequestConfig)): RequestConfig { + if (typeof configOrDefineConfig === 'function') { + return configOrDefineConfig(); + } + return configOrDefineConfig; +} diff --git a/packages/plugin-request/tsconfig.json b/packages/plugin-request/tsconfig.json new file mode 100644 index 000000000..769280c92 --- /dev/null +++ b/packages/plugin-request/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "baseUrl": "./", + "rootDir": "src", + "outDir": "esm", + "jsx": "react" + }, + "include": ["src"] +} diff --git a/packages/plugin-store/src/index.ts b/packages/plugin-store/src/index.ts index 16efbb420..9025de90c 100644 --- a/packages/plugin-store/src/index.ts +++ b/packages/plugin-store/src/index.ts @@ -6,7 +6,7 @@ import fg from 'fast-glob'; import { PAGE_STORE_MODULE, PAGE_STORE_PROVIDER, PAGE_STORE_INITIAL_STATES } from './constants.js'; interface Options { - disableResetPageState?: boolean; + resetPageState?: boolean; } const storeFilePattern = '**/store.{js,ts}'; const ignoreStoreFilePatterns = ['**/models/**', storeFilePattern]; @@ -14,7 +14,7 @@ const ignoreStoreFilePatterns = ['**/models/**', storeFilePattern]; const plugin: Plugin<Options> = (options) => ({ name: '@ice/plugin-store', setup: ({ onGetConfig, modifyUserConfig, generator, context: { rootDir, userConfig } }) => { - const { disableResetPageState = false } = options || {}; + const { resetPageState = false } = options || {}; const srcDir = path.join(rootDir, 'src'); const pageDir = path.join(srcDir, 'pages'); @@ -34,7 +34,7 @@ const plugin: Plugin<Options> = (options) => ({ } config.transformPlugins = [ ...(config.transformPlugins || []), - exportStoreProviderPlugin({ pageDir, disableResetPageState }), + exportStoreProviderPlugin({ pageDir, resetPageState }), ]; return config; }); @@ -49,7 +49,7 @@ const plugin: Plugin<Options> = (options) => ({ runtime: path.join(path.dirname(fileURLToPath(import.meta.url)), 'runtime.js'), }); -function exportStoreProviderPlugin({ pageDir, disableResetPageState }: { pageDir: string; disableResetPageState: boolean }): Config['transformPlugins'][0] { +function exportStoreProviderPlugin({ pageDir, resetPageState }: { pageDir: string; resetPageState: boolean }): Config['transformPlugins'][0] { return { name: 'export-store-provider', enforce: 'post', @@ -63,7 +63,7 @@ function exportStoreProviderPlugin({ pageDir, disableResetPageState }: { pageDir isLayout(id) || // Current id is layout. !isLayoutExisted(id) // If current id is route and there is no layout in the current dir. ) { - return exportPageStore(source, disableResetPageState); + return exportPageStore(source, resetPageState); } } return source; @@ -71,14 +71,14 @@ function exportStoreProviderPlugin({ pageDir, disableResetPageState }: { pageDir }; } -function exportPageStore(source: string, disableResetPageState: boolean) { +function exportPageStore(source: string, resetPageState: boolean) { const importStoreStatement = `import ${PAGE_STORE_MODULE} from './store';\n`; - const exportStoreProviderStatement = disableResetPageState ? ` -const { Provider: ${PAGE_STORE_PROVIDER} } = ${PAGE_STORE_MODULE}; -export { ${PAGE_STORE_PROVIDER} };` : ` + const exportStoreProviderStatement = resetPageState ? ` const { Provider: ${PAGE_STORE_PROVIDER}, getState } = ${PAGE_STORE_MODULE}; const ${PAGE_STORE_INITIAL_STATES} = getState(); -export { ${PAGE_STORE_PROVIDER}, ${PAGE_STORE_INITIAL_STATES} };`; +export { ${PAGE_STORE_PROVIDER}, ${PAGE_STORE_INITIAL_STATES} };` : ` +const { Provider: ${PAGE_STORE_PROVIDER} } = ${PAGE_STORE_MODULE}; +export { ${PAGE_STORE_PROVIDER} };`; return importStoreStatement + source + exportStoreProviderStatement; } diff --git a/packages/rax-compat/CHANGELOG.md b/packages/rax-compat/CHANGELOG.md new file mode 100644 index 000000000..6ab6f4981 --- /dev/null +++ b/packages/rax-compat/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## v0.1.2 + +- Fix: support event transform. diff --git a/packages/rax-compat/package.json b/packages/rax-compat/package.json index f997da7d1..eea3f1afd 100644 --- a/packages/rax-compat/package.json +++ b/packages/rax-compat/package.json @@ -1,6 +1,6 @@ { "name": "rax-compat", - "version": "0.1.1", + "version": "0.1.3", "description": "Rax compatible mode, running rax project on the react runtime.", "files": [ "esm", @@ -47,7 +47,8 @@ "dependencies": { "@swc/helpers": "^0.4.3", "style-unit": "^3.0.5", - "create-react-class": "^15.7.0" + "create-react-class": "^15.7.0", + "@ice/appear": "^0.1.0" }, "devDependencies": { "@ice/pkg": "1.1.2-0", @@ -71,4 +72,4 @@ "author": "ice-admin@alibaba-inc.com", "license": "MIT", "homepage": "https://github.com/ice-lab/ice-next#readme" -} +} \ No newline at end of file diff --git a/packages/rax-compat/src/create-element.ts b/packages/rax-compat/src/create-element.ts index 640d9747e..6a4dfc6f2 100644 --- a/packages/rax-compat/src/create-element.ts +++ b/packages/rax-compat/src/create-element.ts @@ -6,10 +6,11 @@ import type { RefObject, SyntheticEvent, } from 'react'; -import { createElement as _createElement, useEffect, useCallback, useRef, useState, forwardRef as _forwardRef } from 'react'; +import { createElement as _createElement, useEffect, useCallback, useRef, useState } from 'react'; import { cached, convertUnit } from 'style-unit'; -import { observerElement } from './visibility'; +import VisibilityChange from '@ice/appear'; import { isFunction, isObject, isNumber } from './type'; +import transformPrototype from './prototypes'; // https://github.com/alibaba/rax/blob/master/packages/driver-dom/src/index.js @@ -28,35 +29,52 @@ import { isFunction, isObject, isNumber } from './type'; // borderImageOutset|borderImageSlice|borderImageWidth -> erim const NON_DIMENSIONAL_REG = /opa|ntw|ne[ch]|ex(?:s|g|n|p|$)|^ord|zoo|grid|orp|ows|mnc|^columns$|bs|erim|onit/i; -function createInputCompat(type: string) { - function InputCompat(props: any, ref: RefObject<any>) { - const { value, onInput, ...rest } = props; - const [v, setV] = useState(value); - const onChange = useCallback((event: SyntheticEvent) => { - setV((event.target as HTMLInputElement).value); - - // Event of onInput should be native event. - onInput && onInput(event.nativeEvent); - }, [onInput]); - - // Compat maxlength in rax-textinput, because maxlength is invalid props in web,it will be set attributes to element - // and react will Throw a warning in DEV. - // https://github.com/raxjs/rax-components/issues/459 - // https://github.com/raxjs/rax-components/blob/master/packages/rax-textinput/src/index.tsx#L142 - if (rest.maxlength) { - rest.maxLength = rest.maxlength; - delete rest.maxlength; - } - - return _createElement(type, { - ...rest, - value: v, - onChange, - ref, - }); +function InputCompat(props: any) { + const { value, onInput, onChange, inputType, ...rest } = props; + const [v, setV] = useState(value); + const changeCallback = useCallback((event: SyntheticEvent) => { + setV((event.target as HTMLInputElement).value); + + // Event of onInput should be native event. + onInput && onInput(event.nativeEvent); + }, [onInput]); + + const ref = useRef(); + + useEffect(() => { + setV(value); + }, [value]); + + // Compat maxlength in rax-textinput, because maxlength is invalid props in web,it will be set attributes to element + // and react will Throw a warning in DEV. + // https://github.com/raxjs/rax-components/issues/459 + // https://github.com/raxjs/rax-components/blob/master/packages/rax-textinput/src/index.tsx#L142 + if (rest.maxlength) { + rest.maxLength = rest.maxlength; + delete rest.maxlength; } - return _forwardRef(InputCompat); + // The onChange event is SyntheticEvent in React, but it is dom event in Rax, so it needs compat onChange. + useEffect(() => { + let eventTarget: EventTarget; + if (ref && ref.current && onChange) { + eventTarget = ref.current; + eventTarget.addEventListener('change', onChange); + } + + return () => { + if (eventTarget) { + eventTarget.removeEventListener('change', onChange); + } + }; + }, [onChange]); + + return _createElement(inputType, { + ...rest, + value: v, + onChange: changeCallback, + ref, + }); } /** @@ -78,26 +96,29 @@ export function createElement<P extends { props?: Attributes & P | null, ...children: ReactNode[]): ReactElement { // Get a shallow copy of props, to avoid mutating the original object. - const rest = Object.assign({}, props); + let rest: Attributes & P = Object.assign({}, props); const { onAppear, onDisappear } = rest; // Delete props that are not allowed in react. delete rest.onAppear; delete rest.onDisappear; + rest = transformPrototype(rest); + // Compat for style unit. const compatStyleProps = compatStyle(rest.style); if (compatStyleProps) { rest.style = compatStyleProps; } + // Setting the value of props makes the component be a controlled component in React. + // But setting the value is same as web in Rax. + // User can modify value of props to modify native input value + // and native input can also modify the value of self in Rax. + // So we should compat input to InputCompat, the same as textarea. if (type === 'input' || type === 'textarea') { - // Setting the value of props makes the component be a controlled component in React. - // But setting the value is same as web in Rax. - // User can modify value of props to modify native input value - // and native input can also modify the value of self in Rax. - // So we should compat input to InputCompat, the same as textarea. - type = createInputCompat(type); + rest.inputType = type; + type = InputCompat; } // Compat for visibility events. @@ -107,10 +128,7 @@ export function createElement<P extends { { onAppear, onDisappear, - // Passing child ref to `VisibilityChange` to avoid creating a new ref. - childRef: rest.ref, - // Using forwardedRef as a prop to the backend react element. - forwardRef: (ref: RefObject<any>) => _createElement(type, Object.assign({ ref }, rest), ...children), + children: _createElement(type, rest, ...children), }, ); } else { @@ -118,40 +136,6 @@ export function createElement<P extends { } } -function VisibilityChange({ - onAppear, - onDisappear, - childRef, - forwardRef, -}: any) { - const fallbackRef = useRef(null); // `fallbackRef` used if `childRef` is not provided. - const ref = childRef || fallbackRef; - - const listen = useCallback((eventName: string, handler: Function) => { - const { current } = ref; - // Rax components will set custom ref by useImperativeHandle. - // So We should get eventTarget by _nativeNode. - // https://github.com/raxjs/rax-components/blob/master/packages/rax-textinput/src/index.tsx#L151 - if (current && isFunction(handler)) { - const eventTarget = current._nativeNode || current; - observerElement(eventTarget as HTMLElement); - eventTarget.addEventListener(eventName, handler); - } - return () => { - const { current } = ref; - if (current) { - const eventTarget = current._nativeNode || current; - eventTarget.removeEventListener(eventName, handler); - } - }; - }, [ref]); - - useEffect(() => listen('appear', onAppear), [ref, onAppear, listen]); - useEffect(() => listen('disappear', onDisappear), [ref, onDisappear, listen]); - - return forwardRef(ref); -} - const isDimensionalProp = cached((prop: string) => !NON_DIMENSIONAL_REG.test(prop)); // Convert unit as driver-dom does. diff --git a/packages/rax-compat/src/events.ts b/packages/rax-compat/src/events.ts new file mode 100644 index 000000000..5f1c19a07 --- /dev/null +++ b/packages/rax-compat/src/events.ts @@ -0,0 +1,118 @@ + +// Fork from https://github.com/facebook/react/blob/main/packages/react-dom/src/events/DOMEventProperties.js#L36 +const events = [ + 'abort', + 'auxClick', + 'animationEnd', + 'animationIteration', + 'animationStart', + 'cancel', + 'canPlay', + 'canPlayThrough', + 'click', + 'close', + 'contextMenu', + 'copy', + 'cut', + 'dblclick', + 'drag', + 'dragEnd', + 'dragEnter', + 'dragExit', + 'dragLeave', + 'dragOver', + 'dragStart', + 'drop', + 'durationChange', + 'emptied', + 'encrypted', + 'ended', + 'error', + 'gotPointerCapture', + 'input', + 'invalid', + 'keyDown', + 'keyPress', + 'keyUp', + 'load', + 'loadedData', + 'loadedMetadata', + 'loadStart', + 'lostPointerCapture', + 'mouseDown', + 'mouseMove', + 'mouseOut', + 'mouseOver', + 'mouseUp', + 'paste', + 'pause', + 'play', + 'playing', + 'pointerCancel', + 'pointerDown', + 'pointerMove', + 'pointerOut', + 'pointerOver', + 'pointerUp', + 'progress', + 'rateChange', + 'reset', + 'resize', + 'seeked', + 'seeking', + 'stalled', + 'submit', + 'suspend', + 'transitionEnd', + 'timeUpdate', + 'touchCancel', + 'touchEnd', + 'touchStart', + 'volumeChange', + 'scroll', + 'toggle', + 'touchMove', + 'waiting', + 'wheel', + // EnterLeaveEventPlugin.registerEvents need't to convert to other bubbling events in rax compat, + // which are directly brokered, leaving the rest to React. + // https://github.com/facebook/react/blob/main/packages/react-dom/src/events/plugins/EnterLeaveEventPlugin.js#L29 + 'mouseEnter', + 'mouseLeave', + 'pointerEnter', + 'pointerLeave', + // https://github.com/facebook/react/blob/main/packages/react-dom/src/events/plugins/ChangeEventPlugin.js#L37 + 'change', + // https://github.com/facebook/react/blob/main/packages/react-dom/src/events/plugins/SelectEventPlugin.js + 'select', + // https://github.com/facebook/react/blob/main/packages/react-dom/src/events/plugins/BeforeInputEventPlugin.js + 'beforeInput', + 'compositionEnd', + 'compositionStart', + 'compositionUpdate', +]; + +// A map for transform event to react event. +// Such as ontouchstart transform to onTouchStart. +export const registrationNameToReactEvent: Map<string, string> = new Map(); + +registerEvents(); + +function registerDirectEvent( + registrationName: string, + reactEventName: string, +) { + registrationNameToReactEvent.set(`on${registrationName}`, reactEventName); +} + +function registerEvents() { + for (let i = 0; i < events.length; i++) { + const eventName: string = events[i]; + const domEventName: string = eventName.toLowerCase(); + const capitalizedEvent = eventName[0].toUpperCase() + eventName.slice(1); + registerDirectEvent(domEventName, `on${capitalizedEvent}`); + } + // Special cases where event names don't match. + registerDirectEvent('dblclick', 'onDoubleClick'); +} + diff --git a/packages/rax-compat/src/prototypes.ts b/packages/rax-compat/src/prototypes.ts new file mode 100644 index 000000000..5d0f1ab3d --- /dev/null +++ b/packages/rax-compat/src/prototypes.ts @@ -0,0 +1,27 @@ +import { registrationNameToReactEvent } from './events'; + +export default function transformPrototype(props: Object): Object { + const resProps: Object = {}; + Object.keys(props).forEach((propKey: string) => { + let resKey: string = propKey; + let resValue: string = props[propKey]; + // Transform the event so that it works properly in React. + // ontouchstart can work in rax, but react will check event in event plugin. + // Rax compat should transform event which can work in rax runtime. + // React support onDoubleClick but dblclick event is web Standards events. + // etc... + if (propKey.startsWith('on')) { + const lowerCasedPropkey: string = propKey.toLowerCase(); + if (registrationNameToReactEvent.has(lowerCasedPropkey)) { + const reactEvent: string = registrationNameToReactEvent.get(lowerCasedPropkey); + if (reactEvent !== propKey) { + resKey = reactEvent; + } + } + } + + resProps[resKey] = resValue; + }); + + return resProps; +} diff --git a/packages/rax-compat/src/shared.ts b/packages/rax-compat/src/shared.ts index 54ba0176e..ad5ac94ef 100644 --- a/packages/rax-compat/src/shared.ts +++ b/packages/rax-compat/src/shared.ts @@ -1,5 +1,7 @@ import type { ReactElement } from 'react'; +type ChildrenElement<T> = ChildrenElement<T>[] | T; + // Mocked `Rax.shared`. const shared = { get Element(): any { @@ -27,7 +29,7 @@ function warningCompat(message: string) { console.error(`[RaxCompat] ${stack}`); } -function flattenChildren(children: ReactElement) { +function flattenChildren(children: ChildrenElement<ReactElement>) { if (children == null) { return children; } @@ -39,7 +41,7 @@ function flattenChildren(children: ReactElement) { return result.length - 1 ? result : result[0]; } -function traverseChildren(children: ReactElement, result: ReactElement[]) { +function traverseChildren(children: ChildrenElement<ReactElement>, result: ReactElement[]) { if (Array.isArray(children)) { for (let i = 0, l = children.length; i < l; i++) { traverseChildren(children[i], result); diff --git a/packages/rax-compat/tests/children.test.tsx b/packages/rax-compat/tests/children.test.tsx index a0aa01b53..69a9f29f6 100644 --- a/packages/rax-compat/tests/children.test.tsx +++ b/packages/rax-compat/tests/children.test.tsx @@ -1,25 +1,25 @@ import React from 'react'; import { expect, it, describe } from 'vitest'; -import Children from '../src/children'; import { render } from '@testing-library/react'; +import Children from '../src/children'; const arrText = ['hello', 'rax']; describe('children', () => { it('should work with map', () => { function Hello({ children }) { - return <div data-testid="test"> + return (<div data-testid="test"> { Children.map(children, (child, i) => { if (i === 0) { - return <span>{arrText[1]}</span> + return <span>{arrText[1]}</span>; } return child; }) } - </div> + </div>); } - + const instance = ( <Hello> <span>{arrText[0]}</span> @@ -29,10 +29,10 @@ describe('children', () => { const wrapper = render(instance); const node = wrapper.queryByTestId('test'); - + expect(node.children.item(0).textContent).toBe(node.children.item(0).textContent); expect(node.children.item(1).textContent).toBe(arrText[1]); - }) + }); it('should work with forEach', () => { function Hello({ children }) { @@ -40,9 +40,9 @@ describe('children', () => { expect(child.type).toBe('span'); expect(child.props.children).toBe(arrText[i]); }); - return children + return children; } - + const instance = ( <Hello> <span>{arrText[0]}</span> @@ -51,14 +51,14 @@ describe('children', () => { ); render(instance); - }) + }); it('should work with count', () => { function Hello({ children }) { expect(Children.count(children)).toBe(arrText.length); - return children + return children; } - + const instance = ( <Hello> <span>{arrText[0]}</span> @@ -67,15 +67,15 @@ describe('children', () => { ); render(instance); - }) + }); it('should work with only', () => { let child = <span>{arrText[0]}</span>; function Hello({ children }) { expect(Children.only(children)).toBe(child); - return children + return children; } - + const instance = ( <Hello> { @@ -85,14 +85,14 @@ describe('children', () => { ); render(instance); - }) + }); it('should work with toArray', () => { function Hello({ children }) { expect(Children.toArray(children).length).toBe(arrText.length); - return children + return children; } - + const instance = ( <Hello> <span>{arrText[0]}</span> @@ -101,7 +101,7 @@ describe('children', () => { ); render(instance); - }) + }); it('should escape keys', () => { const zero = <div key="1" />; @@ -139,7 +139,7 @@ describe('children', () => { null, <span key="y" />, kid, - kid && React.cloneElement(kid, {key: 'z'}), + kid && React.cloneElement(kid, { key: 'z' }), <hr />, ], ); diff --git a/packages/rax-compat/tests/cloneElement.test.tsx b/packages/rax-compat/tests/cloneElement.test.tsx index f3277a795..6e77d67fe 100644 --- a/packages/rax-compat/tests/cloneElement.test.tsx +++ b/packages/rax-compat/tests/cloneElement.test.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { expect, it, describe } from 'vitest'; +import { render } from '@testing-library/react'; import { Component } from '../src/index'; import cloneElement from '../src/clone-element'; -import { render } from '@testing-library/react'; describe('cloneElement', () => { it('basic', () => { diff --git a/packages/rax-compat/tests/component.test.tsx b/packages/rax-compat/tests/component.test.tsx index e9de1445b..94743b06e 100644 --- a/packages/rax-compat/tests/component.test.tsx +++ b/packages/rax-compat/tests/component.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { expect, it, describe } from 'vitest'; -import { Component, PureComponent, memo } from '../src/index'; import { render } from '@testing-library/react'; +import { Component, PureComponent, memo } from '../src/index'; describe('component', () => { it('Component should work', () => { @@ -31,8 +31,8 @@ describe('component', () => { }); it('memo should work', () => { - const MyComponent = memo(function MyComponent(props: { text: string, id: string }) { - return <div id={props.id}>{props.text}</div> + const MyComponent = memo((props: { text: string; id: string }) => { + return <div id={props.id}>{props.text}</div>; }); const wrapper = render(<MyComponent id="" text="memo demo" />); diff --git a/packages/rax-compat/tests/createElement.test.tsx b/packages/rax-compat/tests/createElement.test.tsx index 0ba0e3afb..42e7a8507 100644 --- a/packages/rax-compat/tests/createElement.test.tsx +++ b/packages/rax-compat/tests/createElement.test.tsx @@ -1,6 +1,6 @@ import { expect, it, describe, vi } from 'vitest'; -import { createElement } from '../src/index'; import { render } from '@testing-library/react'; +import { createElement } from '../src/index'; describe('createElement', () => { it('basic', () => { @@ -8,7 +8,7 @@ describe('createElement', () => { const wrapper = render(createElement( 'div', null, - str + str, )); expect(wrapper.container.childNodes[0].textContent).toBe(str); }); @@ -17,32 +17,32 @@ describe('createElement', () => { let appearFun = vi.spyOn({ func: () => { expect(appearFun).toHaveBeenCalled(); - } - }, 'func') + }, + }, 'func'); const str = 'hello world'; render(createElement( 'div', { - onAppear: appearFun + onAppear: appearFun, }, - str + str, )); }); it('should work with onDisappear', () => { const func = () => { expect(disappearFun).toHaveBeenCalled(); - } + }; let disappearFun = vi.spyOn({ - func: func - }, 'func') + func: func, + }, 'func'); const str = 'hello world'; render(createElement( 'div', { onDisappear: func, }, - str + str, )); }); @@ -53,10 +53,10 @@ describe('createElement', () => { { 'data-testid': 'rpxTest', style: { - width: '300rpx' - } + width: '300rpx', + }, }, - str + str, )); const node = wrapper.queryByTestId('rpxTest'); @@ -84,7 +84,7 @@ describe('createElement', () => { { 'data-testid': 'maxlengthTest', value: str, - maxlength: '' + maxlength: '', }, )); diff --git a/packages/rax-compat/tests/createFactory.test.tsx b/packages/rax-compat/tests/createFactory.test.tsx index bf0ee9e00..63139e1a5 100644 --- a/packages/rax-compat/tests/createFactory.test.tsx +++ b/packages/rax-compat/tests/createFactory.test.tsx @@ -1,23 +1,13 @@ import { expect, it, describe } from 'vitest'; -import { Component } from '../src/index'; -import createFactory from '../src/create-factory'; import { render } from '@testing-library/react'; +import createFactory from '../src/create-factory'; describe('createFactory', () => { it('basic', () => { - class CustomComponent extends Component { - text: string = ''; - - render() { - return <div>{this.props.text}</div>; - } - } - - const factory = createFactory("div"); - const div = factory(null,'div node'); + const factory = createFactory('div'); + const div = factory(null, 'div node'); const wrapper = render(div); - const node = wrapper.queryByTestId('div'); let res = wrapper.getAllByText('div node'); expect(res.length).toBe(1); diff --git a/packages/rax-compat/tests/createPortal.test.tsx b/packages/rax-compat/tests/createPortal.test.tsx index 7ed46a2a4..880657fd0 100644 --- a/packages/rax-compat/tests/createPortal.test.tsx +++ b/packages/rax-compat/tests/createPortal.test.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { expect, it, describe } from 'vitest'; -import createPortal from '../src/create-portal'; import { render } from '@testing-library/react'; +import createPortal from '../src/create-portal'; describe('createPortal', () => { it('basic', () => { @@ -11,13 +11,13 @@ describe('createPortal', () => { const Portal = ({ children }) => { return createPortal(children, div); }; - + function App() { - return <div> + return (<div> <Portal> <text>Hello Rax</text> </Portal> - </div> + </div>); } render(<App />); diff --git a/packages/rax-compat/tests/createReactClass.test.tsx b/packages/rax-compat/tests/createReactClass.test.tsx index 1fd113bfb..1731d0b2c 100644 --- a/packages/rax-compat/tests/createReactClass.test.tsx +++ b/packages/rax-compat/tests/createReactClass.test.tsx @@ -1,16 +1,16 @@ import { expect, it, describe } from 'vitest'; import React from 'react'; -import createReactClass from '../src/create-class'; import { render } from '@testing-library/react'; +import createReactClass from '../src/create-class'; describe('createReactClass', () => { it('basic', () => { const ReactClass = createReactClass({ name: '', id: '', - render: function() { + render: function () { return <div data-testid={this.props.id}>Hello, {this.props.name}</div>; - } + }, }); const wrapper = render(<ReactClass id="reactClassId" name="raxCompat" />); diff --git a/packages/rax-compat/tests/events.test.tsx b/packages/rax-compat/tests/events.test.tsx new file mode 100644 index 000000000..d6d402efc --- /dev/null +++ b/packages/rax-compat/tests/events.test.tsx @@ -0,0 +1,115 @@ +import { expect, it, describe, vi } from 'vitest'; +import React from 'react'; +import { render } from '@testing-library/react'; +import { useRef, useEffect } from '../src/index'; +import { createElement } from '../src/create-element'; +import findDOMNode from '../src/find-dom-node'; +import transformPrototype from '../src/prototypes'; + +describe('events', () => { + it('should work with onclick', () => { + function App() { + const ref = useRef(null); + + const obj = { + handleClick: () => console.log('click'), + }; + + const click = vi.spyOn(obj, 'handleClick'); + + useEffect(() => { + const dom = findDOMNode(ref.current); + dom.click(); + expect(click).toHaveBeenCalled(); + }); + + return createElement('div', { + onclick: obj.handleClick, + ref: ref, + }, 'click me'); + } + + render(<App />); + }); + + it('should work with ontouchstart', () => { + expect(transformPrototype({ + ontouchstart: () => { }, + }).onTouchStart).toBeInstanceOf(Function); + }); + + it('should work with onclick', () => { + expect(transformPrototype({ + onclick: () => { }, + }).onClick).toBeInstanceOf(Function); + expect(transformPrototype({ + onclick: () => { }, + }).onclick).toBe(undefined); + }); + + it('should work with onClick', () => { + expect(transformPrototype({ + onClick: () => { }, + }).onClick).toBeInstanceOf(Function); + }); + + it('should work with ondblclick', () => { + expect(transformPrototype({ + ondblclick: () => { }, + }).onDoubleClick).toBeInstanceOf(Function); + expect(transformPrototype({ + ondblclick: () => { }, + }).ondblclick).toBe(undefined); + }); + + it('should work with onDblclick', () => { + expect(transformPrototype({ + onDblclick: () => { }, + }).onDoubleClick).toBeInstanceOf(Function); + expect(transformPrototype({ + onDblclick: () => { }, + }).onDblclick).toBe(undefined); + }); + + it('should work with onDoubleClick', () => { + expect(transformPrototype({ + onDoubleClick: () => { }, + }).onDoubleClick).toBeInstanceOf(Function); + }); + + it('should work with onmouseenter', () => { + expect(transformPrototype({ + onmouseenter: () => { }, + }).onMouseEnter).toBeInstanceOf(Function); + expect(transformPrototype({ + onmouseenter: () => { }, + }).onmouseenter).toBe(undefined); + }); + + it('should work with onpointerenter', () => { + expect(transformPrototype({ + onpointerenter: () => { }, + }).onPointerEnter).toBeInstanceOf(Function); + expect(transformPrototype({ + onpointerenter: () => { }, + }).onpointerenter).toBe(undefined); + }); + + it('should work with onchange', () => { + expect(transformPrototype({ + onchange: () => { }, + }).onChange).toBeInstanceOf(Function); + expect(transformPrototype({ + onchange: () => { }, + }).onchange).toBe(undefined); + }); + + it('should work with onbeforeinput', () => { + expect(transformPrototype({ + onbeforeinput: () => { }, + }).onBeforeInput).toBeInstanceOf(Function); + expect(transformPrototype({ + onbeforeinput: () => { }, + }).onbeforeinput).toBe(undefined); + }); +}); diff --git a/packages/rax-compat/tests/findDomNode.test.tsx b/packages/rax-compat/tests/findDomNode.test.tsx index 9a913754f..efcc2d37e 100644 --- a/packages/rax-compat/tests/findDomNode.test.tsx +++ b/packages/rax-compat/tests/findDomNode.test.tsx @@ -1,8 +1,8 @@ import { expect, it, describe } from 'vitest'; import React from 'react'; +import { render } from '@testing-library/react'; import { useRef, useEffect } from '../src/index'; import findDOMNode from '../src/find-dom-node'; -import { render } from '@testing-library/react'; describe('findDomNode', () => { it('basic', () => { diff --git a/packages/rax-compat/tests/fragment.test.tsx b/packages/rax-compat/tests/fragment.test.tsx index 36659dc1f..539ab44a2 100644 --- a/packages/rax-compat/tests/fragment.test.tsx +++ b/packages/rax-compat/tests/fragment.test.tsx @@ -1,15 +1,15 @@ import { expect, it, describe } from 'vitest'; import React from 'react'; -import Fragment from '../src/fragment'; import { render } from '@testing-library/react'; +import Fragment from '../src/fragment'; describe('fragment', () => { it('basic', () => { function App() { - return <Fragment> + return (<Fragment> <header>A heading</header> <footer>A footer</footer> - </Fragment>; + </Fragment>); } const wrapper = render(<App />); diff --git a/packages/rax-compat/tests/hooks.test.tsx b/packages/rax-compat/tests/hooks.test.tsx index 327292d56..01d1421b0 100644 --- a/packages/rax-compat/tests/hooks.test.tsx +++ b/packages/rax-compat/tests/hooks.test.tsx @@ -1,5 +1,6 @@ import { expect, it, describe, vi } from 'vitest'; import React from 'react'; +import { render } from '@testing-library/react'; import { useState, useEffect, @@ -8,12 +9,11 @@ import { useContext, useRef, } from '../src/hooks'; -import { render } from '@testing-library/react'; describe('hooks', () => { it('useState', () => { function App() { - const [state, setState] = useState({ text: 'text' }); + const [state] = useState({ text: 'text' }); expect(state.text).toBe('text'); return <div>{state.text}</div>; } @@ -30,6 +30,8 @@ describe('hooks', () => { setLoading(false); expect(loading).toBe(false); }, 1); + // Expect useEffect to execute once + // eslint-disable-next-line }, []); return <div>{loading ? 'loading...' : 'load end'}</div>; } @@ -41,11 +43,11 @@ describe('hooks', () => { let useEffectFunc = vi.spyOn({ func: () => { expect(useEffectFunc).toHaveBeenCalled(); - } - }, 'func') + }, + }, 'func'); function App() { useEffect(useEffectFunc, []); - + return <div>useEffect</div>; } @@ -56,11 +58,11 @@ describe('hooks', () => { let useEffectFunc = vi.spyOn({ func: () => { expect(useEffectFunc).toHaveBeenCalled(); - } - }, 'func') + }, + }, 'func'); function App() { useLayoutEffect(useEffectFunc, []); - + return <div>useEffect</div>; } @@ -69,7 +71,7 @@ describe('hooks', () => { it('useContext', () => { const Context = createContext({ - theme: 'dark' + theme: 'dark', }); function App() { const context = useContext(Context); @@ -79,7 +81,7 @@ describe('hooks', () => { const wrapper = render(<App />); wrapper.findAllByText('dark').then((res) => { expect(res.length).toBe(1); - }); + }); }); it('useRef', () => { @@ -87,15 +89,14 @@ describe('hooks', () => { const inputEl = useRef(null); useEffect(() => { expect(inputEl.current).instanceOf(Element); - }) + }); return ( - <> - <input ref={inputEl} type="text" /> - </> + <> + <input ref={inputEl} type="text" /> + </> ); } render(<TextInputWithFocusButton />); }); - }); diff --git a/packages/rax-compat/tests/inputElement.test.tsx b/packages/rax-compat/tests/inputElement.test.tsx new file mode 100644 index 000000000..24e701020 --- /dev/null +++ b/packages/rax-compat/tests/inputElement.test.tsx @@ -0,0 +1,86 @@ +import React from 'react'; +import { expect, it, describe } from 'vitest'; +import { render } from '@testing-library/react'; +import { useState } from '../src/index'; +import { createElement } from '../src/create-element'; + +describe('inputElement', () => { + it('should work with update input value', () => { + function TestInput() { + const [val, setVal] = useState('input value'); + return (<div> + <input + data-testid="inputValue" + value={val} + /> + + <div + data-testid="inputValueDiv" + onClick={() => { + setVal('111'); + }} + > + click me... + </div> + </div>); + } + + const wrapper = render(createElement(TestInput)); + wrapper.queryByTestId('inputValueDiv')?.click(); + const node = wrapper.queryByTestId('inputValue'); + + setTimeout(() => { + // Wait for click handler. + expect(node.value).toBe('111'); + }, 0); + }); + + it('inputElement should not recreate when update props', () => { + function TestInput() { + const [val, setVal] = useState('input value'); + return (<div> + <input + data-testid="sameInput" + value={val} + /> + + <div + data-testid="sameInputDiv" + onClick={() => { + setVal('111'); + }} + > + click me... + </div> + </div>); + } + + const wrapper = render(createElement(TestInput)); + + const node = wrapper.queryByTestId('sameInput'); + node?.setAttribute('date-value', 'val'); + + wrapper.queryByTestId('sameInputDiv')?.click(); + + setTimeout(() => { + // Wait for click handler. + expect(node?.getAttribute('date-value')).toBe('val'); + }, 0); + }); + + it('should work with onChange', () => { + return new Promise((resolve) => { + function TestInput() { + return createElement('input', { + 'data-testid': 'changeInput', + onChange: () => resolve(), + }); + } + + const wrapper = render(createElement(TestInput)); + + const node = wrapper.queryByTestId('changeInput'); + node!.dispatchEvent(new Event('change')); + }); + }); +}); diff --git a/packages/rax-compat/tests/isValidElement.test.tsx b/packages/rax-compat/tests/isValidElement.test.tsx index 4f9f61948..c2a2e0e57 100644 --- a/packages/rax-compat/tests/isValidElement.test.tsx +++ b/packages/rax-compat/tests/isValidElement.test.tsx @@ -5,9 +5,9 @@ import isValidElement from '../src/is-valid-element'; describe('isValidElement', () => { it('basic', () => { function App() { - return <div> + return (<div> <div>isValidElement</div> - </div>; + </div>); } expect(isValidElement(<App />)).toBe(true); diff --git a/packages/rax-compat/tests/shared.test.tsx b/packages/rax-compat/tests/shared.test.tsx index 4b68159d3..b8a11b07f 100644 --- a/packages/rax-compat/tests/shared.test.tsx +++ b/packages/rax-compat/tests/shared.test.tsx @@ -4,10 +4,24 @@ import { shared } from '../src/index'; describe('render', () => { it('basic', () => { - console.log('shared.Element', shared) + console.log('shared.Element', shared); expect(shared.Element).toBe(null); expect(shared.Host).toBe(null); expect(shared.Instance).toBe(null); expect(shared.flattenChildren).instanceOf(Function); }); + + it('flattenChildren null', () => { + // @ts-ignore e + expect(shared.flattenChildren(null)).toBe(null); + }); + + it('flattenChildren common', () => { + expect(shared.flattenChildren(<>div</>)).toStrictEqual(<React.Fragment>div</React.Fragment>); + }); + + it('flattenChildren array', () => { + const children = [[[<>div</>]]]; + expect(shared.flattenChildren(children)).toStrictEqual(<React.Fragment>div</React.Fragment>); + }); }); diff --git a/packages/route-manifest/tests/formatNestedRouteManifest.spec.ts b/packages/route-manifest/tests/formatNestedRouteManifest.spec.ts index 06abac15d..c230a23d4 100644 --- a/packages/route-manifest/tests/formatNestedRouteManifest.spec.ts +++ b/packages/route-manifest/tests/formatNestedRouteManifest.spec.ts @@ -1,6 +1,6 @@ -import { expect, test, describe } from 'vitest'; import path from 'path'; import { fileURLToPath } from 'url'; +import { expect, test, describe } from 'vitest'; import { generateRouteManifest, formatNestedRouteManifest } from '../src/index'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); diff --git a/packages/route-manifest/tests/generateRouteManifest.spec.ts b/packages/route-manifest/tests/generateRouteManifest.spec.ts index 5f2df90e2..f86b1d760 100644 --- a/packages/route-manifest/tests/generateRouteManifest.spec.ts +++ b/packages/route-manifest/tests/generateRouteManifest.spec.ts @@ -1,6 +1,6 @@ -import { expect, test, describe } from 'vitest'; import path from 'path'; import { fileURLToPath } from 'url'; +import { expect, test, describe } from 'vitest'; import { generateRouteManifest } from '../src/index'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -33,7 +33,7 @@ describe('generateRouteManifest function', () => { }); test('invalid-routes', () => { - expect(() => generateRouteManifest(path.join(fixturesDir, 'invalid-routes'))).toThrow(`invalid character in 'src/pages/[a.pdf].tsx'. Only support char: -, \\w, /`); + expect(() => generateRouteManifest(path.join(fixturesDir, 'invalid-routes'))).toThrow('invalid character in \'src/pages/[a.pdf].tsx\'. Only support char: -, \\w, /'); }); test('ignore-routes', () => { @@ -43,11 +43,11 @@ describe('generateRouteManifest function', () => { test('define-extra-routes', () => { const routeManifest = generateRouteManifest( - path.join(fixturesDir, 'basic-routes'), - ['About/index.tsx'], + path.join(fixturesDir, 'basic-routes'), + ['About/index.tsx'], (defineRoute) => { defineRoute('/about-me', 'About/index.tsx'); - } + }, ); expect(routeManifest).toMatchSnapshot(); }); diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 156a2e8a2..c14a27261 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -29,16 +29,16 @@ "build": "tsc" }, "devDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0", + "@ice/types": "^1.0.0", "@types/react": "^18.0.8", "@types/react-dom": "^18.0.3", + "react": "^18.0.0", + "react-dom": "^18.0.0", "regenerator-runtime": "^0.13.9" }, "sideEffects": false, "dependencies": { "@ice/jsx-runtime": "^0.1.0", - "consola": "^2.15.3", "history": "^5.3.0", "react-router-dom": "^6.2.2" }, diff --git a/packages/runtime/src/App.tsx b/packages/runtime/src/App.tsx index d8b29eec5..6e645c9e9 100644 --- a/packages/runtime/src/App.tsx +++ b/packages/runtime/src/App.tsx @@ -1,10 +1,10 @@ import React, { useMemo } from 'react'; import type { Action, Location } from 'history'; import type { Navigator } from 'react-router-dom'; +import type { RouteWrapperConfig, AppRouterProps } from '@ice/types'; import AppErrorBoundary from './AppErrorBoundary.js'; import { useAppContext } from './AppContext.js'; import { createRouteElements } from './routes.js'; -import type { RouteWrapperConfig, AppRouterProps } from './types.js'; interface Props { action: Action; diff --git a/packages/runtime/src/AppContext.tsx b/packages/runtime/src/AppContext.tsx index 090b5370d..461c8973e 100644 --- a/packages/runtime/src/AppContext.tsx +++ b/packages/runtime/src/AppContext.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import type { AppContext } from './types.js'; +import type { AppContext } from '@ice/types'; const Context = React.createContext<AppContext | undefined>(undefined); @@ -15,4 +15,4 @@ const AppContextProvider = Context.Provider; export { useAppContext, AppContextProvider, -}; \ No newline at end of file +}; diff --git a/packages/runtime/src/AppData.tsx b/packages/runtime/src/AppData.tsx index a2e99f9f3..89fc75c09 100644 --- a/packages/runtime/src/AppData.tsx +++ b/packages/runtime/src/AppData.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import type { AppExport, AppData, RequestContext } from './types.js'; +import type { AppExport, AppData, RequestContext } from '@ice/types'; const Context = React.createContext<AppData | undefined>(undefined); @@ -32,4 +32,4 @@ export { getAppData, useAppData, AppDataProvider, -}; \ No newline at end of file +}; diff --git a/packages/runtime/src/AppRouter.tsx b/packages/runtime/src/AppRouter.tsx index e360f4a72..bc2dd9992 100644 --- a/packages/runtime/src/AppRouter.tsx +++ b/packages/runtime/src/AppRouter.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; import type { RouteObject } from 'react-router-dom'; import { Router, useRoutes } from 'react-router-dom'; +import type { AppRouterProps } from '@ice/types'; import { Router as RouterSingle, useRoutes as useRoutesSingle } from './single-router.js'; -import type { AppRouterProps } from './types.js'; const AppRouter: React.ComponentType<AppRouterProps> = (props) => { const { action, location, navigator, static: staticProps, routes, basename } = props; @@ -31,4 +31,4 @@ function Routes({ routes }: RoutesProps) { return element; } -export default AppRouter; \ No newline at end of file +export default AppRouter; diff --git a/packages/runtime/src/Document.tsx b/packages/runtime/src/Document.tsx index 4228caf99..a4e9cf5f6 100644 --- a/packages/runtime/src/Document.tsx +++ b/packages/runtime/src/Document.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; import type { ReactNode } from 'react'; +import type { AppContext, RouteMatch, AssetsManifest } from '@ice/types'; import { useAppContext } from './AppContext.js'; import { useAppData } from './AppData.js'; import { getMeta, getTitle, getLinks, getScripts } from './routesConfig.js'; -import type { AppContext, RouteMatch, AssetsManifest } from './types.js'; import getCurrentRoutePath from './utils/getCurrentRoutePath.js'; interface DocumentContext { @@ -21,7 +21,7 @@ function useDocumentContext() { export const DocumentContextProvider = Context.Provider; -export function Meta(props) { +export function Meta(props: React.MetaHTMLAttributes<HTMLMetaElement>) { const { matches, routesConfig } = useAppContext(); const meta = getMeta(matches, routesConfig); @@ -33,7 +33,7 @@ export function Meta(props) { ); } -export function Title(props) { +export function Title(props: React.HTMLAttributes<HTMLTitleElement>) { const { matches, routesConfig } = useAppContext(); const title = getTitle(matches, routesConfig); @@ -42,7 +42,7 @@ export function Title(props) { ); } -export function Links(props) { +export function Links(props: React.LinkHTMLAttributes<HTMLLinkElement>) { const { routesConfig, matches, assetsManifest } = useAppContext(); const routeLinks = getLinks(matches, routesConfig); @@ -53,9 +53,8 @@ export function Links(props) { return ( <> { - routeLinks.map(link => { - const { block, ...routeLinkProps } = link; - return <link key={link.href} {...props} {...routeLinkProps} data-route-link />; + routeLinks.map(routeLinkProps => { + return <link key={routeLinkProps.href} {...props} {...routeLinkProps} data-route-link />; }) } {styles.map(style => <link key={style} {...props} rel="stylesheet" type="text/css" href={style} />)} @@ -63,7 +62,7 @@ export function Links(props) { ); } -export function Scripts(props) { +export function Scripts(props: React.ScriptHTMLAttributes<HTMLScriptElement>) { const { routesData, routesConfig, matches, assetsManifest, documentOnly, routeModules, basename } = useAppContext(); const appData = useAppData(); @@ -103,9 +102,8 @@ export function Scripts(props) { dangerouslySetInnerHTML={{ __html: `window.__ICE_APP_CONTEXT__=Object.assign(${JSON.stringify(appContext)}, window.__ICE_APP_CONTEXT__ || {})` }} /> { - routeScripts.map(script => { - const { block, ...routeScriptProps } = script; - return <script key={script.src} {...props} {...routeScriptProps} data-route-script />; + routeScripts.map(routeScriptProps => { + return <script key={routeScriptProps.src} {...props} {...routeScriptProps} data-route-script />; }) } { @@ -131,7 +129,7 @@ export function Data() { ); } -export function Main(props) { +export function Main(props: React.HTMLAttributes<HTMLDivElement>) { const { main } = useDocumentContext(); const { appConfig } = useAppContext(); return ( diff --git a/packages/runtime/src/RouteContext.ts b/packages/runtime/src/RouteContext.ts index 275f1c52e..d2de8c174 100644 --- a/packages/runtime/src/RouteContext.ts +++ b/packages/runtime/src/RouteContext.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import type { RouteData, RouteConfig } from './types.js'; +import type { RouteData, RouteConfig } from '@ice/types'; const DataContext = React.createContext<RouteData | undefined>(undefined); DataContext.displayName = 'Data'; diff --git a/packages/runtime/src/RouteWrapper.tsx b/packages/runtime/src/RouteWrapper.tsx index c4e20767d..451cdb532 100644 --- a/packages/runtime/src/RouteWrapper.tsx +++ b/packages/runtime/src/RouteWrapper.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import type { RouteWrapperConfig } from './types.js'; +import type { RouteWrapperConfig } from '@ice/types'; import { useAppContext } from './AppContext.js'; import { DataProvider, ConfigProvider } from './RouteContext.js'; @@ -36,4 +36,4 @@ export default function RouteWrapper(props: Props) { </ConfigProvider> </DataProvider> ); -} \ No newline at end of file +} diff --git a/packages/runtime/src/appConfig.ts b/packages/runtime/src/appConfig.ts index dbce91fff..cdd11c1cf 100644 --- a/packages/runtime/src/appConfig.ts +++ b/packages/runtime/src/appConfig.ts @@ -1,4 +1,4 @@ -import type { AppConfig, AppExport } from './types.js'; +import type { AppConfig, AppExport } from '@ice/types'; const defaultAppConfig: AppConfig = { app: { @@ -18,11 +18,11 @@ export default function getAppConfig(appExport: AppExport): AppConfig { return { app: { ...defaultAppConfig.app, - ...(appConfig.app || {}), + ...(app || {}), }, router: { ...defaultAppConfig.router, - ...(appConfig.router || {}), + ...(router || {}), }, ...others, }; diff --git a/packages/runtime/src/dataLoader.ts b/packages/runtime/src/dataLoader.ts index 9a00a3238..7e33b10cf 100644 --- a/packages/runtime/src/dataLoader.ts +++ b/packages/runtime/src/dataLoader.ts @@ -1,4 +1,4 @@ -import type { GetData } from './types.js'; +import type { GetData } from '@ice/types'; import getRequestContext from './requestContext.js'; interface Loaders { diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts index 1ce3e167b..bcbf01e79 100644 --- a/packages/runtime/src/index.ts +++ b/packages/runtime/src/index.ts @@ -5,6 +5,18 @@ import { useSearchParams, useLocation, } from 'react-router-dom'; +import type { + RuntimePlugin, + AppContext, + AppConfig, + RouteConfig, + RouteItem, + ServerContext, + AppProvider, + RouteWrapper, + RenderMode, + GetAppData, +} from '@ice/types'; import Runtime from './runtime.js'; import App from './App.js'; import runClientApp from './runClientApp.js'; @@ -19,18 +31,6 @@ import { Main, Data, } from './Document.js'; -import type { - RuntimePlugin, - AppContext, - AppConfig, - RouteConfig, - RouteItem, - ServerContext, - AppProvider, - RouteWrapper, - RenderMode, - GetAppData, -} from './types.js'; import dataLoader from './dataLoader.js'; import getAppConfig, { defineAppConfig } from './appConfig.js'; import { routerHistory as history } from './history.js'; @@ -72,4 +72,4 @@ export type { RouteWrapper, RenderMode, GetAppData, -}; \ No newline at end of file +}; diff --git a/packages/runtime/src/matchRoutes.ts b/packages/runtime/src/matchRoutes.ts index d2715ef3d..e33ef9252 100644 --- a/packages/runtime/src/matchRoutes.ts +++ b/packages/runtime/src/matchRoutes.ts @@ -4,8 +4,8 @@ import type { Location } from 'history'; import type { RouteObject } from 'react-router-dom'; import { matchRoutes as originMatchRoutes } from 'react-router-dom'; +import type { RouteItem, RouteMatch } from '@ice/types'; import { matchRoutes as matchRoutesSingle } from './single-router.js'; -import type { RouteItem, RouteMatch } from './types.js'; export default function matchRoutes( routes: RouteItem[], @@ -15,7 +15,6 @@ export default function matchRoutes( const matchRoutesFn = process.env.ICE_CORE_ROUTER === 'true' ? originMatchRoutes : matchRoutesSingle; let matches = matchRoutesFn(routes as unknown as RouteObject[], location, basename); if (!matches) return []; - return matches.map(({ params, pathname, pathnameBase, route }) => ({ params, pathname, diff --git a/packages/runtime/src/requestContext.ts b/packages/runtime/src/requestContext.ts index 074df0dfc..f581ebab8 100644 --- a/packages/runtime/src/requestContext.ts +++ b/packages/runtime/src/requestContext.ts @@ -1,4 +1,4 @@ -import type { ServerContext, RequestContext } from './types.js'; +import type { ServerContext, RequestContext } from '@ice/types'; interface Location { pathname: string; @@ -49,4 +49,4 @@ function parseSearch(search: string) { } return result; -} \ No newline at end of file +} diff --git a/packages/runtime/src/routes.tsx b/packages/runtime/src/routes.tsx index e1c343713..b9e4c35ba 100644 --- a/packages/runtime/src/routes.tsx +++ b/packages/runtime/src/routes.tsx @@ -1,6 +1,6 @@ import React from 'react'; +import type { RouteItem, RouteModules, RouteWrapperConfig, RouteMatch, RequestContext, RoutesConfig, RoutesData, RenderMode } from '@ice/types'; import RouteWrapper from './RouteWrapper.js'; -import type { RouteItem, RouteModules, RouteWrapperConfig, RouteMatch, RequestContext, RoutesConfig, RoutesData, RenderMode } from './types.js'; import { useAppContext } from './AppContext.js'; type RouteModule = Pick<RouteItem, 'id' | 'load'>; @@ -147,7 +147,7 @@ export function createRouteElements( }); } -function RouteComponent({ id }: { id: string }) { +export function RouteComponent({ id }: { id: string }) { // get current route component from latest routeModules const { routeModules } = useAppContext(); const { default: Component } = routeModules[id] || {}; @@ -169,7 +169,6 @@ export function filterMatchesToLoad(prevMatches: RouteMatch[], currentMatches: R let isNew = (match: RouteMatch, index: number) => { // [a] -> [a, b] if (!prevMatches[index]) return true; - // [a, b] -> [a, c] return match.route.id !== prevMatches[index].route.id; }; diff --git a/packages/runtime/src/routesConfig.ts b/packages/runtime/src/routesConfig.ts index 69faeb0b9..106cd11cc 100644 --- a/packages/runtime/src/routesConfig.ts +++ b/packages/runtime/src/routesConfig.ts @@ -1,14 +1,23 @@ -import type { RouteMatch, RoutesConfig, RouteConfig } from './types.js'; +import type { RouteMatch, RoutesConfig, RouteConfig } from '@ice/types'; -export function getMeta(matches: RouteMatch[], routesConfig: RoutesConfig) { +export function getMeta( + matches: RouteMatch[], + routesConfig: RoutesConfig, +): React.MetaHTMLAttributes<HTMLMetaElement>[] { return getMergedValue('meta', matches, routesConfig) || []; } -export function getLinks(matches: RouteMatch[], routesConfig: RoutesConfig) { +export function getLinks( + matches: RouteMatch[], + routesConfig: RoutesConfig, +): React.LinkHTMLAttributes<HTMLLinkElement>[] { return getMergedValue('links', matches, routesConfig) || []; } -export function getScripts(matches: RouteMatch[], routesConfig: RoutesConfig) { +export function getScripts( + matches: RouteMatch[], + routesConfig: RoutesConfig, +): React.ScriptHTMLAttributes<HTMLScriptElement>[] { return getMergedValue('scripts', matches, routesConfig) || []; } @@ -164,4 +173,4 @@ async function appendTags(type: string, props: ElementProps) { document.head.appendChild(tag); }); -} \ No newline at end of file +} diff --git a/packages/runtime/src/runClientApp.tsx b/packages/runtime/src/runClientApp.tsx index 5350d8a04..7a9a3f3b2 100644 --- a/packages/runtime/src/runClientApp.tsx +++ b/packages/runtime/src/runClientApp.tsx @@ -2,16 +2,16 @@ import React, { useLayoutEffect, useState } from 'react'; import * as ReactDOM from 'react-dom/client'; import { createHashHistory, createBrowserHistory, createMemoryHistory } from 'history'; import type { HashHistory, BrowserHistory, Action, Location, InitialEntry, MemoryHistory } from 'history'; +import type { + AppContext, AppExport, RouteItem, AppRouterProps, RoutesData, RoutesConfig, + RouteWrapperConfig, RuntimeModules, RouteMatch, RouteModules, AppConfig, +} from '@ice/types'; import { createHistory as createHistorySingle } from './single-router.js'; import { setHistory } from './history.js'; import Runtime from './runtime.js'; import App from './App.js'; import { AppContextProvider } from './AppContext.js'; import { AppDataProvider, getAppData } from './AppData.js'; -import type { - AppContext, AppExport, RouteItem, AppRouterProps, RoutesData, RoutesConfig, - RouteWrapperConfig, RuntimeModules, RouteMatch, RouteModules, AppConfig, DocumentComponent, -} from './types.js'; import { loadRouteModules, loadRoutesData, getRoutesConfig, filterMatchesToLoad } from './routes.js'; import { updateRoutesConfig } from './routesConfig.js'; import getRequestContext from './requestContext.js'; @@ -22,7 +22,6 @@ interface RunClientAppOptions { app: AppExport; routes: RouteItem[]; runtimeModules: RuntimeModules; - Document: DocumentComponent; hydrate: boolean; basename?: string; memoryRouter?: boolean; @@ -35,7 +34,6 @@ export default async function runClientApp(options: RunClientAppOptions) { app, routes, runtimeModules, - Document, basename, hydrate, memoryRouter, @@ -71,7 +69,7 @@ export default async function runClientApp(options: RunClientAppOptions) { routesData = await loadRoutesData(matches, requestContext, routeModules); } if (!routesConfig) { - routesConfig = getRoutesConfig(matches, routesConfig, routeModules); + routesConfig = getRoutesConfig(matches, routesData, routeModules); } const appContext: AppContext = { @@ -98,15 +96,14 @@ export default async function runClientApp(options: RunClientAppOptions) { await Promise.all(runtimeModules.map(m => runtime.loadModule(m)).filter(Boolean)); - render({ runtime, Document, history }); + render({ runtime, history }); } interface RenderOptions { history: History; runtime: Runtime; - Document: DocumentComponent; } -async function render({ history, runtime, Document }: RenderOptions) { +async function render({ history, runtime }: RenderOptions) { const appContext = runtime.getAppContext(); const { appConfig } = appContext; const render = runtime.getRender(); @@ -114,7 +111,6 @@ async function render({ history, runtime, Document }: RenderOptions) { const RouteWrappers = runtime.getWrappers(); const AppRouter = runtime.getAppRouter(); - render( document.getElementById(appConfig.app.rootId), <BrowserEntry @@ -123,7 +119,6 @@ async function render({ history, runtime, Document }: RenderOptions) { AppProvider={AppProvider} RouteWrappers={RouteWrappers} AppRouter={AppRouter} - Document={Document} />, ); } @@ -134,7 +129,6 @@ interface BrowserEntryProps { AppProvider: React.ComponentType<any>; RouteWrappers: RouteWrapperConfig[]; AppRouter: React.ComponentType<AppRouterProps>; - Document: DocumentComponent; } interface HistoryState { @@ -152,7 +146,6 @@ interface RouteState { function BrowserEntry({ history, appContext, - Document, ...rest }: BrowserEntryProps) { const { @@ -232,7 +225,7 @@ function BrowserEntry({ * Prepare for the next pages. * Load modules、getPageData and preLoad the custom assets. */ -async function loadNextPage( +export async function loadNextPage( currentMatches: RouteMatch[], preRouteState: RouteState, ) { @@ -302,4 +295,4 @@ function createRouterHistory(type: AppConfig['router']['type'], memoryRouter: bo if (type === 'hash') { return createHashHistory; } -} \ No newline at end of file +} diff --git a/packages/runtime/src/runServerApp.tsx b/packages/runtime/src/runServerApp.tsx index 7564878e6..b00e5d1a1 100644 --- a/packages/runtime/src/runServerApp.tsx +++ b/packages/runtime/src/runServerApp.tsx @@ -3,17 +3,6 @@ import * as React from 'react'; import * as ReactDOMServer from 'react-dom/server'; import { Action, parsePath } from 'history'; import type { Location } from 'history'; -import { default as consola } from 'consola'; -import Runtime from './runtime.js'; -import App from './App.js'; -import { AppContextProvider } from './AppContext.js'; -import { AppDataProvider, getAppData } from './AppData.js'; -import getAppConfig from './appConfig.js'; -import { DocumentContextProvider } from './Document.js'; -import { loadRouteModules, loadRoutesData, getRoutesConfig } from './routes.js'; -import { piperToString, renderToNodeStream } from './server/streamRender.js'; -import { createStaticNavigator } from './server/navigator.js'; -import type { NodeWritablePiper } from './server/streamRender.js'; import type { AppContext, RouteItem, ServerContext, AppData, @@ -24,7 +13,17 @@ import type { RouteModules, RenderMode, DocumentComponent, -} from './types.js'; +} from '@ice/types'; +import Runtime from './runtime.js'; +import App from './App.js'; +import { AppContextProvider } from './AppContext.js'; +import { AppDataProvider, getAppData } from './AppData.js'; +import getAppConfig from './appConfig.js'; +import { DocumentContextProvider } from './Document.js'; +import { loadRouteModules, loadRoutesData, getRoutesConfig } from './routes.js'; +import { piperToString, renderToNodeStream } from './server/streamRender.js'; +import { createStaticNavigator } from './server/navigator.js'; +import type { NodeWritablePiper } from './server/streamRender.js'; import getRequestContext from './requestContext.js'; import matchRoutes from './matchRoutes.js'; import getCurrentRoutePath from './utils/getCurrentRoutePath.js'; @@ -79,7 +78,7 @@ export async function renderToHTML(requestContext: ServerContext, renderOptions: if (renderOptions.disableFallback) { throw error; } - consola.error('PiperToString error, downgrade to CSR.', error); + console.error('PiperToString error, downgrade to CSR.', error); // downgrade to CSR. const result = fallback(); return result; @@ -109,7 +108,7 @@ export async function renderToResponse(requestContext: ServerContext, renderOpti if (renderOptions.disableFallback) { throw error; } - consola.error('PiperToResponse error, downgrade to CSR.', error); + console.error('PiperToResponse error, downgrade to CSR.', error); // downgrade to CSR. const result = await fallback(); sendResult(res, result); @@ -185,7 +184,7 @@ async function doRender(serverContext: ServerContext, renderOptions: RenderOptio if (disableFallback) { throw err; } - consola.error('Warning: render server entry error, downgrade to csr.', err); + console.error('Warning: render server entry error, downgrade to csr.', err); return renderDocument({ matches, routePath, renderOptions, routeModules: {} }); } } diff --git a/packages/runtime/src/runtime.tsx b/packages/runtime/src/runtime.tsx index f1e8902a0..3199e8c59 100644 --- a/packages/runtime/src/runtime.tsx +++ b/packages/runtime/src/runtime.tsx @@ -14,7 +14,7 @@ import type { SetRender, AppRouterProps, ComponentWithChildren, -} from './types.js'; +} from '@ice/types'; import DefaultAppRouter from './AppRouter.js'; import { useData, useConfig } from './RouteContext.js'; import { useAppContext } from './AppContext.js'; @@ -103,4 +103,4 @@ class Runtime { }; } -export default Runtime; \ No newline at end of file +export default Runtime; diff --git a/packages/runtime/src/types.ts b/packages/runtime/src/types.ts deleted file mode 100644 index 117148f8b..000000000 --- a/packages/runtime/src/types.ts +++ /dev/null @@ -1,208 +0,0 @@ -import type { IncomingMessage, ServerResponse } from 'http'; -import type { Action, InitialEntry, Location } from 'history'; -import type { ComponentType, ReactNode, PropsWithChildren } from 'react'; -import type { HydrationOptions } from 'react-dom/client'; -import type { Navigator, Params } from 'react-router-dom'; -import type { useConfig, useData } from './RouteContext.js'; -import type { useAppContext } from './AppContext.js'; - -type VoidFunction = () => void; -type AppLifecycle = 'onShow' | 'onHide' | 'onPageNotFound' | 'onShareAppMessage' | 'onUnhandledRejection' | 'onLaunch' | 'onError' | 'onTabItemClick'; -type App = Partial<{ - rootId: string; - strict: boolean; - errorBoundary: boolean; -} & Record<AppLifecycle, VoidFunction>>; - -export type AppData = any; -export type RouteData = any; - -// route.getConfig return value -export interface RouteConfig { - title?: string; - // TODO: fix type - meta?: any[]; - links?: any[]; - scripts?: any[]; - - // plugin extends - auth?: string[]; -} - -export interface AppExport { - default?: AppConfig; - [key: string]: any; - getAppData?: GetAppData; -} - -export type GetAppData = (ctx: RequestContext) => Promise<AppData> | AppData; - -// app.getData & route.getData -export type GetData = (ctx: RequestContext) => Promise<RouteData> | RouteData; -export type GetServerData = (ctx: RequestContext) => Promise<RouteData> | RouteData; -export type GetStaticData = (ctx: RequestContext) => Promise<RouteData> | RouteData; -// route.getConfig -export type GetConfig = (args: { data: RouteData }) => RouteConfig; - -export interface AppConfig { - app?: App; - router?: { - type?: 'hash' | 'browser' | 'memory'; - basename?: string; - initialEntries?: InitialEntry[]; - }; -} - -export interface RoutesConfig { - [routeId: string]: RouteConfig; -} - -export interface RoutesData { - [routeId: string]: RouteData; -} - -// useAppContext -export interface AppContext { - appConfig: AppConfig; - appData: any; - assetsManifest: AssetsManifest; - routesData: RoutesData; - routesConfig: RoutesConfig; - routeModules: RouteModules; - routePath?: string; - matches?: RouteMatch[]; - routes?: RouteItem[]; - documentOnly?: boolean; - matchedIds?: string[]; - appExport?: AppExport; - basename?: string; -} - -export type Renderer = ( - container: Element | Document, - initialChildren: React.ReactNode, - options?: HydrationOptions, -) => void; - -export interface ServerContext { - req?: IncomingMessage; - res?: ServerResponse; -} - -export interface RequestContext extends ServerContext { - pathname: string; - query: Record<string, any>; -} - -export interface RouteComponent { - default: ComponentType<any>; - getStaticData?: GetStaticData; - getServerData?: GetServerData; - getData?: GetData; - getConfig?: GetConfig; - [key: string]: any; -} - -export interface RouteItem { - id: string; - path: string; - element?: ReactNode; - componentName: string; - index?: boolean; - exact?: boolean; - strict?: boolean; - load?: () => Promise<RouteComponent>; - children?: RouteItem[]; - layout?: boolean; -} - -export type ComponentWithChildren<P = {}> = ComponentType<PropsWithChildren<P>>; - -export type DocumentComponent = ComponentWithChildren<{ - pagePath: string; -}>; - -export interface RouteWrapperConfig { - Wrapper: RouteWrapper; - layout?: boolean; -} - -export type AppProvider = ComponentWithChildren<any>; -export type RouteWrapper = ComponentType<any>; - -export type SetAppRouter = (AppRouter: ComponentType<AppRouterProps>) => void; -export type AddProvider = (Provider: AppProvider) => void; -export type SetRender = (render: Renderer) => void; -export type AddWrapper = (wrapper: RouteWrapper, forLayout?: boolean) => void; - -export interface RouteModules { - [routeId: string]: RouteComponent; -} - -export interface AssetsManifest { - dataLoader?: string; - publicPath: string; - entries: string[]; - pages: string[]; - assets?: { - [assetPath: string]: string; - }; -} - -export interface RuntimeAPI { - setAppRouter: SetAppRouter; - addProvider: AddProvider; - setRender: SetRender; - addWrapper: AddWrapper; - appContext: AppContext; - useData: typeof useData; - useConfig: typeof useConfig; - useAppContext: typeof useAppContext; -} - -export interface RuntimePlugin { - ( - apis: RuntimeAPI - ): Promise<void> | void; -} - -export interface CommonJsRuntime { - default: RuntimePlugin; -} - -export type RuntimeModules = (RuntimePlugin | CommonJsRuntime)[]; - -export interface AppRouterProps { - action: Action; - location: Location; - navigator: Navigator; - routes: RouteItem[]; - static?: boolean; - basename?: string; -} - -export interface AppRouteProps { - routes: RouteItem[]; -} - -// rewrite the `RouteMatch` type which is referenced by the react-router-dom -export interface RouteMatch { - /** - * The names and values of dynamic parameters in the URL. - */ - params: Params; - /** - * The portion of the URL pathname that was matched. - */ - pathname: string; - /** - * The portion of the URL pathname that was matched before child routes. - */ - pathnameBase: string; - /** - * The route object that was used to match. - */ - route: RouteItem; -} - -export type RenderMode = 'SSR' | 'SSG'; \ No newline at end of file diff --git a/packages/runtime/src/utils/getCurrentRoutePath.ts b/packages/runtime/src/utils/getCurrentRoutePath.ts index 61d949c18..80bcdb413 100644 --- a/packages/runtime/src/utils/getCurrentRoutePath.ts +++ b/packages/runtime/src/utils/getCurrentRoutePath.ts @@ -1,4 +1,4 @@ -import type { RouteMatch } from '../types.js'; +import type { RouteMatch } from '@ice/types'; /** * Get the current route path exclude the basename. diff --git a/packages/runtime/tests/appConfig.test.ts b/packages/runtime/tests/appConfig.test.ts index 0f1833da1..bc3c9daee 100644 --- a/packages/runtime/tests/appConfig.test.ts +++ b/packages/runtime/tests/appConfig.test.ts @@ -1,13 +1,33 @@ -import { expect, test, describe } from 'vitest'; -import { defineAppConfig } from '../src/appConfig.js'; +import { expect, it, describe } from 'vitest'; +import getAppConfig, { defineAppConfig } from '../src/appConfig.js'; describe('AppConfig', () => { - test('defineAppConfig', () => { + it('getAppConfig', () => { + const appConfig = getAppConfig({ + default: { + app: { + rootId: 'app', + }, + }, + auth: {}, + }); + expect(appConfig).toStrictEqual({ + app: { + rootId: 'app', + strict: false, + }, + router: { + type: 'browser', + }, + }); + }); + + it('defineAppConfig', () => { const appConfig = {}; expect(defineAppConfig(appConfig)).toEqual(appConfig); }); - test('defineAppConfig fn', () => { + it('defineAppConfig fn', () => { const appConfig = {}; expect(defineAppConfig(() => appConfig)).toEqual(appConfig); }); diff --git a/packages/runtime/tests/navigator.test.ts b/packages/runtime/tests/navigator.test.ts new file mode 100644 index 000000000..d7625168c --- /dev/null +++ b/packages/runtime/tests/navigator.test.ts @@ -0,0 +1,33 @@ +import { expect, it, describe } from 'vitest'; +import { createStaticNavigator } from '../src/server/navigator'; + +describe('mock server navigator', () => { + const staticNavigator = createStaticNavigator(); + it('createHref', () => { + expect(staticNavigator.createHref('/')).toBe('/'); + }); + + it('push', () => { + expect(() => staticNavigator.push('/')).toThrow(); + }); + + it('replace', () => { + expect(() => staticNavigator.replace('/')).toThrow(); + }); + + it('go', () => { + expect(() => staticNavigator.go(1)).toThrow(); + }); + + it('back', () => { + expect(() => staticNavigator.back()).toThrow(); + }); + + it('forward', () => { + expect(() => staticNavigator.forward()).toThrow(); + }); + + it('block', () => { + expect(() => staticNavigator.block()).toThrow(); + }); +}); \ No newline at end of file diff --git a/packages/runtime/tests/routes.test.ts b/packages/runtime/tests/routes.test.ts deleted file mode 100644 index cf8792d8a..000000000 --- a/packages/runtime/tests/routes.test.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { expect, test, describe } from 'vitest'; -import { filterMatchesToLoad } from '../src/routes.js'; - -describe('routes', () => { - test('filter new matches', () => { - const oldMatches = [ - { - pathname: '/', - route: { - id: '/page/layout' - } - }, - { - pathname: '/', - route: { - id: '/page/home' - } - } - ]; - - const newMatches = [ - { - pathname: '/', - route: { - id: '/page/layout' - } - }, - { - pathname: '/about', - route: { - id: '/page/about' - } - } - ]; - - // @ts-ignore - const matches = filterMatchesToLoad(oldMatches, newMatches); - - expect( - matches - ).toEqual([{ - pathname: '/about', - route: { - id: '/page/about' - } - }]); - }); - - test('filter matches with path changed', () => { - const oldMatches = [ - { - pathname: '/users/123', - route: { - id: '/users/123' - } - } - ]; - - const newMatches = [ - { - pathname: '/users/456', - route: { - id: '/users/456' - } - } - ]; - - // @ts-ignore - const matches = filterMatchesToLoad(oldMatches, newMatches); - - expect( - matches - ).toEqual([ - { - pathname: '/users/456', - route: { - id: '/users/456' - } - } - ]); - }); -}); diff --git a/packages/runtime/tests/routes.test.tsx b/packages/runtime/tests/routes.test.tsx new file mode 100644 index 000000000..3a6fcc477 --- /dev/null +++ b/packages/runtime/tests/routes.test.tsx @@ -0,0 +1,322 @@ +import React from 'react'; +import { renderToString } from 'react-dom/server'; +import { expect, it, describe, beforeEach, afterEach, vi } from 'vitest'; +import type { RouteComponent as IRouteComponent } from '@ice/types/esm/runtime'; +import RouteWrapper from '../src/RouteWrapper'; +import { AppContextProvider } from '../src/AppContext'; +import { + filterMatchesToLoad, + createRouteElements, + RouteComponent, + loadRouteModules, + loadRoutesData, + getRoutesConfig, +} from '../src/routes.js'; + +describe('routes', () => { + let windowSpy; + beforeEach(() => { + windowSpy = vi.spyOn(global, 'window', 'get'); + }); + + afterEach(() => { + windowSpy.mockRestore(); + }); + + Object.defineProperty(window, 'open', open); + const homeItem = { + default: () => <></>, + getConfig: () => ({ title: 'home' }), + getData: async () => ({ type: 'getData' }), + getServerData: async () => ({ type: 'getServerData' }), + getStaticData: async () => ({ type: 'getStaticData' }), + }; + const aboutItem = { + default: () => <></>, + getConfig: () => ({ title: 'about' }), + }; + const routeModules = [ + { + id: 'home', + load: async () => { + return homeItem as IRouteComponent; + }, + }, + { + id: 'about', + load: async () => { + return aboutItem as IRouteComponent; + }, + }, + ]; + + it('route Component', () => { + const domstring = renderToString( + // @ts-ignore + <AppContextProvider value={{ routeModules: { + home: { + default: () => <div>home</div>, + }, + } }} + > + <RouteComponent id="home" /> + </AppContextProvider>, + ); + expect(domstring).toBe('<div>home</div>'); + }); + + it('route error', () => { + const currentEnv = process.env.NODE_ENV; + process.env.NODE_ENV = 'development'; + expect(() => renderToString( + // @ts-ignore + <AppContextProvider value={{ routeModules: {} }}> + <RouteComponent id="home" /> + </AppContextProvider>, + )).toThrow(); + process.env.NODE_ENV = currentEnv; + }); + + it('load route modules', async () => { + windowSpy.mockImplementation(() => ({})); + const routeModule = await loadRouteModules(routeModules, { home: homeItem }); + expect(routeModule).toStrictEqual({ + home: homeItem, + about: aboutItem, + }); + }); + + it('load error module', async () => { + const routeModule = await loadRouteModules([{ + id: 'error', + // @ts-ignore + load: async () => { + throw new Error('err'); + return {}; + }, + }], {}); + expect(routeModule).toStrictEqual({ + error: undefined, + }); + }); + + it('load route data', async () => { + const routeModule = await loadRouteModules(routeModules); + const routesDataSSG = await loadRoutesData( + // @ts-ignore + [{ route: routeModules[0] }], + {}, + routeModule, + 'SSG', + ); + const routesDataSSR = await loadRoutesData( + // @ts-ignore + [{ route: routeModules[0] }], + {}, + routeModule, + 'SSR', + ); + const routesDataCSR = await loadRoutesData( + // @ts-ignore + [{ route: routeModules[0] }], + {}, + routeModule, + 'CSR', + ); + expect(routesDataSSG).toStrictEqual({ + home: { + type: 'getStaticData', + }, + }); + expect(routesDataSSR).toStrictEqual({ + home: { + type: 'getServerData', + }, + }); + expect(routesDataCSR).toStrictEqual({ + home: { + type: 'getData', + }, + }); + }); + + it('load data from __ICE_DATA_LOADER__', async () => { + windowSpy.mockImplementation(() => ({ + __ICE_DATA_LOADER__: async (id) => ({ id: `${id}_data` }), + })); + const routesData = await loadRoutesData( + // @ts-ignore + [{ route: routeModules[0] }], + {}, + {}, + 'SSG', + ); + expect(routesData).toStrictEqual({ + home: { + id: 'home_data', + }, + }); + }); + + it('get routes config', async () => { + const routeModule = await loadRouteModules(routeModules); + const routesConfig = getRoutesConfig( + // @ts-ignore + [{ route: routeModules[0] }], + { home: {} }, + routeModule, + ); + expect(routesConfig).toStrictEqual({ + home: { + title: 'home', + }, + }); + }); + + it('get routes config when failed get route module', async () => { + const routesConfig = getRoutesConfig( + // @ts-ignore + [{ route: routeModules[0] }], + { home: {} }, + {}, + ); + expect(routesConfig).toStrictEqual({ + home: {}, + }); + }); + + it('create route element', () => { + const routeElement = createRouteElements([{ + path: '/', + id: 'home', + componentName: 'home', + }]); + expect(routeElement).toEqual([{ + componentName: 'home', + element: ( + <RouteWrapper id="home"> + <RouteComponent + id="home" + /> + </RouteWrapper> + ), + id: 'home', + path: '/', + }]); + }); + + it('create route with children', () => { + const routeElement = createRouteElements([{ + path: '/', + id: 'home', + componentName: 'home', + children: [{ + path: '/about', + id: 'about', + componentName: 'about', + }], + }]); + expect(routeElement).toEqual([{ + componentName: 'home', + element: ( + <RouteWrapper id="home"> + <RouteComponent + id="home" + /> + </RouteWrapper> + ), + children: [{ + componentName: 'about', + element: ( + <RouteWrapper id="about"> + <RouteComponent + id="about" + /> + </RouteWrapper> + ), + id: 'about', + path: '/about', + }], + id: 'home', + path: '/', + }]); + }); + + it('filter new matches', () => { + const oldMatches = [ + { + pathname: '/', + route: { + id: '/page/layout', + }, + }, + { + pathname: '/', + route: { + id: '/page/home', + }, + }, + ]; + + const newMatches = [ + { + pathname: '/', + route: { + id: '/page/layout', + }, + }, + { + pathname: '/about', + route: { + id: '/page/about', + }, + }, + ]; + + // @ts-ignore + const matches = filterMatchesToLoad(oldMatches, newMatches); + + expect( + matches, + ).toEqual([{ + pathname: '/about', + route: { + id: '/page/about', + }, + }]); + }); + + it('filter matches with path changed', () => { + const oldMatches = [ + { + pathname: '/users/123', + route: { + id: '/users/123', + }, + }, + ]; + + const newMatches = [ + { + pathname: '/users/456', + route: { + id: '/users/456', + }, + }, + ]; + + // @ts-ignore + const matches = filterMatchesToLoad(oldMatches, newMatches); + + expect( + matches, + ).toEqual([ + { + pathname: '/users/456', + route: { + id: '/users/456', + }, + }, + ]); + }); +}); diff --git a/packages/runtime/tests/routesConfig.test.ts b/packages/runtime/tests/routesConfig.test.ts new file mode 100644 index 000000000..5b87a7be2 --- /dev/null +++ b/packages/runtime/tests/routesConfig.test.ts @@ -0,0 +1,69 @@ +import { expect, it, vi, describe, beforeEach, afterEach } from 'vitest'; + +import { updateRoutesConfig } from '../src/routesConfig'; + +describe('routes config', () => { + let documentSpy; + const insertTags: any[] = []; + const appendTags: any[] = []; + + beforeEach(() => { + documentSpy = vi.spyOn(global, 'document', 'get'); + documentSpy.mockImplementation(() => ({ + head: { + querySelector: () => ({ + content: '', + }), + insertBefore: (tag) => { + insertTags.push(tag); + }, + appendChild: (tag) => { + appendTags.push(tag); + tag.onload(); + }, + }, + getElementById: () => null, + querySelectorAll: () => [], + createElement: (type) => { + const element = { + type, + setAttribute: (attr, value) => { + element[attr] = value; + }, + }; + return element; + }, + })); + }); + afterEach(() => { + documentSpy.mockRestore(); + }); + + it('update routes config', async () => { + const routesConfig = { + home: { + title: 'home', + meta: [ + { + name: 'theme-color', + content: '#eee', + }, + ], + links: [{ + href: 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css', + rel: 'stylesheet', + }], + scripts: [{ + src: 'https://cdn.jsdelivr.net/npm/lodash@2.4.1/dist/lodash.min.js', + }], + }, + }; + // @ts-ignore + await updateRoutesConfig([{ route: { id: 'home' } }], routesConfig); + expect(insertTags.length).toBe(1); + expect(insertTags[0]?.type).toBe('meta'); + expect(appendTags.length).toBe(2); + expect(appendTags[0]?.type).toBe('link'); + expect(appendTags[1]?.type).toBe('script'); + }); +}); \ No newline at end of file diff --git a/packages/runtime/tests/runClientApp.test.tsx b/packages/runtime/tests/runClientApp.test.tsx new file mode 100644 index 000000000..34c8b4565 --- /dev/null +++ b/packages/runtime/tests/runClientApp.test.tsx @@ -0,0 +1,350 @@ +import React from 'react'; +import { renderToString } from 'react-dom/server'; +import { expect, it, vi, describe, beforeEach, afterEach } from 'vitest'; +import runClientApp, { loadNextPage } from '../src/runClientApp'; +import { useAppData } from '../src/AppData'; +import { useConfig, useData } from '../src/RouteContext'; + +describe('run client app', () => { + let windowSpy; + let documentSpy; + const mockData = { + location: new URL('http://localhost:4000/'), + history: { + replaceState: vi.fn(), + }, + addEventListener: vi.fn(), + }; + beforeEach(() => { + process.env.ICE_CORE_ROUTER = 'true'; + windowSpy = vi.spyOn(global, 'window', 'get'); + documentSpy = vi.spyOn(global, 'document', 'get'); + + windowSpy.mockImplementation(() => mockData); + documentSpy.mockImplementation(() => ({ + head: { + querySelector: () => ({ + content: '', + }), + }, + getElementById: () => null, + querySelectorAll: () => [], + })); + }); + afterEach(() => { + windowSpy.mockRestore(); + documentSpy.mockRestore(); + }); + + let domstring = ''; + + const serverRuntime = async ({ setRender }) => { + setRender((container, element) => { + try { + domstring = renderToString(element as any); + } catch (err) {} + }); + }; + + const wrapperRuntime = async ({ addWrapper }) => { + const RouteWrapper = ({ children }) => { + return <div>{children}</div>; + }; + addWrapper(RouteWrapper, true); + }; + + const providerRuntmie = async ({ addProvider }) => { + const Provider = ({ children }) => { + return <div>{children}</div>; + }; + addProvider(Provider); + // Add twice. + addProvider(Provider); + }; + + const basicRoutes = [ + { + id: 'home', + path: '/', + componentName: 'Home', + load: async () => ({ + default: () => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const appData = useAppData(); + return ( + <div>home{appData?.msg || ''}</div> + ); + }, + getConfig: () => ({ title: 'home' }), + getData: async () => ({ data: 'test' }), + }), + }, + ]; + + it('run client basic', async () => { + windowSpy.mockImplementation(() => ({ + ...mockData, + location: new URL('http://localhost:4000/?test=1&runtime=true&baisc'), + })); + + await runClientApp({ + app: {}, + routes: basicRoutes, + runtimeModules: [serverRuntime], + hydrate: false, + }); + expect(domstring).toBe('<div>home</div>'); + }); + + it('run client single-router', async () => { + process.env.ICE_CORE_ROUTER = ''; + await runClientApp({ + app: {}, + routes: basicRoutes, + runtimeModules: [serverRuntime], + hydrate: false, + }); + process.env.ICE_CORE_ROUTER = 'true'; + expect(domstring).toBe('<div>home</div>'); + }); + + it('run client with wrapper', async () => { + await runClientApp({ + app: {}, + routes: basicRoutes, + runtimeModules: [serverRuntime, wrapperRuntime], + hydrate: true, + }); + expect(domstring).toBe('<div><div>home</div></div>'); + }); + + it('run client with app provider', async () => { + await runClientApp({ + app: {}, + routes: basicRoutes, + runtimeModules: [serverRuntime, providerRuntmie], + hydrate: true, + }); + expect(domstring).toBe('<div><div><div>home</div></div></div>'); + }); + + it('run client with empty route', async () => { + await runClientApp({ + app: {}, + routes: [], + runtimeModules: [serverRuntime], + hydrate: false, + }); + }); + + it('run client with memory router', async () => { + const routes = [...basicRoutes, { + id: 'about', + path: '/about', + componentName: 'About', + load: async () => ({ + default: () => { + return ( + <div>about</div> + ); + }, + }), + }]; + await runClientApp({ + app: { + default: { + router: { + type: 'memory', + initialEntries: ['/about'], + }, + }, + }, + routes, + runtimeModules: [serverRuntime], + hydrate: true, + }); + + expect(domstring).toBe('<div>about</div>'); + await runClientApp({ + app: { + default: { + }, + }, + routes, + runtimeModules: [serverRuntime], + hydrate: true, + }); + }); + + it('run client with memory router - from context', async () => { + windowSpy.mockImplementation(() => ({ + ...mockData, + __ICE_APP_CONTEXT__: { + routePath: '/about', + }, + })); + const routes = [...basicRoutes, { + id: 'about', + path: '/about', + componentName: 'About', + load: async () => ({ + default: () => { + return ( + <div>about</div> + ); + }, + }), + }]; + await runClientApp({ + app: { + }, + routes, + runtimeModules: [serverRuntime], + hydrate: true, + memoryRouter: true, + }); + + expect(domstring).toBe('<div>about</div>'); + }); + + it('run client with hash router', async () => { + await runClientApp({ + app: { + default: { + router: { + type: 'hash', + }, + }, + }, + routes: basicRoutes, + runtimeModules: [serverRuntime], + hydrate: true, + }); + expect(domstring).toBe('<div>home</div>'); + }); + + it('run client with app data', async () => { + let executed = false; + await runClientApp({ + app: { + getAppData: async () => { + executed = true; + return { msg: '-getAppData' }; + }, + }, + routes: basicRoutes, + runtimeModules: [serverRuntime], + hydrate: false, + }); + expect(domstring).toBe('<div>home<!-- -->-getAppData</div>'); + expect(executed).toBe(true); + }); + + it('run client with app data', async () => { + let useGlobalLoader = false; + let executed = false; + windowSpy.mockImplementation(() => ({ + ...mockData, + __ICE_DATA_LOADER__: async () => { + useGlobalLoader = true; + return { msg: '-globalData' }; + }, + })); + + await runClientApp({ + app: { + getAppData: async () => { + executed = true; + return { msg: 'app' }; + }, + }, + routes: basicRoutes, + runtimeModules: [serverRuntime], + hydrate: false, + }); + expect(executed).toBe(false); + expect(useGlobalLoader).toBe(true); + expect(domstring).toBe('<div>home<!-- -->-globalData</div>'); + }); + + it('run client with AppErrorBoundary', async () => { + await runClientApp({ + app: { + default: { + app: { + errorBoundary: true, + }, + }, + }, + routes: [{ + id: 'home', + path: '/', + componentName: 'Home', + load: async () => ({ + default: () => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const config = useConfig(); + // eslint-disable-next-line react-hooks/rules-of-hooks + const data = useData(); + return ( + <div>home{data?.data}{config.title}</div> + ); + }, + getConfig: () => ({ title: 'home' }), + getData: async () => ({ data: 'test' }), + }), + }], + runtimeModules: [serverRuntime], + hydrate: false, + }); + expect(domstring).toBe('<div>home<!-- -->test<!-- -->home</div>'); + }); + + it('load next page', async () => { + const homePage = { + default: () => <></>, + getConfig: () => ({ title: 'home' }), + getData: async () => ({ type: 'getDataHome' }), + }; + const aboutPage = { + default: () => <></>, + getConfig: () => ({ title: 'about' }), + getData: async () => ({ type: 'getDataAbout' }), + }; + const mockedModules = [ + { + id: 'home', + load: async () => { + return homePage; + }, + }, + { + id: 'about', + load: async () => { + return aboutPage; + }, + }, + ]; + const { routesData, routesConfig, routeModules } = await loadNextPage( + // @ts-ignore + [{ route: mockedModules[0] }], + { + // @ts-ignore + matches: [{ route: mockedModules[1] }], + routesData: {}, + routeModules: {}, + }, + ); + expect(routesData).toStrictEqual({ + home: { type: 'getDataHome' }, + }); + expect(routesConfig).toStrictEqual({ + home: { + title: 'home', + }, + }); + expect(routeModules).toStrictEqual({ + home: homePage, + }); + }); +}); \ No newline at end of file diff --git a/packages/runtime/tests/runServerApp.test.tsx b/packages/runtime/tests/runServerApp.test.tsx new file mode 100644 index 000000000..ad7eda511 --- /dev/null +++ b/packages/runtime/tests/runServerApp.test.tsx @@ -0,0 +1,212 @@ +import React from 'react'; +import { expect, it, describe } from 'vitest'; +import { renderToHTML, renderToResponse } from '../src/runServerApp'; +import { Meta, Title, Links, Main, Scripts } from '../src/Document'; + +describe('run server app', () => { + process.env.ICE_CORE_ROUTER = 'true'; + const basicRoutes = [ + { + id: 'home', + path: 'home', + componentName: 'Home', + load: async () => ({ + default: () => { + return ( + <div>home</div> + ); + }, + getConfig: () => ({ title: 'home' }), + getData: async () => ({ data: 'test' }), + }), + }, + ]; + + const assetsManifest = { + publicPath: '/', + assets: {}, + entries: [], + pages: { + home: ['js/home.js'], + }, + }; + + const Document = () => ( + <html> + <head> + <meta charSet="utf-8" /> + <meta name="description" content="ICE 3.0 Demo" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <Meta /> + <Title /> + <Links /> + </head> + <body> + <Main /> + <Scripts /> + </body> + </html> + ); + + it('render to html', async () => { + const html = await renderToHTML({ + // @ts-ignore + req: { + url: '/home', + }, + }, { + app: {}, + assetsManifest, + runtimeModules: [], + routes: basicRoutes, + Document, + renderMode: 'SSR', + }); + // @ts-ignore + expect(html?.value?.includes('<div>home</div>')).toBe(true); + // @ts-ignore + expect(html?.value?.includes('js/home.js')).toBe(true); + }); + + it('render to html basename', async () => { + const html = await renderToHTML({ + // @ts-ignore + req: { + url: '/home', + }, + }, { + app: {}, + assetsManifest, + runtimeModules: [], + routes: basicRoutes, + Document, + renderMode: 'SSR', + basename: '/ice', + }); + // @ts-ignore + expect(html?.statusCode).toBe(404); + }); + + it('render to html serverOnlyBasename', async () => { + const html = await renderToHTML({ + // @ts-ignore + req: { + url: '/home', + }, + }, { + app: {}, + assetsManifest, + runtimeModules: [], + routes: basicRoutes, + Document, + renderMode: 'SSR', + serverOnlyBasename: '/', + basename: '/ice', + }); + // @ts-ignore + expect(html?.statusCode).toBe(200); + }); + + it('render to 404 html', async () => { + const html = await renderToHTML({ + // @ts-ignore + req: { + url: '/about', + }, + }, { + app: {}, + assetsManifest, + runtimeModules: [], + routes: basicRoutes, + Document, + }); + // @ts-ignore + expect(html?.statusCode).toBe(404); + }); + + it('router hash', async () => { + const html = await renderToHTML({ + // @ts-ignore + req: { + url: '/home', + }, + }, { + app: { + default: { + router: { + type: 'hash', + }, + }, + }, + assetsManifest, + runtimeModules: [], + routes: basicRoutes, + Document, + }); + // @ts-ignore + expect(html?.statusCode).toBe(200); + // @ts-ignore + expect(html?.value?.includes('<div>home</div>')).toBe(false); + }); + + it('fallback to csr', async () => { + const html = await renderToHTML({ + // @ts-ignore + req: { + url: '/home', + }, + }, { + app: {}, + assetsManifest, + runtimeModules: [], + routes: [{ + id: 'home', + path: 'home', + componentName: 'Home', + load: async () => ({ + default: () => { + throw new Error('err'); + return ( + <div>home</div> + ); + }, + }), + }], + Document, + }); + // @ts-ignore + expect(html?.value?.includes('<div>home</div>')).toBe(false); + // @ts-ignore + expect(html?.value?.includes('js/home.js')).toBe(true); + }); + + it('render to response', async () => { + let htmlContent = ''; + await renderToResponse({ + // @ts-ignore + req: { + url: '/home', + }, + res: { + destination: {}, + // @ts-ignore + setHeader: () => {}, + // @ts-ignore + end: (content) => { + htmlContent = content; + }, + }, + }, { + app: {}, + assetsManifest, + runtimeModules: [], + routes: basicRoutes, + Document, + renderMode: 'SSR', + routePath: '/', + documentOnly: true, + }); + expect(!!htmlContent).toBe(true); + expect(htmlContent.includes('<div>home</div')).toBe(false); + }); +}); \ No newline at end of file diff --git a/packages/runtime/tests/singleRoute.test.tsx b/packages/runtime/tests/singleRoute.test.tsx new file mode 100644 index 000000000..facb795d8 --- /dev/null +++ b/packages/runtime/tests/singleRoute.test.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import { expect, it, describe } from 'vitest'; + +import { + useRoutes, + Router, + createHistory, + matchRoutes, + Link, + Outlet, + useParams, + useSearchParams, + useLocation, + useNavigate, +} from '../src/single-router'; + +describe('single route api', () => { + it('useRoutes', () => { + expect(useRoutes([{ element: <div>test</div> }])).toStrictEqual( + <React.Fragment> + <div> + test + </div> + </React.Fragment>); + }); + + it('Router', () => { + expect(Router({ children: <div>test</div> })).toStrictEqual( + <React.Fragment> + <div> + test + </div> + </React.Fragment>); + }); + + it('createHistory', () => { + expect(createHistory().location).toBe(''); + }); + + it('matchRoutes', () => { + expect(matchRoutes([{}])[0].pathname).toBe(''); + }); + + it('Link', () => { + expect(Link()).toBe(null); + }); + + it('Outlet', () => { + expect(Outlet()).toStrictEqual(<React.Fragment />); + }); + + it('useParams', () => { + expect(useParams()).toStrictEqual({}); + }); + + it('useSearchParams', () => { + expect(useSearchParams()[0]).toStrictEqual({}); + }); + + it('useLocation', () => { + expect(useLocation()).toStrictEqual({}); + }); + + it('useNavigate', () => { + expect(useNavigate()).toStrictEqual({}); + }); +}); \ No newline at end of file diff --git a/packages/style-import/tests/importStyle.test.ts b/packages/style-import/tests/importStyle.test.ts index 9bfdc3782..ae7dec83a 100644 --- a/packages/style-import/tests/importStyle.test.ts +++ b/packages/style-import/tests/importStyle.test.ts @@ -3,58 +3,58 @@ import { importStyle } from '../src/index'; describe('import style', () => { it('simple import', async () => { - const sourceCode = `import { Button } from 'antd';`; + const sourceCode = 'import { Button } from \'antd\';'; const result = await importStyle(sourceCode, { libraryName: 'antd', style: true }); expect(result?.code).toBe(`${sourceCode}\nimport 'antd/es/button/style';`); }); it('custom style', async () => { - const sourceCode = `import { Button } from 'antd';`; + const sourceCode = 'import { Button } from \'antd\';'; const result = await importStyle(sourceCode, { libraryName: 'antd', style: (name) => `antd/es/${name.toLocaleLowerCase()}/style` }); expect(result?.code).toBe(`${sourceCode}\nimport 'antd/es/button/style';`); }); it('mismatch import', async () => { - const sourceCode = `import { Button } from 'antd-mobile';`; + const sourceCode = 'import { Button } from \'antd-mobile\';'; const result = await importStyle(sourceCode, { libraryName: 'antd', style: true }); expect(result?.code).toBe(`${sourceCode}`); }); it('multiple import', async () => { - const sourceCode = `import { Button, Table } from 'antd';`; + const sourceCode = 'import { Button, Table } from \'antd\';'; const result = await importStyle(sourceCode, { libraryName: 'antd', style: true }); expect(result?.code).toBe(`${sourceCode}\nimport 'antd/es/button/style';\nimport 'antd/es/table/style';`); }); it('named import', async () => { - const sourceCode = `import { Button as Btn } from 'antd';`; + const sourceCode = 'import { Button as Btn } from \'antd\';'; const result = await importStyle(sourceCode, { libraryName: 'antd', style: true }); expect(result?.code).toBe(`${sourceCode}\nimport 'antd/es/button/style';`); }); it('default import', async () => { - const sourceCode = `import * as antd from 'antd';`; + const sourceCode = 'import * as antd from \'antd\';'; const result = await importStyle(sourceCode, { libraryName: 'antd', style: true }); expect(result?.code).toBe(`${sourceCode}`); }); it('sourcemap', async () => { - const sourceCode = `import * as antd from 'antd';`; + const sourceCode = 'import * as antd from \'antd\';'; const result = await importStyle(sourceCode, { libraryName: 'antd', style: true, sourceMap: true }); expect(!!result?.map).toBe(true); }); it('none import', async () => { - const sourceCode = `export const a = 'antd';`; + const sourceCode = 'export const a = \'antd\';'; const result = await importStyle(sourceCode, { libraryName: 'antd', style: true }); expect(result).toBe(null); }); - + it('parse error', async () => { - const sourceCode = `export antd, { Button } from 'antd';`; + const sourceCode = 'export antd, { Button } from \'antd\';'; const result = await importStyle(sourceCode, { libraryName: 'antd', style: true }); expect(result).toBe(null); }); it('import error', async () => { - const sourceCode = `import antd, { Button } from 'antd';`; + const sourceCode = 'import antd, { Button } from \'antd\';'; const result = await importStyle(sourceCode, { libraryName: 'antd', style: true }); expect(result?.code).toBe(sourceCode); }); it('style false', async () => { - const sourceCode = `import { Button } from 'antd';`; + const sourceCode = 'import { Button } from \'antd\';'; const result = await importStyle(sourceCode, { libraryName: 'antd', style: false }); expect(result).toBe(null); }); diff --git a/packages/types/package.json b/packages/types/package.json index 8083f9467..e99bf274d 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -30,15 +30,17 @@ "bugs": "https://github.com/ice-lab/ice-next/issues", "homepage": "https://next.ice.work", "devDependencies": { - "@builder/swc": "^0.2.0", "@ice/route-manifest": "^1.0.0", - "@ice/runtime": "^1.0.0", + "@swc/core": "1.2.210", "build-scripts": "^2.0.0-24", - "esbuild": "^0.14.23", + "esbuild": "^0.14.51", "eslint": "^8.14.0", "eslint-webpack-plugin": "3.1.1", "fork-ts-checker-webpack-plugin": "7.2.6", + "history": "^5.3.0", "react": "^18.0.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.2.2", "terser": "^5.12.1", "typescript": "^4.6.4", "unplugin": "^0.9.5", diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts index d89c348da..30d6f9311 100644 --- a/packages/types/src/config.ts +++ b/packages/types/src/config.ts @@ -13,7 +13,7 @@ import type { ForkTsCheckerWebpackPluginOptions } from 'fork-ts-checker-webpack- import type { UnpluginOptions, UnpluginContext } from 'unplugin'; import type Server from 'webpack-dev-server'; import type { ECMA } from 'terser'; -import type { Config as SWCCompilationConfig } from '@builder/swc'; +import type { Config as SWCCompilationConfig } from '@swc/core'; import type { BuildOptions } from 'esbuild'; import type { UserConfig } from './userConfig'; @@ -26,7 +26,7 @@ interface PredefinedOptions { module?: boolean | undefined; ecma?: ECMA | undefined; } -type MinimizerOptions<T> = PredefinedOptions & InferDefaultType<T>; +export type MinimizerOptions<T> = PredefinedOptions & InferDefaultType<T>; interface ConfigurationCtx extends Config { supportedBrowsers: string[]; @@ -39,6 +39,8 @@ interface SwcOptions { removeExportExprs?: string[]; compilationConfig?: SWCCompilationConfig; keepPlatform?: 'node' | 'web' | 'weex' | 'miniapp'; + keepExports?: string[]; + getRoutePaths?: Function; } interface TransformOptions { @@ -52,6 +54,8 @@ interface TransformPlugin { enforce?: string; transform?: Transform; transformInclude?: UnpluginOptions['transformInclude']; + load?: UnpluginOptions['load']; + loadInclude?: UnpluginOptions['loadInclude']; } export type ModifyWebpackConfig = (config: Configuration, ctx: ConfigurationCtx) => Configuration; @@ -99,7 +103,7 @@ export interface Config { compileIncludes?: (string | RegExp)[]; - minify?: boolean; + minify?: boolean | string; minimizerOptions?: MinimizerOptions<CustomOptions>; diff --git a/packages/types/src/runtime.ts b/packages/types/src/runtime.ts index 691935b6b..c1ba14b63 100644 --- a/packages/types/src/runtime.ts +++ b/packages/types/src/runtime.ts @@ -1,3 +1,214 @@ -import type { RuntimePlugin, RouteConfig, AppConfig, AppProvider, RouteWrapper } from '@ice/runtime'; +import type { IncomingMessage, ServerResponse } from 'http'; +import type { Action, InitialEntry, Location } from 'history'; +import type { ComponentType, ReactNode, PropsWithChildren } from 'react'; +import type { HydrationOptions } from 'react-dom/client'; +import type { Navigator, Params } from 'react-router-dom'; -export { RuntimePlugin, RouteConfig, AppConfig, AppProvider, RouteWrapper }; \ No newline at end of file +type useConfig = () => RouteConfig; +type useData = () => RouteData; +type useAppContext = () => AppContext; + +type VoidFunction = () => void; +type AppLifecycle = 'onShow' | 'onHide' | 'onPageNotFound' | 'onShareAppMessage' | 'onUnhandledRejection' | 'onLaunch' | 'onError' | 'onTabItemClick'; +type App = Partial<{ + rootId: string; + strict: boolean; + errorBoundary: boolean; +} & Record<AppLifecycle, VoidFunction>>; + +export type AppData = any; +export type RouteData = any; + +// route.getConfig return value +export interface RouteConfig { + title?: string; + // TODO: fix type + meta?: any[]; + links?: any[]; + scripts?: any[]; + + // plugin extends + auth?: string[]; +} + +export interface AppExport { + default?: AppConfig; + [key: string]: any; + getAppData?: GetAppData; +} + +export type GetAppData = (ctx: RequestContext) => Promise<AppData> | AppData; + +// app.getData & route.getData +export type GetData = (ctx: RequestContext) => Promise<RouteData> | RouteData; +export type GetServerData = (ctx: RequestContext) => Promise<RouteData> | RouteData; +export type GetStaticData = (ctx: RequestContext) => Promise<RouteData> | RouteData; +// route.getConfig +export type GetConfig = (args: { data: RouteData }) => RouteConfig; + +export interface AppConfig { + app?: App; + router?: { + type?: 'hash' | 'browser' | 'memory'; + basename?: string; + initialEntries?: InitialEntry[]; + }; +} + +export interface RoutesConfig { + [routeId: string]: RouteConfig; +} + +export interface RoutesData { + [routeId: string]: RouteData; +} + +// useAppContext +export interface AppContext { + appConfig: AppConfig; + appData: any; + assetsManifest: AssetsManifest; + routesData: RoutesData; + routesConfig: RoutesConfig; + routeModules: RouteModules; + routePath?: string; + matches?: RouteMatch[]; + routes?: RouteItem[]; + documentOnly?: boolean; + matchedIds?: string[]; + appExport?: AppExport; + basename?: string; +} + +export type Renderer = ( + container: Element | Document, + initialChildren: React.ReactNode, + options?: HydrationOptions, +) => void; + +export interface ServerContext { + req?: IncomingMessage; + res?: ServerResponse; +} + +export interface RequestContext extends ServerContext { + pathname: string; + query: Record<string, any>; +} + +export interface RouteComponent { + default: ComponentType<any>; + getStaticData?: GetStaticData; + getServerData?: GetServerData; + getData?: GetData; + getConfig?: GetConfig; + [key: string]: any; +} + +export interface RouteItem { + id: string; + path: string; + element?: ReactNode; + componentName: string; + index?: boolean; + exact?: boolean; + strict?: boolean; + load?: () => Promise<RouteComponent>; + children?: RouteItem[]; + layout?: boolean; +} + +export type ComponentWithChildren<P = {}> = ComponentType<PropsWithChildren<P>>; + +export type DocumentComponent = ComponentWithChildren<{ + pagePath: string; +}>; + +export interface RouteWrapperConfig { + Wrapper: RouteWrapper; + layout?: boolean; +} + +export type AppProvider = ComponentWithChildren<any>; +export type RouteWrapper = ComponentType<any>; + +export type SetAppRouter = (AppRouter: ComponentType<AppRouterProps>) => void; +export type AddProvider = (Provider: AppProvider) => void; +export type SetRender = (render: Renderer) => void; +export type AddWrapper = (wrapper: RouteWrapper, forLayout?: boolean) => void; + +export interface RouteModules { + [routeId: string]: RouteComponent; +} + +export interface AssetsManifest { + dataLoader?: string; + publicPath: string; + entries: { + [assetPath: string]: string[]; + }; + pages: { + [assetPath: string]: string[]; + }; + assets?: { + [assetPath: string]: string; + }; +} + +export interface RuntimeAPI { + setAppRouter: SetAppRouter; + addProvider: AddProvider; + setRender: SetRender; + addWrapper: AddWrapper; + appContext: AppContext; + useData: useData; + useConfig: useConfig; + useAppContext: useAppContext; +} + +export interface RuntimePlugin { + ( + apis: RuntimeAPI + ): Promise<void> | void; +} + +export interface CommonJsRuntime { + default: RuntimePlugin; +} + +export type RuntimeModules = (RuntimePlugin | CommonJsRuntime)[]; + +export interface AppRouterProps { + action: Action; + location: Location; + navigator: Navigator; + routes: RouteItem[]; + static?: boolean; + basename?: string; +} + +export interface AppRouteProps { + routes: RouteItem[]; +} + +// rewrite the `RouteMatch` type which is referenced by the react-router-dom +export interface RouteMatch { + /** + * The names and values of dynamic parameters in the URL. + */ + params: Params; + /** + * The portion of the URL pathname that was matched. + */ + pathname: string; + /** + * The portion of the URL pathname that was matched before child routes. + */ + pathnameBase: string; + /** + * The route object that was used to match. + */ + route: RouteItem; +} + +export type RenderMode = 'SSR' | 'SSG'; diff --git a/packages/types/src/userConfig.ts b/packages/types/src/userConfig.ts index a9a67f6d8..fad4a809d 100644 --- a/packages/types/src/userConfig.ts +++ b/packages/types/src/userConfig.ts @@ -1,7 +1,7 @@ import type { DefineRouteFunction } from '@ice/route-manifest'; import type { PluginList } from 'build-scripts'; import type { UnpluginOptions } from 'unplugin'; -import type { Config, ModifyWebpackConfig } from './config'; +import type { Config, ModifyWebpackConfig, MinimizerOptions } from './config'; import type { OverwritePluginAPI } from './plugin'; interface SyntaxFeatures { @@ -14,6 +14,16 @@ interface Optimization { router?: boolean; } +interface MinifyOptions { + type: 'terser' | 'swc'; + options?: MinimizerOptions<Record<string, any>>; +} + +interface IgnorePattern { + resourceRegExp: RegExp; + contextRegExp?: RegExp; +} + export interface UserConfig { alias?: Record<string, string | false>; define?: Record<string, string | boolean>; @@ -31,7 +41,7 @@ export interface UserConfig { }; plugins?: PluginList<Config, OverwritePluginAPI>; dropLogLevel?: 'trace' | 'debug' | 'log' | 'info' | 'warn' | 'error'; - minify?: boolean; + minify?: boolean | 'swc' | MinifyOptions; compileDependencies?: boolean | string[] | RegExp[]; sourceMap?: string | boolean; tsChecker?: boolean; @@ -39,8 +49,9 @@ export interface UserConfig { ssr?: boolean; ssg?: boolean; server?: { - format: 'esm' | 'cjs'; - bundle: boolean; + format?: 'esm' | 'cjs'; + bundle?: boolean; + ignores?: IgnorePattern[]; }; optimization?: Optimization; mock?: { exclude?: string[] }; diff --git a/packages/webpack-config/package.json b/packages/webpack-config/package.json index 8d6e12da4..5a014b8b3 100644 --- a/packages/webpack-config/package.json +++ b/packages/webpack-config/package.json @@ -13,23 +13,20 @@ ], "dependencies": { "@ice/swc-plugin-remove-export": "^0.1.0", + "@ice/swc-plugin-keep-export": "^0.1.1", "@ice/swc-plugin-keep-platform": "^0.1.0", "@swc/core": "1.2.210", "@ice/bundles": "^0.1.0", - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7", "@rollup/pluginutils": "^4.2.0", "browserslist": "^4.19.3", "consola": "^2.15.3", "fast-glob": "^3.2.11", - "magic-string": "^0.26.1", - "mini-css-extract-plugin": "2.6.0", - "react-refresh": "^0.12.0", - "unplugin": "^0.9.5" + "magic-string": "^0.26.1" }, "devDependencies": { "@ice/types": "^1.0.0", "build-scripts": "^2.0.0-24", - "esbuild": "^0.14.23", + "esbuild": "^0.14.51", "webpack": "^5.73.0", "webpack-dev-server": "^4.7.4" }, diff --git a/packages/webpack-config/src/config/css.ts b/packages/webpack-config/src/config/css.ts index 24754f87b..419546a38 100644 --- a/packages/webpack-config/src/config/css.ts +++ b/packages/webpack-config/src/config/css.ts @@ -1,7 +1,7 @@ import { createRequire } from 'module'; import { createHash } from 'crypto'; // FIXME when resolve mini-css-extract-plugin symbol in test -import MiniCssExtractPlugin from 'mini-css-extract-plugin'; +import MiniCssExtractPlugin from '@ice/bundles/compiled/mini-css-extract-plugin/dist/index.js'; import { sass, less, postcss } from '@ice/bundles'; import type { ModifyWebpackConfig } from '@ice/types/esm/config'; import type { LoaderContext } from 'webpack'; diff --git a/packages/webpack-config/src/getCompilerPlugins.ts b/packages/webpack-config/src/getCompilerPlugins.ts index 85e3a392d..ab146ad34 100644 --- a/packages/webpack-config/src/getCompilerPlugins.ts +++ b/packages/webpack-config/src/getCompilerPlugins.ts @@ -1,13 +1,14 @@ import type { Config } from '@ice/types'; import type { BuildOptions } from 'esbuild'; -import { createUnplugin } from 'unplugin'; -import type { UnpluginOptions } from 'unplugin'; +import unplugin from '@ice/bundles/compiled/unplugin/index.js'; +import type { UnpluginOptions } from '@ice/bundles/compiled/unplugin/index.js'; +import type { Configuration } from 'webpack'; import compilationPlugin from './unPlugins/compilation.js'; import compileExcludes from './compileExcludes.js'; -import type { WebpackConfig } from './index.js'; type Compiler = 'webpack' | 'esbuild'; +const { createUnplugin } = unplugin; function getPluginTransform(plugin: UnpluginOptions, type: 'esbuild' | 'webpack') { const { transform } = plugin; if (transform) { @@ -24,7 +25,12 @@ function getPluginTransform(plugin: UnpluginOptions, type: 'esbuild' | 'webpack' return plugin; } -function getCompilerPlugins(config: Config, compiler: 'webpack'): WebpackConfig['plugins']; +function transformInclude(id: string) { + // Ingore binary file to be transformed. + return !!id.match(/\.(js|jsx|ts|tsx|mjs|mts|css|less|scss)$/); +} + +function getCompilerPlugins(config: Config, compiler: 'webpack'): Configuration['plugins']; function getCompilerPlugins(config: Config, compiler: 'esbuild'): BuildOptions['plugins']; function getCompilerPlugins(config: Config, compiler: Compiler) { const { @@ -42,7 +48,7 @@ function getCompilerPlugins(config: Config, compiler: Compiler) { // Add custom transform before swc compilation so the source code can be got before transformed. compilerPlugins.push( ...(transformPlugins.filter(({ enforce }) => !enforce || enforce === 'pre') || []), - ...transforms.map((transform, index) => ({ name: `transform_${index}`, transform })), + ...transforms.map((transform, index) => ({ name: `transform_${index}`, transform, transformInclude })), ); // Use webpack loader instead of webpack plugin to do the compilation. // Reason: https://github.com/unjs/unplugin/issues/154 diff --git a/packages/webpack-config/src/index.ts b/packages/webpack-config/src/index.ts index 8d777715f..11f0e482f 100644 --- a/packages/webpack-config/src/index.ts +++ b/packages/webpack-config/src/index.ts @@ -3,7 +3,7 @@ import { createRequire } from 'module'; import fg from 'fast-glob'; import consola from 'consola'; // FIXME when prepack @pmmmwh/react-refresh-webpack-plugin -import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'; +import ReactRefreshWebpackPlugin from '@ice/bundles/compiled/@pmmmwh/react-refresh-webpack-plugin/lib/index.js'; import bundleAnalyzer from '@ice/bundles/compiled/webpack-bundle-analyzer/index.js'; import lodash from '@ice/bundles/compiled/lodash/index.js'; import CssMinimizerPlugin from '@ice/bundles/compiled/css-minimizer-webpack-plugin/index.js'; @@ -13,7 +13,6 @@ import ESlintPlugin from '@ice/bundles/compiled/eslint-webpack-plugin/index.js'; import CopyPlugin from '@ice/bundles/compiled/copy-webpack-plugin/index.js'; import type { Configuration, WebpackPluginInstance, NormalModule, Compiler } from 'webpack'; import type webpack from 'webpack'; -import type { Configuration as DevServerConfiguration } from 'webpack-dev-server'; import type { Config } from '@ice/types'; import browserslist from 'browserslist'; import configAssets from './config/assets.js'; @@ -35,8 +34,11 @@ interface GetWebpackConfigOptions { webpack: typeof webpack; runtimeTmpDir: string; } -export type WebpackConfig = Configuration & { devServer?: DevServerConfiguration }; -type GetWebpackConfig = (options: GetWebpackConfigOptions) => WebpackConfig; +type GetWebpackConfig = (options: GetWebpackConfigOptions) => Configuration; +enum JSMinifier { + terser = 'terser', + swc = 'swc', +} function getEntry(rootDir: string, runtimeTmpDir: string) { // check entry.client.ts @@ -160,7 +162,7 @@ const getWebpackConfig: GetWebpackConfig = ({ rootDir, config, webpack, runtimeT compileExcludes, swcOptions, }); - const webpackConfig: WebpackConfig = { + const webpackConfig: Configuration = { mode, experiments: { layers: true, @@ -219,12 +221,11 @@ const getWebpackConfig: GetWebpackConfig = ({ rootDir, config, webpack, runtimeT splitChunks: splitChunks == false ? { minChunks: Infinity, cacheGroups: { default: false } } : getSplitChunksConfig(rootDir), - minimize: minify, + minimize: !!minify, minimizer: [ new TerserPlugin({ - // keep same with compilation - // use swcMinify with fix error of pure_funcs - // minify: TerserPlugin.swcMinify + // Minify of swc is still experimental, config `minify: 'swc'` faster minification. + minify: minify === JSMinifier.swc ? TerserPlugin.swcMinify : TerserPlugin.terserMinify, extractComments: false, terserOptions, }), diff --git a/packages/webpack-config/src/unPlugins/compilation.ts b/packages/webpack-config/src/unPlugins/compilation.ts index 3b60ab8f0..1facad823 100644 --- a/packages/webpack-config/src/unPlugins/compilation.ts +++ b/packages/webpack-config/src/unPlugins/compilation.ts @@ -1,7 +1,7 @@ import { createRequire } from 'module'; import swc from '@swc/core'; import type { Options as SwcConfig, ReactConfig } from '@swc/core'; -import type { UnpluginOptions } from 'unplugin'; +import type { UnpluginOptions } from '@ice/bundles/compiled/unplugin/index.js'; import lodash from '@ice/bundles/compiled/lodash/index.js'; import type { Config } from '@ice/types'; @@ -22,10 +22,27 @@ interface Options { const compilationPlugin = (options: Options): UnpluginOptions => { const { sourceMap, mode, fastRefresh, compileIncludes = [], compileExcludes, swcOptions = {}, cacheDir } = options; + + const { removeExportExprs, compilationConfig, keepPlatform, keepExports, getRoutePaths } = swcOptions; + const compileRegex = compileIncludes.map((includeRule) => { return includeRule instanceof RegExp ? includeRule : new RegExp(includeRule); }); + function isRouteEntry(id) { + const routes = getRoutePaths(); + + const matched = routes.find(route => { + return id.indexOf(route) > -1; + }); + + return !!matched; + } + + function isAppEntry(id) { + return /(.*)src\/app/.test(id); + } + const extensionRegex = /\.(jsx?|tsx?|mjs)$/; return { name: 'compilation-plugin', @@ -57,8 +74,6 @@ const compilationPlugin = (options: Options): UnpluginOptions => { merge(programmaticOptions, commonOptions); - const { removeExportExprs, compilationConfig, keepPlatform } = swcOptions; - if (compilationConfig) { merge(programmaticOptions, compilationConfig); } @@ -66,26 +81,33 @@ const compilationPlugin = (options: Options): UnpluginOptions => { const swcPlugins = []; // handle app.tsx and page entries only if (removeExportExprs) { - if (/(.*)pages(.*)\.(jsx?|tsx?|mjs)$/.test(id)) { + if (isRouteEntry(id) || isAppEntry(id)) { swcPlugins.push([ require.resolve('@ice/swc-plugin-remove-export'), removeExportExprs, ]); - } else if (/(.*)src\/app/.test(id)) { - let removeList; + } + } - // FIXME: https://github.com/ice-lab/ice-next/issues/487 - if (removeExportExprs.indexOf('getConfig') === -1) { + if (keepExports) { + if (isRouteEntry(id)) { + swcPlugins.push([ + require.resolve('@ice/swc-plugin-keep-export'), + keepExports, + ]); + } else if (isAppEntry(id)) { + let keepList; + + if (keepExports.indexOf('getConfig') > -1) { // when build for getConfig, should keep default, it equals to getAppConfig - removeList = removeExportExprs.filter(key => key !== 'default'); + keepList = keepExports.concat(['default']); } else { - // when build for getData, should remove all other exports - removeList = removeExportExprs; + keepList = keepExports; } swcPlugins.push([ - require.resolve('@ice/swc-plugin-remove-export'), - removeList, + require.resolve('@ice/swc-plugin-keep-export'), + keepList, ]); } } @@ -115,8 +137,9 @@ const compilationPlugin = (options: Options): UnpluginOptions => { let { map } = output; return { code, map }; } catch (e) { - // catch error for Unhandled promise rejection - this.error(e); + // Catch error for unhandled promise rejection. + // In some cases, this referred to undefined. + if (this) this.error(e); return { code: null, map: null }; } }, @@ -151,7 +174,7 @@ function getJsxTransformOptions({ noInterop: false, }, env: { - loose: true, + loose: false, }, }; const syntaxFeatures = { diff --git a/packages/webpack-config/src/unPlugins/redirectImport.ts b/packages/webpack-config/src/unPlugins/redirectImport.ts index 5273dcf13..d874f23ed 100644 --- a/packages/webpack-config/src/unPlugins/redirectImport.ts +++ b/packages/webpack-config/src/unPlugins/redirectImport.ts @@ -1,6 +1,6 @@ import moduleLexer from '@ice/bundles/compiled/es-module-lexer/index.js'; import type { ImportSpecifier } from '@ice/bundles/compiled/es-module-lexer'; -import type { UnpluginOptions } from 'unplugin'; +import type { UnpluginOptions } from '@ice/bundles/compiled/unplugin/index.js'; import consola from 'consola'; import MagicString from 'magic-string'; import { createFilter } from '@rollup/pluginutils'; diff --git a/packages/webpack-config/test/redirectImport.test.ts b/packages/webpack-config/test/redirectImport.test.ts index f253780a8..a17780925 100644 --- a/packages/webpack-config/test/redirectImport.test.ts +++ b/packages/webpack-config/test/redirectImport.test.ts @@ -1,7 +1,7 @@ -import { expect, describe, it } from 'vitest'; import * as path from 'path'; import * as fs from 'fs'; import { fileURLToPath } from 'url'; +import { expect, describe, it } from 'vitest'; import { redirectImport } from '../src/unPlugins/redirectImport'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -14,8 +14,8 @@ describe('redirect import', () => { specifier: 'Head', source: 'react-helmet', exportAlias: { - 'Head': 'Helmet', - } + Head: 'Helmet', + }, }, { specifier: 'store', source: '@ice/store', @@ -53,5 +53,5 @@ describe('redirect import', () => { const code = fs.readFileSync(path.join(__dirname, './fixtures/multiple.js'), 'utf-8'); const transformed = await redirectImport(code, { exportData, targetSource: 'ice' }); expect(transformed).toBe('import request from \'axios\';\nimport store from \'@ice/store\';'); - }) -}) \ No newline at end of file + }); +}); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 090349cc4..b57140404 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,15 +12,15 @@ importers: '@types/fs-extra': ^9.0.13 '@types/glob': ^7.2.0 '@types/node': ^17.0.45 - '@types/semver': ^7.3.11 + '@types/semver': ^7.3.12 '@vercel/ncc': ^0.33.4 + '@vitest/coverage-c8': ^0.23.1 c8: ^7.12.0 chalk: ^4.1.2 chokidar: ^3.5.3 dependency-check: ^4.1.0 dts-bundle: ^0.7.3 - eslint: ^8.21.0 - esno: ^0.14.1 + eslint: ^8.22.0 execa: ^6.1.0 find-up: ^5.0.0 fs-extra: ^10.1.0 @@ -37,10 +37,11 @@ importers: rimraf: ^3.0.2 semver: ^7.3.7 stylelint: ^14.10.0 + tsx: ^3.9.0 typescript: ^4.7.4 vitest: ^0.15.2 devDependencies: - '@applint/spec': 1.2.3_6hnv5syfqtznzbamotbjuefldu + '@applint/spec': 1.2.3_wpfjmk7pkvc77ookm5durpydpe '@commitlint/cli': 16.3.0 '@ice/bundles': link:packages/bundles '@testing-library/react': 13.3.0_biqbaboplfbrettd7655fr4n2y @@ -48,15 +49,15 @@ importers: '@types/fs-extra': 9.0.13 '@types/glob': 7.2.0 '@types/node': 17.0.45 - '@types/semver': 7.3.11 + '@types/semver': 7.3.12 '@vercel/ncc': 0.33.4 + '@vitest/coverage-c8': 0.23.2_jsdom@20.0.0 c8: 7.12.0 chalk: 4.1.2 chokidar: 3.5.3 dependency-check: 4.1.0 dts-bundle: 0.7.3 - eslint: 8.21.0 - esno: 0.14.1 + eslint: 8.23.0 execa: 6.1.0 find-up: 5.0.0 fs-extra: 10.1.0 @@ -73,9 +74,39 @@ importers: rimraf: 3.0.2 semver: 7.3.7 stylelint: 14.10.0 + tsx: 3.9.0 typescript: 4.7.4 vitest: 0.15.2_c8@7.12.0+jsdom@20.0.0 + examples/app-config: + specifiers: + '@ice/app': workspace:* + '@ice/plugin-auth': workspace:* + '@ice/plugin-rax-compat': workspace:* + '@ice/runtime': workspace:* + '@types/react': ^18.0.0 + '@types/react-dom': ^18.0.2 + '@uni/env': ^1.1.0 + ahooks: ^3.3.8 + react: ^18.0.0 + react-dom: ^18.0.0 + speed-measure-webpack-plugin: ^1.5.0 + webpack: ^5.73.0 + dependencies: + '@ice/app': link:../../packages/ice + '@ice/plugin-auth': link:../../packages/plugin-auth + '@ice/plugin-rax-compat': link:../../packages/plugin-rax-compat + '@ice/runtime': link:../../packages/runtime + '@uni/env': 1.1.0 + ahooks: 3.4.1_react@18.2.0 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + devDependencies: + '@types/react': 18.0.17 + '@types/react-dom': 18.0.6 + speed-measure-webpack-plugin: 1.5.0_webpack@5.74.0 + webpack: 5.74.0 + examples/basic-project: specifiers: '@ice/app': workspace:* @@ -102,8 +133,8 @@ importers: devDependencies: '@types/react': 18.0.8 '@types/react-dom': 18.0.3 - speed-measure-webpack-plugin: 1.5.0_webpack@5.73.0 - webpack: 5.73.0 + speed-measure-webpack-plugin: 1.5.0_webpack@5.74.0 + webpack: 5.74.0 examples/csr-project: specifiers: @@ -127,8 +158,8 @@ importers: devDependencies: '@types/react': 18.0.8 '@types/react-dom': 18.0.3 - speed-measure-webpack-plugin: 1.5.0_webpack@5.73.0 - webpack: 5.73.0 + speed-measure-webpack-plugin: 1.5.0_webpack@5.74.0 + webpack: 5.74.0 examples/hash-router: specifiers: @@ -147,9 +178,42 @@ importers: '@types/react': 18.0.8 '@types/react-dom': 18.0.3 + examples/rax-inline-style: + specifiers: + '@ice/app': workspace:* + '@ice/plugin-rax-compat': workspace:* + '@ice/runtime': workspace:* + '@types/react': ^18.0.0 + '@types/react-dom': ^18.0.2 + rax: ^1.2.2 + rax-image: ^2.4.1 + rax-is-valid-element: ^1.0.0 + rax-text: ^2.2.0 + rax-view: ^2.3.0 + react: ^18.0.0 + react-dom: ^18.0.0 + webpack: ^5.73.0 + dependencies: + '@ice/app': link:../../packages/ice + '@ice/plugin-rax-compat': link:../../packages/plugin-rax-compat + '@ice/runtime': link:../../packages/runtime + rax: 1.2.2 + rax-image: 2.4.1_rax@1.2.2 + rax-is-valid-element: 1.0.0 + rax-text: 2.2.0_rax@1.2.2 + rax-view: 2.3.0_rax@1.2.2 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + devDependencies: + '@types/react': 18.0.17 + '@types/react-dom': 18.0.6 + webpack: 5.74.0 + examples/rax-project: specifiers: '@ice/app': workspace:* + '@ice/appear': workspace:* + '@ice/plugin-jsx-plus': workspace:* '@ice/plugin-rax-compat': workspace:* '@ice/runtime': workspace:* '@types/react': ^18.0.0 @@ -164,6 +228,8 @@ importers: webpack: ^5.73.0 dependencies: '@ice/app': link:../../packages/ice + '@ice/appear': link:../../packages/appear + '@ice/plugin-jsx-plus': link:../../packages/plugin-jsx-plus '@ice/plugin-rax-compat': link:../../packages/plugin-rax-compat '@ice/runtime': link:../../packages/runtime rax: 1.2.2 @@ -176,7 +242,7 @@ importers: devDependencies: '@types/react': 18.0.8 '@types/react-dom': 18.0.3 - webpack: 5.73.0 + webpack: 5.74.0 examples/routes-generate: specifiers: @@ -262,6 +328,7 @@ importers: specifiers: '@alifd/next': ^1.25.49 '@ice/app': workspace:* + '@ice/plugin-css-assets-local': workspace:* '@ice/plugin-fusion': workspace:* '@ice/runtime': workspace:* '@types/react': ^18.0.0 @@ -270,15 +337,49 @@ importers: react-dom: ^18.0.0 dependencies: '@alifd/next': 1.25.49_biqbaboplfbrettd7655fr4n2y - '@ice/app': link:../../packages/ice - '@ice/plugin-fusion': link:../../packages/plugin-fusion '@ice/runtime': link:../../packages/runtime react: 18.2.0 react-dom: 18.2.0_react@18.2.0 devDependencies: + '@ice/app': link:../../packages/ice + '@ice/plugin-css-assets-local': link:../../packages/plugin-css-assets-local + '@ice/plugin-fusion': link:../../packages/plugin-fusion '@types/react': 18.0.8 '@types/react-dom': 18.0.3 + examples/with-jest: + specifiers: + '@ice/app': workspace:* + '@ice/runtime': workspace:* + '@testing-library/jest-dom': ^5.16.5 + '@testing-library/react': ^13.3.0 + '@types/jest': ^29.0.0 + '@types/react': ^18.0.0 + '@types/react-dom': ^18.0.2 + '@types/testing-library__jest-dom': ^5.14.5 + jest: ^28.1.3 + jest-environment-jsdom: ^29.0.2 + react: ^18.0.0 + react-dom: ^18.0.0 + ts-jest: ^28.0.8 + typescript: ^4.8.2 + dependencies: + '@ice/runtime': link:../../packages/runtime + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + devDependencies: + '@ice/app': link:../../packages/ice + '@testing-library/jest-dom': 5.16.5 + '@testing-library/react': 13.3.0_biqbaboplfbrettd7655fr4n2y + '@types/jest': 29.0.3 + '@types/react': 18.0.17 + '@types/react-dom': 18.0.6 + '@types/testing-library__jest-dom': 5.14.5 + jest: 28.1.3 + jest-environment-jsdom: 29.0.3 + ts-jest: 28.0.8_oavexkd2euoi6eueqpz7c42uqe + typescript: 4.8.3 + examples/with-pha: specifiers: '@ice/app': workspace:* @@ -298,7 +399,26 @@ importers: devDependencies: '@types/react': 18.0.8 '@types/react-dom': 18.0.3 - webpack: 5.73.0 + webpack: 5.74.0 + + examples/with-plugin-request: + specifiers: + '@ice/app': workspace:* + '@ice/plugin-request': workspace:* + '@ice/runtime': workspace:* + '@types/react': ^18.0.17 + '@types/react-dom': ^18.0.6 + react: ^18.2.0 + react-dom: ^18.2.0 + dependencies: + '@ice/app': link:../../packages/ice + '@ice/plugin-request': link:../../packages/plugin-request + '@ice/runtime': link:../../packages/runtime + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + devDependencies: + '@types/react': 18.0.17 + '@types/react-dom': 18.0.6 examples/with-store: specifiers: @@ -315,90 +435,193 @@ importers: '@types/react': 18.0.15 '@types/react-dom': 18.0.6 + examples/with-vitest: + specifiers: + '@ice/app': workspace:* + '@ice/runtime': workspace:* + '@testing-library/jest-dom': ^5.16.5 + '@testing-library/react': ^13.3.0 + '@types/react': ^18.0.0 + '@types/react-dom': ^18.0.2 + '@types/testing-library__jest-dom': ^5.14.5 + '@vitejs/plugin-react': ^1.3.2 + jsdom: ^20.0.0 + react: ^18.0.0 + react-dom: ^18.0.0 + typescript: ^4.8.2 + vitest: ^0.15.2 + dependencies: + '@ice/runtime': link:../../packages/runtime + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + devDependencies: + '@ice/app': link:../../packages/ice + '@testing-library/jest-dom': 5.16.5 + '@testing-library/react': 13.3.0_biqbaboplfbrettd7655fr4n2y + '@types/react': 18.0.17 + '@types/react-dom': 18.0.6 + '@types/testing-library__jest-dom': 5.14.5 + '@vitejs/plugin-react': 1.3.2 + jsdom: 20.0.0 + typescript: 4.8.3 + vitest: 0.15.2_jsdom@20.0.0 + + packages/appear: + specifiers: + react: ^18.0.0 + react-dom: ^18.0.0 + devDependencies: + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + packages/bundles: specifiers: + '@pmmmwh/react-refresh-webpack-plugin': 0.5.7 '@swc/core': 1.2.210 '@types/cacache': ^15.0.1 '@types/less': ^3.0.3 '@types/lodash': ^4.14.181 '@types/webpack-bundle-analyzer': ^4.4.1 + ansi-html-community: ^0.0.8 + bonjour-service: ^1.0.13 cacache: 16.0.7 caniuse-lite: ^1.0.30001332 chokidar: 3.5.3 + colorette: ^2.0.10 + common-path-prefix: 3.0.0 + compression: ^1.7.4 + connect-history-api-fallback: ^1.6.0 copy-webpack-plugin: 10.2.4 + core-js-pure: ^3.8.1 css-loader: 6.7.1 css-minimizer-webpack-plugin: 3.4.1 cssnano: ^5.1.7 + default-gateway: ^6.0.3 + error-stack-parser: ^2.0.6 es-module-lexer: 0.10.5 eslint: ^8.14.0 eslint-webpack-plugin: 3.1.1 events: 3.3.0 + express: ^4.17.3 + find-up: 5.0.0 fork-ts-checker-webpack-plugin: 7.2.6 fs-extra: ^10.0.0 + globby: 13.1.2 + graceful-fs: ^4.2.6 + html-entities: ^2.3.2 + http-proxy-middleware: ^2.0.3 + ipaddr.js: ^2.0.1 jest-worker: 27.5.1 less: 4.1.2 less-loader: 10.2.0 + loader-utils: ^2.0.0 lodash: 4.17.21 - mini-css-extract-plugin: 2.6.0 + mini-css-extract-plugin: 2.6.1 + open: ^8.0.9 ora: 5.4.1 + p-retry: ^4.5.0 + portfinder: ^1.0.28 postcss: 8.4.12 postcss-loader: 6.2.1 postcss-modules: 4.3.1 postcss-nested: 5.0.6 postcss-plugin-rpx2vw: 1.0.0 postcss-preset-env: 7.4.3 + react-refresh: 0.14.0 + rimraf: ^3.0.2 sass: 1.50.0 sass-loader: 12.6.0 + schema-utils: ^4.0.0 + selfsigned: ^2.0.1 + serve-index: ^1.9.1 + sockjs: ^0.3.21 + source-map: 0.8.0-beta.0 + spdy: ^4.0.2 tapable: 2.2.1 - terser: 5.12.1 - terser-webpack-plugin: 5.3.1 + terser: 5.14.2 + terser-webpack-plugin: 5.3.5 typescript: ^4.6.4 - webpack: 5.73.0 + unplugin: 0.9.5 + webpack: 5.74.0 webpack-bundle-analyzer: 4.5.0 - webpack-dev-server: 4.8.1 + webpack-dev-middleware: ^5.3.1 + webpack-dev-server: 4.10.0 webpack-sources: 3.2.3 + ws: ^8.4.2 dependencies: '@swc/core': 1.2.210 + ansi-html-community: 0.0.8 caniuse-lite: 1.0.30001332 chokidar: 3.5.3 + core-js-pure: 3.24.1 + error-stack-parser: 2.0.7 events: 3.3.0 + html-entities: 2.3.3 jest-worker: 27.5.1 less: 4.1.2 postcss: 8.4.12 + react-refresh: 0.14.0 sass: 1.50.0 devDependencies: + '@pmmmwh/react-refresh-webpack-plugin': 0.5.7_blviz2256hckjssg6tjpu76wzi '@types/cacache': 15.0.1 '@types/less': 3.0.3 '@types/lodash': 4.14.182 '@types/webpack-bundle-analyzer': 4.4.1_@swc+core@1.2.210 + bonjour-service: 1.0.13 cacache: 16.0.7 - copy-webpack-plugin: 10.2.4_webpack@5.73.0 - css-loader: 6.7.1_webpack@5.73.0 - css-minimizer-webpack-plugin: 3.4.1_webpack@5.73.0 + colorette: 2.0.19 + common-path-prefix: 3.0.0 + compression: 1.7.4 + connect-history-api-fallback: 1.6.0 + copy-webpack-plugin: 10.2.4_webpack@5.74.0 + css-loader: 6.7.1_webpack@5.74.0 + css-minimizer-webpack-plugin: 3.4.1_webpack@5.74.0 cssnano: 5.1.7_postcss@8.4.12 + default-gateway: 6.0.3 es-module-lexer: 0.10.5 eslint: 8.14.0 - eslint-webpack-plugin: 3.1.1_7fh3pplfe77vb5lwiuqfjafe74 - fork-ts-checker-webpack-plugin: 7.2.6_dydffymiyrgjbmyedhp7lreziy + eslint-webpack-plugin: 3.1.1_asfk4lnnm2udvewr2geiu7gcyy + express: 4.18.1 + find-up: 5.0.0 + fork-ts-checker-webpack-plugin: 7.2.6_spx7prkkl7pj6nxt6g3ewnbaqu fs-extra: 10.1.0 - less-loader: 10.2.0_less@4.1.2+webpack@5.73.0 + globby: 13.1.2 + graceful-fs: 4.2.10 + http-proxy-middleware: 2.0.6 + ipaddr.js: 2.0.1 + less-loader: 10.2.0_less@4.1.2+webpack@5.74.0 + loader-utils: 2.0.2 lodash: 4.17.21 - mini-css-extract-plugin: 2.6.0_webpack@5.73.0 + mini-css-extract-plugin: 2.6.1_webpack@5.74.0 + open: 8.4.0 ora: 5.4.1 - postcss-loader: 6.2.1_x2aj2q6umelkzhlylaf35s6ot4 + p-retry: 4.6.1 + portfinder: 1.0.28 + postcss-loader: 6.2.1_l7cnarxuwtifxq3zndacrkp2tq postcss-modules: 4.3.1_postcss@8.4.12 postcss-nested: 5.0.6_postcss@8.4.12 postcss-plugin-rpx2vw: 1.0.0_postcss@8.4.12 postcss-preset-env: 7.4.3_postcss@8.4.12 - sass-loader: 12.6.0_sass@1.50.0+webpack@5.73.0 + rimraf: 3.0.2 + sass-loader: 12.6.0_sass@1.50.0+webpack@5.74.0 + schema-utils: 4.0.0 + selfsigned: 2.0.1 + serve-index: 1.9.1 + sockjs: 0.3.24 + source-map: 0.8.0-beta.0 + spdy: 4.0.2 tapable: 2.2.1 - terser: 5.12.1 - terser-webpack-plugin: 5.3.1_cr5ideiic2hpdwwauzasyctjxa + terser: 5.14.2 + terser-webpack-plugin: 5.3.5_vwzmvoh3samqo2nn3x7mqt365m typescript: 4.6.4 - webpack: 5.73.0_@swc+core@1.2.210 + unplugin: 0.9.5_webpack@5.74.0 + webpack: 5.74.0_@swc+core@1.2.210 webpack-bundle-analyzer: 4.5.0 - webpack-dev-server: 4.8.1_webpack@5.73.0 + webpack-dev-middleware: 5.3.1_webpack@5.74.0 + webpack-dev-server: 4.10.0_webpack@5.74.0 webpack-sources: 3.2.3 + ws: 8.8.1 packages/ice: specifiers: @@ -434,11 +657,12 @@ importers: dotenv: ^16.0.0 dotenv-expand: ^8.0.3 ejs: ^3.1.6 - esbuild: ^0.14.23 + esbuild: ^0.14.51 esbuild-register: ^3.3.2 fast-glob: ^3.2.11 find-up: ^5.0.0 fs-extra: ^10.0.0 + jest: ^29.0.2 less: ^4.1.2 magic-string: ^0.26.1 micromatch: ^4.0.5 @@ -446,7 +670,7 @@ importers: multer: ^1.4.5-lts.1 open: ^8.4.0 path-to-regexp: ^6.2.0 - react: ^18.0.0 + react: ^18.2.0 react-router: ^6.3.0 regenerator-runtime: ^0.13.9 resolve.exports: ^1.1.0 @@ -454,7 +678,7 @@ importers: semver: ^7.3.5 temp: ^0.9.4 trusted-cert: ^1.1.3 - unplugin: ^0.9.5 + unplugin: ^0.9.0 webpack: ^5.73.0 webpack-dev-server: ^4.7.4 dependencies: @@ -479,8 +703,8 @@ importers: dotenv: 16.0.0 dotenv-expand: 8.0.3 ejs: 3.1.7 - esbuild: 0.14.38 - esbuild-register: 3.3.2_esbuild@0.14.38 + esbuild: 0.14.54 + esbuild-register: 3.3.2_esbuild@0.14.54 fast-glob: 3.2.11 find-up: 5.0.0 fs-extra: 10.1.0 @@ -498,7 +722,6 @@ importers: semver: 7.3.7 temp: 0.9.4 trusted-cert: 1.1.3 - webpack-dev-server: 4.8.1_webpack@5.73.0 devDependencies: '@types/babel__generator': 7.6.4 '@types/babel__traverse': 7.17.1 @@ -511,9 +734,11 @@ importers: '@types/sass': 1.43.1 '@types/temp': 0.9.1 chokidar: 3.5.3 + jest: 29.0.3 react: 18.2.0 - unplugin: 0.9.5_4upc34oiflw3lduyjvrzpjntau - webpack: 5.73.0_esbuild@0.14.38 + unplugin: 0.9.5_3qmdnfoccgmcaqi5n264fyeyfi + webpack: 5.74.0_esbuild@0.14.54 + webpack-dev-server: 4.8.1_webpack@5.74.0 packages/jsx-runtime: specifiers: @@ -553,6 +778,17 @@ importers: '@types/react-dom': 18.0.3 regenerator-runtime: 0.13.9 + packages/plugin-css-assets-local: + specifiers: + '@ice/types': ^1.0.0 + consola: ^2.15.3 + extract-css-assets-webpack-plugin: ^0.2.10 + dependencies: + consola: 2.15.3 + extract-css-assets-webpack-plugin: 0.2.10 + devDependencies: + '@ice/types': link:../types + packages/plugin-fusion: specifiers: '@ice/style-import': ^1.0.0 @@ -562,6 +798,33 @@ importers: devDependencies: '@ice/types': link:../types + packages/plugin-jsx-plus: + specifiers: + '@babel/core': ^7.19.1 + '@ice/types': ^1.0.0 + '@types/react': ^18.0.20 + '@types/react-dom': ^18.0.6 + babel-plugin-transform-jsx-class: ^0.1.3 + babel-plugin-transform-jsx-condition: ^0.1.2 + babel-plugin-transform-jsx-fragment: ^0.1.4 + babel-plugin-transform-jsx-list: ^0.1.2 + babel-plugin-transform-jsx-memo: ^0.1.4 + babel-plugin-transform-jsx-slot: ^0.1.2 + babel-runtime-jsx-plus: ^0.1.5 + dependencies: + '@babel/core': 7.19.1 + babel-plugin-transform-jsx-class: 0.1.3 + babel-plugin-transform-jsx-condition: 0.1.2 + babel-plugin-transform-jsx-fragment: 0.1.4 + babel-plugin-transform-jsx-list: 0.1.2 + babel-plugin-transform-jsx-memo: 0.1.4 + babel-plugin-transform-jsx-slot: 0.1.2 + babel-runtime-jsx-plus: 0.1.5 + devDependencies: + '@ice/types': link:../types + '@types/react': 18.0.20 + '@types/react-dom': 18.0.6 + packages/plugin-moment-locales: specifiers: '@ice/types': ^1.0.0 @@ -573,7 +836,7 @@ importers: '@ice/types': ^1.0.0 chalk: ^4.0.0 consola: ^2.15.3 - esbuild: ^0.14.23 + esbuild: ^0.14.51 humps: ^2.0.1 lodash.clonedeep: ^4.5.0 webpack: ^5.73.0 @@ -585,20 +848,30 @@ importers: lodash.clonedeep: 4.5.0 devDependencies: '@ice/types': link:../types - esbuild: 0.14.38 - webpack: 5.73.0_esbuild@0.14.38 - webpack-dev-server: 4.9.3_webpack@5.73.0 + esbuild: 0.14.54 + webpack: 5.74.0_esbuild@0.14.54 + webpack-dev-server: 4.9.3_webpack@5.74.0 packages/plugin-rax-compat: specifiers: + '@babel/core': ^7.0.0 + '@babel/plugin-proposal-export-default-from': ^7.18.9 + '@ice/bundles': ^0.1.0 '@ice/types': ^1.0.0 '@types/webpack': ^5.28.0 + babel-plugin-transform-jsx-stylesheet: 1.0.6 consola: ^2.15.3 + css: ^2.2.1 lodash.merge: ^4.6.2 rax-compat: ^0.1.0 stylesheet-loader: ^0.9.1 dependencies: + '@babel/core': 7.18.10 + '@babel/plugin-proposal-export-default-from': 7.18.10_@babel+core@7.18.10 + '@ice/bundles': link:../bundles + babel-plugin-transform-jsx-stylesheet: 1.0.6 consola: 2.15.3 + css: 2.2.4 lodash.merge: 4.6.2 rax-compat: link:../rax-compat stylesheet-loader: 0.9.1 @@ -606,6 +879,23 @@ importers: '@ice/types': link:../types '@types/webpack': 5.28.0 + packages/plugin-request: + specifiers: + '@ice/types': ^1.0.0 + '@types/react': ^18.0.0 + '@types/react-dom': ^18.0.0 + ahooks: ^3.0.0 + axios: ^0.27.2 + regenerator-runtime: ^0.13.9 + dependencies: + ahooks: 3.4.1 + axios: 0.27.2 + devDependencies: + '@ice/types': link:../types + '@types/react': 18.0.17 + '@types/react-dom': 18.0.6 + regenerator-runtime: 0.13.9 + packages/plugin-store: specifiers: '@ice/store': ^2.0.1 @@ -629,6 +919,7 @@ importers: packages/rax-compat: specifiers: + '@ice/appear': ^0.1.0 '@ice/pkg': 1.1.2-0 '@swc/helpers': ^0.4.3 '@types/rax': ^1.0.8 @@ -639,6 +930,7 @@ importers: react-dom: ^18.0.0 style-unit: ^3.0.5 dependencies: + '@ice/appear': link:../appear '@swc/helpers': 0.4.3 create-react-class: 15.7.0 style-unit: 3.0.5 @@ -659,9 +951,9 @@ importers: packages/runtime: specifiers: '@ice/jsx-runtime': ^0.1.0 + '@ice/types': ^1.0.0 '@types/react': ^18.0.8 '@types/react-dom': ^18.0.3 - consola: ^2.15.3 history: ^5.3.0 react: ^18.0.0 react-dom: ^18.0.0 @@ -669,10 +961,10 @@ importers: regenerator-runtime: ^0.13.9 dependencies: '@ice/jsx-runtime': link:../jsx-runtime - consola: 2.15.3 history: 5.3.0 react-router-dom: 6.3.0_biqbaboplfbrettd7655fr4n2y devDependencies: + '@ice/types': link:../types '@types/react': 18.0.8 '@types/react-dom': 18.0.3 react: 18.2.0 @@ -692,76 +984,74 @@ importers: packages/types: specifiers: - '@builder/swc': ^0.2.0 '@ice/route-manifest': ^1.0.0 - '@ice/runtime': ^1.0.0 + '@swc/core': 1.2.210 build-scripts: ^2.0.0-24 - esbuild: ^0.14.23 + esbuild: ^0.14.51 eslint: ^8.14.0 eslint-webpack-plugin: 3.1.1 fork-ts-checker-webpack-plugin: 7.2.6 + history: ^5.3.0 react: ^18.0.0 + react-dom: ^18.2.0 + react-router-dom: ^6.2.2 terser: ^5.12.1 typescript: ^4.6.4 unplugin: ^0.9.5 webpack: ^5.73.0 webpack-dev-server: ^4.7.4 devDependencies: - '@builder/swc': 0.2.0 '@ice/route-manifest': link:../route-manifest - '@ice/runtime': link:../runtime + '@swc/core': 1.2.210 build-scripts: 2.0.0-24 - esbuild: 0.14.38 + esbuild: 0.14.54 eslint: 8.14.0 - eslint-webpack-plugin: 3.1.1_7fh3pplfe77vb5lwiuqfjafe74 - fork-ts-checker-webpack-plugin: 7.2.6_dydffymiyrgjbmyedhp7lreziy + eslint-webpack-plugin: 3.1.1_asfk4lnnm2udvewr2geiu7gcyy + fork-ts-checker-webpack-plugin: 7.2.6_spx7prkkl7pj6nxt6g3ewnbaqu + history: 5.3.0 react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + react-router-dom: 6.3.0_biqbaboplfbrettd7655fr4n2y terser: 5.12.1 typescript: 4.6.4 - unplugin: 0.9.5_4upc34oiflw3lduyjvrzpjntau - webpack: 5.73.0_esbuild@0.14.38 - webpack-dev-server: 4.8.1_webpack@5.73.0 + unplugin: 0.9.5_3qmdnfoccgmcaqi5n264fyeyfi + webpack: 5.74.0_3cawqt5e67dzz3yqkvwzyd4tq4 + webpack-dev-server: 4.8.1_webpack@5.74.0 packages/webpack-config: specifiers: '@ice/bundles': ^0.1.0 + '@ice/swc-plugin-keep-export': ^0.1.1 '@ice/swc-plugin-keep-platform': ^0.1.0 '@ice/swc-plugin-remove-export': ^0.1.0 '@ice/types': ^1.0.0 - '@pmmmwh/react-refresh-webpack-plugin': ^0.5.7 '@rollup/pluginutils': ^4.2.0 '@swc/core': 1.2.210 browserslist: ^4.19.3 build-scripts: ^2.0.0-24 consola: ^2.15.3 - esbuild: ^0.14.23 + esbuild: ^0.14.51 fast-glob: ^3.2.11 magic-string: ^0.26.1 - mini-css-extract-plugin: 2.6.0 - react-refresh: ^0.12.0 - unplugin: ^0.9.5 webpack: ^5.73.0 webpack-dev-server: ^4.7.4 dependencies: '@ice/bundles': link:../bundles + '@ice/swc-plugin-keep-export': 0.1.1 '@ice/swc-plugin-keep-platform': 0.1.0 '@ice/swc-plugin-remove-export': 0.1.0 - '@pmmmwh/react-refresh-webpack-plugin': 0.5.7_co3pwf5d42rd2rqpmthdozfyry '@rollup/pluginutils': 4.2.1 '@swc/core': 1.2.210 browserslist: 4.20.3 consola: 2.15.3 fast-glob: 3.2.11 magic-string: 0.26.1 - mini-css-extract-plugin: 2.6.0_webpack@5.73.0 - react-refresh: 0.12.0 - unplugin: 0.9.5_4upc34oiflw3lduyjvrzpjntau devDependencies: '@ice/types': link:../types build-scripts: 2.0.0-24 - esbuild: 0.14.38 - webpack: 5.73.0_ohfecwmx44wixok6ry5c6snfbe - webpack-dev-server: 4.8.1_webpack@5.73.0 + esbuild: 0.14.54 + webpack: 5.74.0_3cawqt5e67dzz3yqkvwzyd4tq4 + webpack-dev-server: 4.10.0_webpack@5.74.0 website: specifiers: @@ -810,6 +1100,10 @@ importers: packages: + /@adobe/css-tools/4.0.1: + resolution: {integrity: sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g==} + dev: true + /@algolia/autocomplete-core/1.7.1: resolution: {integrity: sha512-eiZw+fxMzNQn01S8dA/hcCpoWCOCwcIIEUtHHdzN5TGB3IpzLbuhqFeTfh2OUhhgkE8Uo17+wH+QJ/wYyQmmzg==} dependencies: @@ -974,7 +1268,7 @@ packages: engines: {node: '>=6.0.0'} dependencies: '@jridgewell/gen-mapping': 0.1.1 - '@jridgewell/trace-mapping': 0.3.14 + '@jridgewell/trace-mapping': 0.3.15 /@ant-design/colors/6.0.0: resolution: {integrity: sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==} @@ -1021,7 +1315,7 @@ packages: conventional-changelog-conventionalcommits: 4.6.3 dev: true - /@applint/eslint-config/1.1.8_dhthnkasvnjsxo7ami3aqpfe6y: + /@applint/eslint-config/1.1.8_rdkfluwvl27q5zjpxyid6eowjm: resolution: {integrity: sha512-HOJIPICipY2KXglNVjc+gsH0MTaJy0t6lk18KbvYczpSGplM8QrXlrtvSVJbJApCJUa5l/S22N8/SlOGcMWwjQ==} peerDependencies: '@typescript-eslint/eslint-plugin': '>=5.0.0' @@ -1032,14 +1326,14 @@ packages: eslint-plugin-react: '>=7.26.1' eslint-plugin-react-hooks: '>=4.2.0' dependencies: - '@typescript-eslint/eslint-plugin': 5.33.0_njno5y7ry2l2lcmiu4tywxkwnq - '@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq - eslint: 8.21.0 - eslint-plugin-import: 2.26.0_qfqnhzzittf54udqwes54xx65q - eslint-plugin-jsx-a11y: 6.6.1_eslint@8.21.0 + '@typescript-eslint/eslint-plugin': 5.33.0_utqslv3yrrmokmopolieguuyui + '@typescript-eslint/parser': 5.33.0_sorwav4hsh5vncerguqybud76i + eslint: 8.23.0 + eslint-plugin-import: 2.26.0_2oek2lsxxydv5vqayc4g7edtsi + eslint-plugin-jsx-a11y: 6.6.1_eslint@8.23.0 eslint-plugin-jsx-plus: 0.1.0 - eslint-plugin-react: 7.30.1_eslint@8.21.0 - eslint-plugin-react-hooks: 4.6.0_eslint@8.21.0 + eslint-plugin-react: 7.30.1_eslint@8.23.0 + eslint-plugin-react-hooks: 4.6.0_eslint@8.23.0 transitivePeerDependencies: - supports-color - typescript @@ -1049,7 +1343,7 @@ packages: resolution: {integrity: sha512-E9j36XUQQ61ghAzosPORABOB8GGMtZ/ZRHOBjsQ7Cr4PgU7zhNbClsoaie6wimRSZfOt9OUR/rAPR4u3rY43Hg==} dev: true - /@applint/spec/1.2.3_6hnv5syfqtznzbamotbjuefldu: + /@applint/spec/1.2.3_wpfjmk7pkvc77ookm5durpydpe: resolution: {integrity: sha512-6Wx4FHYB71NYywVi7zu1JAkRCGP73bH1mjQIHVhTp0JWenC0bs1210ofjrjwJntuRYMc+JF22XA1YVwbiRmXbw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1057,31 +1351,31 @@ packages: stylelint: '>=14.0.0' dependencies: '@applint/commitlint-config': 1.0.2 - '@applint/eslint-config': 1.1.8_dhthnkasvnjsxo7ami3aqpfe6y + '@applint/eslint-config': 1.1.8_rdkfluwvl27q5zjpxyid6eowjm '@applint/prettier-config': 1.0.1 '@applint/stylelint-config': 1.0.2_sxsdq5quf36cxl3eayzfgd5vbm '@babel/core': 7.18.10 - '@babel/eslint-parser': 7.18.9_xqt7ek4fk233nrovqiamjvck4u + '@babel/eslint-parser': 7.18.9_vpm4f2cg7baehg25txksxfh2hy '@babel/preset-react': 7.18.6_@babel+core@7.18.10 - '@typescript-eslint/eslint-plugin': 5.33.0_njno5y7ry2l2lcmiu4tywxkwnq - '@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + '@typescript-eslint/eslint-plugin': 5.33.0_utqslv3yrrmokmopolieguuyui + '@typescript-eslint/parser': 5.33.0_sorwav4hsh5vncerguqybud76i deepmerge: 4.2.2 - eslint: 8.21.0 - eslint-config-ali: 13.1.0_eslint@8.21.0 - eslint-plugin-import: 2.26.0_qfqnhzzittf54udqwes54xx65q - eslint-plugin-jsx-a11y: 6.6.1_eslint@8.21.0 + eslint: 8.23.0 + eslint-config-ali: 13.1.0_eslint@8.23.0 + eslint-plugin-import: 2.26.0_2oek2lsxxydv5vqayc4g7edtsi + eslint-plugin-jsx-a11y: 6.6.1_eslint@8.23.0 eslint-plugin-jsx-plus: 0.1.0 eslint-plugin-rax-compile-time-miniapp: 1.0.0 - eslint-plugin-react: 7.30.1_eslint@8.21.0 - eslint-plugin-react-hooks: 4.6.0_eslint@8.21.0 - eslint-plugin-vue: 8.7.1_eslint@8.21.0 + eslint-plugin-react: 7.30.1_eslint@8.23.0 + eslint-plugin-react-hooks: 4.6.0_eslint@8.23.0 + eslint-plugin-vue: 8.7.1_eslint@8.23.0 postcss: 8.4.16 postcss-less: 6.0.0_postcss@8.4.16 postcss-scss: 4.0.4_postcss@8.4.16 require-all: 3.0.0 stylelint: 14.10.0 stylelint-scss: 4.3.0_stylelint@14.10.0 - vue-eslint-parser: 8.3.0_eslint@8.21.0 + vue-eslint-parser: 8.3.0_eslint@8.23.0 transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -1129,8 +1423,13 @@ packages: dev: false /@babel/compat-data/7.18.8: - resolution: {integrity: sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==} + resolution: {integrity: sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/@babel/compat-data/-/compat-data-7.18.8.tgz} + engines: {node: '>=6.9.0'} + + /@babel/compat-data/7.19.1: + resolution: {integrity: sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==} engines: {node: '>=6.9.0'} + dev: false /@babel/core/7.12.9: resolution: {integrity: sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==} @@ -1156,7 +1455,7 @@ packages: - supports-color /@babel/core/7.18.10: - resolution: {integrity: sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==} + resolution: {integrity: sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/@babel/core/-/core-7.18.10.tgz} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.0 @@ -1200,7 +1499,30 @@ packages: - supports-color dev: false - /@babel/eslint-parser/7.18.9_xqt7ek4fk233nrovqiamjvck4u: + /@babel/core/7.19.1: + resolution: {integrity: sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.19.0 + '@babel/helper-compilation-targets': 7.19.1_@babel+core@7.19.1 + '@babel/helper-module-transforms': 7.19.0 + '@babel/helpers': 7.19.0 + '@babel/parser': 7.19.1 + '@babel/template': 7.18.10 + '@babel/traverse': 7.19.1 + '@babel/types': 7.19.0 + convert-source-map: 1.8.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.1 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/eslint-parser/7.18.9_vpm4f2cg7baehg25txksxfh2hy: resolution: {integrity: sha512-KzSGpMBggz4fKbRbWLNyPVTuQr6cmCcBhOyXTw/fieOVaw5oYAwcAj4a7UKcDYCPxQq+CG1NCDZH9e2JTXquiQ==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: @@ -1208,7 +1530,7 @@ packages: eslint: ^7.5.0 || ^8.0.0 dependencies: '@babel/core': 7.18.10 - eslint: 8.21.0 + eslint: 8.23.0 eslint-scope: 5.1.1 eslint-visitor-keys: 2.1.0 semver: 6.3.0 @@ -1223,7 +1545,7 @@ packages: jsesc: 2.5.2 /@babel/generator/7.18.12: - resolution: {integrity: sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==} + resolution: {integrity: sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/@babel/generator/-/generator-7.18.12.tgz} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.18.10 @@ -1239,6 +1561,15 @@ packages: jsesc: 2.5.2 dev: false + /@babel/generator/7.19.0: + resolution: {integrity: sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.19.0 + '@jridgewell/gen-mapping': 0.3.2 + jsesc: 2.5.2 + dev: false + /@babel/helper-annotate-as-pure/7.16.7: resolution: {integrity: sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==} engines: {node: '>=6.9.0'} @@ -1280,7 +1611,7 @@ packages: dev: false /@babel/helper-compilation-targets/7.18.9_@babel+core@7.18.10: - resolution: {integrity: sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==} + resolution: {integrity: sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1291,6 +1622,19 @@ packages: browserslist: 4.21.3 semver: 6.3.0 + /@babel/helper-compilation-targets/7.19.1_@babel+core@7.19.1: + resolution: {integrity: sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.19.1 + '@babel/core': 7.19.1 + '@babel/helper-validator-option': 7.18.6 + browserslist: 4.21.3 + semver: 6.3.0 + dev: false + /@babel/helper-create-class-features-plugin/7.18.0_@babel+core@7.18.2: resolution: {integrity: sha512-Kh8zTGR9de3J63e5nS0rQUdRs/kbtwoeQQ0sriS0lItjC96u8XXZN6lKpuyWd2coKSU13py/y+LTmThLuVX0Pg==} engines: {node: '>=6.9.0'} @@ -1427,6 +1771,14 @@ packages: '@babel/template': 7.18.10 '@babel/types': 7.18.10 + /@babel/helper-function-name/7.19.0: + resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.18.10 + '@babel/types': 7.19.0 + dev: false + /@babel/helper-hoist-variables/7.16.7: resolution: {integrity: sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==} engines: {node: '>=6.9.0'} @@ -1438,7 +1790,7 @@ packages: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.10 + '@babel/types': 7.19.0 /@babel/helper-member-expression-to-functions/7.17.7: resolution: {integrity: sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw==} @@ -1464,7 +1816,7 @@ packages: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.10 + '@babel/types': 7.19.0 /@babel/helper-module-transforms/7.18.0: resolution: {integrity: sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==} @@ -1497,6 +1849,22 @@ packages: transitivePeerDependencies: - supports-color + /@babel/helper-module-transforms/7.19.0: + resolution: {integrity: sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-simple-access': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-validator-identifier': 7.18.6 + '@babel/template': 7.18.10 + '@babel/traverse': 7.19.1 + '@babel/types': 7.19.0 + transitivePeerDependencies: + - supports-color + dev: false + /@babel/helper-optimise-call-expression/7.16.7: resolution: {integrity: sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==} engines: {node: '>=6.9.0'} @@ -1593,7 +1961,7 @@ packages: resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.10 + '@babel/types': 7.19.0 /@babel/helper-skip-transparent-expression-wrappers/7.16.0: resolution: {integrity: sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==} @@ -1619,7 +1987,7 @@ packages: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.10 + '@babel/types': 7.19.0 /@babel/helper-string-parser/7.18.10: resolution: {integrity: sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==} @@ -1686,6 +2054,17 @@ packages: transitivePeerDependencies: - supports-color + /@babel/helpers/7.19.0: + resolution: {integrity: sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.18.10 + '@babel/traverse': 7.19.1 + '@babel/types': 7.19.0 + transitivePeerDependencies: + - supports-color + dev: false + /@babel/highlight/7.17.9: resolution: {integrity: sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==} engines: {node: '>=6.9.0'} @@ -1733,6 +2112,13 @@ packages: '@babel/types': 7.18.4 dev: false + /@babel/parser/7.19.1: + resolution: {integrity: sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.19.0 + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.17.12_@babel+core@7.18.2: resolution: {integrity: sha512-xCJQXl4EeQ3J9C4yOmpTrtVGmzpm2iSzyxbkZHw7UCnZBftHpF/hpII80uWVyVrc40ytIClHjgWGTG1g/yB+aw==} engines: {node: '>=6.9.0'} @@ -1876,6 +2262,17 @@ packages: '@babel/helper-plugin-utils': 7.18.9 '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.18.10 + /@babel/plugin-proposal-export-default-from/7.18.10_@babel+core@7.18.10: + resolution: {integrity: sha512-5H2N3R2aQFxkV4PIBUR/i7PUSwgTZjouJKzI8eKswfIjT0PhvzkPn0t0wIS5zn6maQuvtT0t1oHtMUz61LOuow==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.18.10.tgz} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.18.9 + '@babel/plugin-syntax-export-default-from': 7.18.6_@babel+core@7.18.10 + dev: false + /@babel/plugin-proposal-export-namespace-from/7.17.12_@babel+core@7.18.2: resolution: {integrity: sha512-j7Ye5EWdwoXOpRmo5QmRyHPsDIe6+u70ZYZrd7uz+ebPYFKfRcLcNu3Ro0vOlJ5zuv8rU7xa+GttNiRzX56snQ==} engines: {node: '>=6.9.0'} @@ -2164,6 +2561,15 @@ packages: '@babel/helper-plugin-utils': 7.17.12 dev: false + /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.18.10: + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.18.9 + dev: true + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.18.10: resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: @@ -2217,6 +2623,16 @@ packages: '@babel/helper-plugin-utils': 7.16.7 dev: false + /@babel/plugin-syntax-export-default-from/7.18.6_@babel+core@7.18.10: + resolution: {integrity: sha512-Kr//z3ujSVNx6E9z9ih5xXXMqK07VVTuqPmqGe6Mss/zW5XPeLZeSDZoP9ab/hT4wPKqAgjl2PnhPrcpk8Seew==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.18.6.tgz} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.18.9 + dev: false + /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.18.10: resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} peerDependencies: @@ -2253,6 +2669,15 @@ packages: '@babel/core': 7.18.10 '@babel/helper-plugin-utils': 7.18.9 + /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.18.10: + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.18.9 + dev: true + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.18.10: resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: @@ -3045,6 +3470,26 @@ packages: '@babel/core': 7.18.10 '@babel/plugin-transform-react-jsx': 7.18.10_@babel+core@7.18.10 + /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.18.10: + resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.18.9 + dev: true + + /@babel/plugin-transform-react-jsx-source/7.18.6_@babel+core@7.18.10: + resolution: {integrity: sha512-utZmlASneDfdaMh0m/WausbjUjEdGrQJz0vFK93d7wD3xf5wBtX219+q6IlCNZeguIcxS2f/CvLZrlLSvSHQXw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.18.9 + dev: true + /@babel/plugin-transform-react-jsx/7.17.3_@babel+core@7.18.2: resolution: {integrity: sha512-9tjBm4O07f7mzKSIlEmPdiE6ub7kfIe6Cd+w+oQebpATfTQMAgW+YOuWxogbKVTulA+MEO7byMeIUtQ1z+z+ZQ==} engines: {node: '>=6.9.0'} @@ -3577,8 +4022,8 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/parser': 7.18.11 - '@babel/types': 7.18.10 + '@babel/parser': 7.19.1 + '@babel/types': 7.19.0 /@babel/traverse/7.18.10: resolution: {integrity: sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g==} @@ -3633,6 +4078,24 @@ packages: - supports-color dev: false + /@babel/traverse/7.19.1: + resolution: {integrity: sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.19.0 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.19.1 + '@babel/types': 7.19.0 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: false + /@babel/types/7.17.0: resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==} engines: {node: '>=6.9.0'} @@ -3656,108 +4119,18 @@ packages: '@babel/helper-validator-identifier': 7.16.7 to-fast-properties: 2.0.0 + /@babel/types/7.19.0: + resolution: {integrity: sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.18.10 + '@babel/helper-validator-identifier': 7.18.6 + to-fast-properties: 2.0.0 + /@bcoe/v8-coverage/0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true - /@builder/swc-darwin-arm64/0.2.0: - resolution: {integrity: sha512-+nmnScnq40eMKqCLpVwl7P/JCHrzm9q1ECvD/nGTNATweMB0hhTjX7V/5DfHELl1RHGnw7NchAuVJDesNa9daw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@builder/swc-darwin-x64/0.2.0: - resolution: {integrity: sha512-vR9H+o5WmrasoAgMmL9HA2DfUosreGt0Pak54iOIyu3V6hSXaLxKuSidqEMcWBG1nN2wEYBvlzP8s04WusqPRQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@builder/swc-linux-arm64-gnu/0.2.0: - resolution: {integrity: sha512-O18+aSQ7ZGcBwongjsatQ7OcJo9D0YDsBujPkQfQ0sBwnxmzGTw4kkXHr/K9Bou9wcy8TEpXRfaauaLHzzecAA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@builder/swc-linux-arm64-musl/0.2.0: - resolution: {integrity: sha512-0vkGpqmJNOfsWh7qb3Mqga0gJPsAomxPitWapRlFQ736Q0qHL4Bb270/VZO3xcjA0zZKaN8VdwVw+Pxqg3ziQA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@builder/swc-linux-x64-gnu/0.2.0: - resolution: {integrity: sha512-6gPaiwQq1l/eeNthOBvWInHU5i2bfbnGuw4YDsTF2pHhbHd7eR++N5viTROJLjFaZevWrNUbfMc47IMRGQg7WA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@builder/swc-linux-x64-musl/0.2.0: - resolution: {integrity: sha512-01zpp3sHM48x1Tl1fzM6si1E6ZIooJkXts+vPu36v265gXEb1winhFHCXXtQXvSHZ/XEyRFD1BcgdCm3goSJRw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@builder/swc-win32-arm64-msvc/0.2.0: - resolution: {integrity: sha512-+06kFldeVV1Yzy2tfkeClwsglW50j6qG2vpTA3Tqwp5kEAGFNT1tUwsoWcbySJSCRlGBAVHDZxJlsUMqSK34Yw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@builder/swc-win32-ia32-msvc/0.2.0: - resolution: {integrity: sha512-wc9GA1YWv5ZxVYl73KDdRuX3All8reNIUbtPEKz2LwQ5locUX6gb7pdDzDz0et/xXjshZRGka7wDU2wzgi8Giw==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@builder/swc-win32-x64-msvc/0.2.0: - resolution: {integrity: sha512-l8eMGTigKHrA46HAkXWblYwxQeT/SEe9yKrIYi2kfngWHNUALUFlPnnoJOSmLCGwPRZTHUgcx45Ta+15ahj5DQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@builder/swc/0.2.0: - resolution: {integrity: sha512-XYo9NCDQ8i8wG6TwrO+zxevJ6Icuj+F+LlwN5SP5lFC8foqi04gtY6Ogu3jKGW9YsfZLZ25ExhY03uFoy87dHg==} - engines: {node: '>= 12'} - dependencies: - '@napi-rs/triples': 1.1.0 - optionalDependencies: - '@builder/swc-darwin-arm64': 0.2.0 - '@builder/swc-darwin-x64': 0.2.0 - '@builder/swc-linux-arm64-gnu': 0.2.0 - '@builder/swc-linux-arm64-musl': 0.2.0 - '@builder/swc-linux-x64-gnu': 0.2.0 - '@builder/swc-linux-x64-musl': 0.2.0 - '@builder/swc-win32-arm64-msvc': 0.2.0 - '@builder/swc-win32-ia32-msvc': 0.2.0 - '@builder/swc-win32-x64-msvc': 0.2.0 - dev: true - /@colors/colors/1.5.0: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} @@ -4766,7 +5139,7 @@ packages: peerDependencies: react: '*' dependencies: - '@types/react': 18.0.17 + '@types/react': 18.0.20 prop-types: 15.8.1 react: 17.0.2 @@ -5189,6 +5562,27 @@ packages: - webpack-cli dev: false + /@esbuild-kit/cjs-loader/2.3.3: + resolution: {integrity: sha512-Rt4O1mXlPEDVxvjsHLgbtHVdUXYK9C1/6ThpQnt7FaXIjUOsI6qhHYMgALhNnlIMZffag44lXd6Dqgx3xALbpQ==} + dependencies: + '@esbuild-kit/core-utils': 2.3.0 + get-tsconfig: 4.2.0 + dev: true + + /@esbuild-kit/core-utils/2.3.0: + resolution: {integrity: sha512-JL73zt/LN/qqziHuod4/bM2xBNNofDZu1cbwT6KIn6B11lA4cgDXkoSHOfNCbZMZOnh0Aqf0vW/gNQC+Z18hKQ==} + dependencies: + esbuild: 0.15.5 + source-map-support: 0.5.21 + dev: true + + /@esbuild-kit/esm-loader/2.4.2: + resolution: {integrity: sha512-N9dPKAj8WOx6djVnStgILWXip4fjDcBk9L7azO0/uQDpu8Ee0eaL78mkN4Acid9BzvNAKWwdYXFJZnsVahNEew==} + dependencies: + '@esbuild-kit/core-utils': 2.3.0 + get-tsconfig: 4.2.0 + dev: true + /@esbuild/linux-loong64/0.14.54: resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} engines: {node: '>=12'} @@ -5197,8 +5591,8 @@ packages: requiresBuild: true optional: true - /@esbuild/linux-loong64/0.15.1: - resolution: {integrity: sha512-1tORADNFK9QS4KYyUyh3Td9WGrdiI1rSoKvY6A43+9G0kPujBuT4lIGyoK0AweOSO1aRIR28xQUfiJCUa78bUw==} + /@esbuild/linux-loong64/0.15.5: + resolution: {integrity: sha512-UHkDFCfSGTuXq08oQltXxSZmH1TXyWsL+4QhZDWvvLl6mEJQqk3u7/wq1LjhrrAXYIllaTtRSzUXl4Olkf2J8A==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -5223,13 +5617,13 @@ packages: - supports-color dev: true - /@eslint/eslintrc/1.3.0: - resolution: {integrity: sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==} + /@eslint/eslintrc/1.3.1: + resolution: {integrity: sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 debug: 4.3.4 - espree: 9.3.3 + espree: 9.4.0 globals: 13.17.0 ignore: 5.2.0 import-fresh: 3.3.0 @@ -5288,6 +5682,11 @@ packages: resolution: {integrity: sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==} dev: true + /@humanwhocodes/module-importer/1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + /@humanwhocodes/object-schema/1.2.1: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true @@ -5351,55 +5750,504 @@ packages: - react-native dev: false + /@ice/swc-plugin-keep-export/0.1.1: + resolution: {integrity: sha512-FjBZV6msseDZ+g1DmS8qTQADDK646A7jWZpSbJ15Z0QX0KTmNwSCzb061nj7p7EW3xOW6N2cGNdGV6+TENb7Jg==} + dev: false + /@ice/swc-plugin-keep-platform/0.1.0: resolution: {integrity: sha512-y9ckEmUBr6e6dzYzHVAV/+WMhBcHkOGnIiIQh91cTm1ZlGq5gMEbJDQJh/0ucacBrMpWNCPDvJwsBvqHZDVIdQ==} dev: false /@ice/swc-plugin-remove-export/0.1.0: - resolution: {integrity: sha512-L3dSLxJ2b+u8tEF5ISYzpqYMRTfKHwtTlfdKHUWHqK+z8gIUwsqB28SfkGbHlRFPhjlvE+5zP727lsbC3uED5g==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/@ice/swc-plugin-remove-export/-/swc-plugin-remove-export-0.1.0.tgz} + resolution: {integrity: sha512-L3dSLxJ2b+u8tEF5ISYzpqYMRTfKHwtTlfdKHUWHqK+z8gIUwsqB28SfkGbHlRFPhjlvE+5zP727lsbC3uED5g==} dev: false + /@istanbuljs/load-nyc-config/1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + /@istanbuljs/schema/0.1.3: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} dev: true - /@jridgewell/gen-mapping/0.1.1: - resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} - engines: {node: '>=6.0.0'} + /@jest/console/28.1.3: + resolution: {integrity: sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.14 + '@jest/types': 28.1.3 + '@types/node': 17.0.45 + chalk: 4.1.2 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + slash: 3.0.0 + dev: true - /@jridgewell/gen-mapping/0.3.1: - resolution: {integrity: sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==} - engines: {node: '>=6.0.0'} + /@jest/console/29.0.3: + resolution: {integrity: sha512-cGg0r+klVHSYnfE977S9wmpuQ9L+iYuYgL+5bPXiUlUynLLYunRxswEmhBzvrSKGof5AKiHuTTmUKAqRcDY9dg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jridgewell/set-array': 1.1.1 - '@jridgewell/sourcemap-codec': 1.4.11 - '@jridgewell/trace-mapping': 0.3.9 - dev: false + '@jest/types': 29.0.3 + '@types/node': 17.0.45 + chalk: 4.1.2 + jest-message-util: 29.0.3 + jest-util: 29.0.3 + slash: 3.0.0 + dev: true - /@jridgewell/gen-mapping/0.3.2: - resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} - engines: {node: '>=6.0.0'} + /@jest/core/28.1.3: + resolution: {integrity: sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.14 - '@jridgewell/trace-mapping': 0.3.14 + '@jest/console': 28.1.3 + '@jest/reporters': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 17.0.45 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.4.0 + exit: 0.1.2 + graceful-fs: 4.2.10 + jest-changed-files: 28.1.3 + jest-config: 28.1.3_@types+node@17.0.45 + jest-haste-map: 28.1.3 + jest-message-util: 28.1.3 + jest-regex-util: 28.0.2 + jest-resolve: 28.1.3 + jest-resolve-dependencies: 28.1.3 + jest-runner: 28.1.3 + jest-runtime: 28.1.3 + jest-snapshot: 28.1.3 + jest-util: 28.1.3 + jest-validate: 28.1.3 + jest-watcher: 28.1.3 + micromatch: 4.0.5 + pretty-format: 28.1.3 + rimraf: 3.0.2 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true - /@jridgewell/resolve-uri/3.1.0: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} - engines: {node: '>=6.0.0'} + /@jest/core/29.0.3: + resolution: {integrity: sha512-1d0hLbOrM1qQE3eP3DtakeMbKTcXiXP3afWxqz103xPyddS2NhnNghS7MaXx1dcDt4/6p4nlhmeILo2ofgi8cQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/console': 29.0.3 + '@jest/reporters': 29.0.3 + '@jest/test-result': 29.0.3 + '@jest/transform': 29.0.3 + '@jest/types': 29.0.3 + '@types/node': 17.0.45 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.4.0 + exit: 0.1.2 + graceful-fs: 4.2.10 + jest-changed-files: 29.0.0 + jest-config: 29.0.3_@types+node@17.0.45 + jest-haste-map: 29.0.3 + jest-message-util: 29.0.3 + jest-regex-util: 29.0.0 + jest-resolve: 29.0.3 + jest-resolve-dependencies: 29.0.3 + jest-runner: 29.0.3 + jest-runtime: 29.0.3 + jest-snapshot: 29.0.3 + jest-util: 29.0.3 + jest-validate: 29.0.3 + jest-watcher: 29.0.3 + micromatch: 4.0.5 + pretty-format: 29.0.3 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true - /@jridgewell/set-array/1.1.1: - resolution: {integrity: sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==} - engines: {node: '>=6.0.0'} - dev: false + /@jest/environment/28.1.3: + resolution: {integrity: sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/fake-timers': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 17.0.45 + jest-mock: 28.1.3 + dev: true - /@jridgewell/set-array/1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} + /@jest/environment/29.0.3: + resolution: {integrity: sha512-iKl272NKxYNQNqXMQandAIwjhQaGw5uJfGXduu8dS9llHi8jV2ChWrtOAVPnMbaaoDhnI3wgUGNDvZgHeEJQCA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/fake-timers': 29.0.3 + '@jest/types': 29.0.3 + '@types/node': 17.0.45 + jest-mock: 29.0.3 + dev: true + + /@jest/expect-utils/28.1.3: + resolution: {integrity: sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + jest-get-type: 28.0.2 + dev: true + + /@jest/expect-utils/29.0.3: + resolution: {integrity: sha512-i1xUkau7K/63MpdwiRqaxgZOjxYs4f0WMTGJnYwUKubsNRZSeQbLorS7+I4uXVF9KQ5r61BUPAUMZ7Lf66l64Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.0.0 + dev: true + + /@jest/expect/28.1.3: + resolution: {integrity: sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + expect: 28.1.3 + jest-snapshot: 28.1.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/expect/29.0.3: + resolution: {integrity: sha512-6W7K+fsI23FQ01H/BWccPyDZFrnU9QlzDcKOjrNVU5L8yUORFAJJIpmyxWPW70+X624KUNqzZwPThPMX28aXEQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + expect: 29.0.3 + jest-snapshot: 29.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/fake-timers/28.1.3: + resolution: {integrity: sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + '@sinonjs/fake-timers': 9.1.2 + '@types/node': 17.0.45 + jest-message-util: 28.1.3 + jest-mock: 28.1.3 + jest-util: 28.1.3 + dev: true + + /@jest/fake-timers/29.0.3: + resolution: {integrity: sha512-tmbUIo03x0TdtcZCESQ0oQSakPCpo7+s6+9mU19dd71MptkP4zCwoeZqna23//pgbhtT1Wq02VmA9Z9cNtvtCQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.0.3 + '@sinonjs/fake-timers': 9.1.2 + '@types/node': 17.0.45 + jest-message-util: 29.0.3 + jest-mock: 29.0.3 + jest-util: 29.0.3 + dev: true + + /@jest/globals/28.1.3: + resolution: {integrity: sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/environment': 28.1.3 + '@jest/expect': 28.1.3 + '@jest/types': 28.1.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/globals/29.0.3: + resolution: {integrity: sha512-YqGHT65rFY2siPIHHFjuCGUsbzRjdqkwbat+Of6DmYRg5shIXXrLdZoVE/+TJ9O1dsKsFmYhU58JvIbZRU1Z9w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.0.3 + '@jest/expect': 29.0.3 + '@jest/types': 29.0.3 + jest-mock: 29.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/reporters/28.1.3: + resolution: {integrity: sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + '@jridgewell/trace-mapping': 0.3.15 + '@types/node': 17.0.45 + chalk: 4.1.2 + collect-v8-coverage: 1.0.1 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-instrument: 5.2.0 + istanbul-lib-report: 3.0.0 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.5 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + jest-worker: 28.1.3 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + terminal-link: 2.1.1 + v8-to-istanbul: 9.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/reporters/29.0.3: + resolution: {integrity: sha512-3+QU3d4aiyOWfmk1obDerie4XNCaD5Xo1IlKNde2yGEi02WQD+ZQD0i5Hgqm1e73sMV7kw6pMlCnprtEwEVwxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.0.3 + '@jest/test-result': 29.0.3 + '@jest/transform': 29.0.3 + '@jest/types': 29.0.3 + '@jridgewell/trace-mapping': 0.3.15 + '@types/node': 17.0.45 + chalk: 4.1.2 + collect-v8-coverage: 1.0.1 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-instrument: 5.2.0 + istanbul-lib-report: 3.0.0 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.5 + jest-message-util: 29.0.3 + jest-util: 29.0.3 + jest-worker: 29.0.3 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + terminal-link: 2.1.1 + v8-to-istanbul: 9.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/schemas/28.1.3: + resolution: {integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@sinclair/typebox': 0.24.41 + dev: true + + /@jest/schemas/29.0.0: + resolution: {integrity: sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.24.41 + dev: true + + /@jest/source-map/28.1.2: + resolution: {integrity: sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jridgewell/trace-mapping': 0.3.15 + callsites: 3.1.0 + graceful-fs: 4.2.10 + dev: true + + /@jest/source-map/29.0.0: + resolution: {integrity: sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jridgewell/trace-mapping': 0.3.15 + callsites: 3.1.0 + graceful-fs: 4.2.10 + dev: true + + /@jest/test-result/28.1.3: + resolution: {integrity: sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/console': 28.1.3 + '@jest/types': 28.1.3 + '@types/istanbul-lib-coverage': 2.0.4 + collect-v8-coverage: 1.0.1 + dev: true + + /@jest/test-result/29.0.3: + resolution: {integrity: sha512-vViVnQjCgTmbhDKEonKJPtcFe9G/CJO4/Np4XwYJah+lF2oI7KKeRp8t1dFvv44wN2NdbDb/qC6pi++Vpp0Dlg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.0.3 + '@jest/types': 29.0.3 + '@types/istanbul-lib-coverage': 2.0.4 + collect-v8-coverage: 1.0.1 + dev: true + + /@jest/test-sequencer/28.1.3: + resolution: {integrity: sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/test-result': 28.1.3 + graceful-fs: 4.2.10 + jest-haste-map: 28.1.3 + slash: 3.0.0 + dev: true + + /@jest/test-sequencer/29.0.3: + resolution: {integrity: sha512-Hf4+xYSWZdxTNnhDykr8JBs0yBN/nxOXyUQWfotBUqqy0LF9vzcFB0jm/EDNZCx587znLWTIgxcokW7WeZMobQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.0.3 + graceful-fs: 4.2.10 + jest-haste-map: 29.0.3 + slash: 3.0.0 + dev: true + + /@jest/transform/28.1.3: + resolution: {integrity: sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@babel/core': 7.18.10 + '@jest/types': 28.1.3 + '@jridgewell/trace-mapping': 0.3.15 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 1.8.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.10 + jest-haste-map: 28.1.3 + jest-regex-util: 28.0.2 + jest-util: 28.1.3 + micromatch: 4.0.5 + pirates: 4.0.5 + slash: 3.0.0 + write-file-atomic: 4.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/transform/29.0.3: + resolution: {integrity: sha512-C5ihFTRYaGDbi/xbRQRdbo5ddGtI4VSpmL6AIcZxdhwLbXMa7PcXxxqyI91vGOFHnn5aVM3WYnYKCHEqmLVGzg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.18.10 + '@jest/types': 29.0.3 + '@jridgewell/trace-mapping': 0.3.15 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 1.8.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.10 + jest-haste-map: 29.0.3 + jest-regex-util: 29.0.0 + jest-util: 29.0.3 + micromatch: 4.0.5 + pirates: 4.0.5 + slash: 3.0.0 + write-file-atomic: 4.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/types/28.1.3: + resolution: {integrity: sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/schemas': 28.1.3 + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 17.0.45 + '@types/yargs': 17.0.12 + chalk: 4.1.2 + dev: true + + /@jest/types/29.0.3: + resolution: {integrity: sha512-coBJmOQvurXjN1Hh5PzF7cmsod0zLIOXpP8KD161mqNlroMhLcwpODiEzi7ZsRl5Z/AIuxpeNm8DCl43F4kz8A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.0.0 + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 17.0.45 + '@types/yargs': 17.0.12 + chalk: 4.1.2 + dev: true + + /@jridgewell/gen-mapping/0.1.1: + resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + + /@jridgewell/gen-mapping/0.3.1: + resolution: {integrity: sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.1 + '@jridgewell/sourcemap-codec': 1.4.11 + '@jridgewell/trace-mapping': 0.3.9 + dev: false + + /@jridgewell/gen-mapping/0.3.2: + resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/trace-mapping': 0.3.15 + + /@jridgewell/resolve-uri/3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + + /@jridgewell/set-array/1.1.1: + resolution: {integrity: sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==} + engines: {node: '>=6.0.0'} + dev: false + + /@jridgewell/set-array/1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + + /@jridgewell/source-map/0.3.2: + resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} + dependencies: + '@jridgewell/gen-mapping': 0.3.2 + '@jridgewell/trace-mapping': 0.3.14 /@jridgewell/sourcemap-codec/1.4.11: resolution: {integrity: sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==} @@ -5414,6 +6262,12 @@ packages: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 + /@jridgewell/trace-mapping/0.3.15: + resolution: {integrity: sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + /@jridgewell/trace-mapping/0.3.9: resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} dependencies: @@ -5459,10 +6313,6 @@ packages: /@mdx-js/util/1.6.22: resolution: {integrity: sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==} - /@napi-rs/triples/1.1.0: - resolution: {integrity: sha512-XQr74QaLeMiqhStEhLn1im9EOMnkypp7MZOwQhGzqp2Weu5eQJbpPxWxixxlYRKWPOmJjsk6qYfYH9kq43yc2w==} - dev: true - /@node-rs/jieba-android-arm-eabi/1.6.1: resolution: {integrity: sha512-R1YQfsPr7sK3Tq1sM0//6lNAGJK9RnMT0ShITT+7EJYr5OufUBb38lf/mRhrLxR0NF1pycEsMjdCAwrWrHd8rA==} engines: {node: '>= 10'} @@ -5522,6 +6372,7 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] requiresBuild: true dev: false optional: true @@ -5531,6 +6382,7 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] requiresBuild: true dev: false optional: true @@ -5540,6 +6392,7 @@ packages: engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] requiresBuild: true dev: false optional: true @@ -5549,6 +6402,7 @@ packages: engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] requiresBuild: true dev: false optional: true @@ -5633,7 +6487,7 @@ packages: rimraf: 3.0.2 dev: true - /@pmmmwh/react-refresh-webpack-plugin/0.5.7_co3pwf5d42rd2rqpmthdozfyry: + /@pmmmwh/react-refresh-webpack-plugin/0.5.7_blviz2256hckjssg6tjpu76wzi: resolution: {integrity: sha512-bcKCAzF0DV2IIROp9ZHkRJa6O4jy7NlnHdWL3GmcUxYWNjLXkK5kfELELwEfSP5hXPfVL/qOGMAROuMQb9GG8Q==} engines: {node: '>= 10.13'} peerDependencies: @@ -5661,17 +6515,17 @@ packages: dependencies: ansi-html-community: 0.0.8 common-path-prefix: 3.0.0 - core-js-pure: 3.22.2 + core-js-pure: 3.24.1 error-stack-parser: 2.0.7 find-up: 5.0.0 html-entities: 2.3.3 loader-utils: 2.0.2 - react-refresh: 0.12.0 + react-refresh: 0.14.0 schema-utils: 3.1.1 source-map: 0.7.3 - webpack: 5.73.0_ohfecwmx44wixok6ry5c6snfbe - webpack-dev-server: 4.8.1_webpack@5.73.0 - dev: false + webpack: 5.74.0_@swc+core@1.2.210 + webpack-dev-server: 4.10.0_webpack@5.74.0 + dev: true /@polka/url/1.0.0-next.21: resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} @@ -5801,10 +6655,26 @@ packages: /@sideway/pinpoint/2.0.0: resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + /@sinclair/typebox/0.24.41: + resolution: {integrity: sha512-TJCgQurls4FipFvHeC+gfAzb+GGstL0TDwYJKQVtTeSvJIznWzP7g3bAd5gEBlr8+bIxqnWS9VGVWREDhmE8jA==} + dev: true + /@sindresorhus/is/0.14.0: resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==} engines: {node: '>=6'} + /@sinonjs/commons/1.8.3: + resolution: {integrity: sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers/9.1.2: + resolution: {integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==} + dependencies: + '@sinonjs/commons': 1.8.3 + dev: true + /@slorber/static-site-generator-webpack-plugin/4.0.7: resolution: {integrity: sha512-Ug7x6z5lwrz0WqdnNFOMYrDQNTPAprvHLSh6+/fmml3qUiz6l5eq+2MzLKWtn/q5K5NpSiFsZTP/fck/3vjSxA==} engines: {node: '>=14'} @@ -6112,6 +6982,7 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [glibc] requiresBuild: true optional: true @@ -6120,6 +6991,7 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [musl] requiresBuild: true optional: true @@ -6128,6 +7000,7 @@ packages: engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [glibc] requiresBuild: true optional: true @@ -6136,6 +7009,7 @@ packages: engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [musl] requiresBuild: true optional: true @@ -6183,7 +7057,7 @@ packages: '@swc/core-win32-x64-msvc': 1.2.210 /@swc/helpers/0.4.3: - resolution: {integrity: sha512-6JrF+fdUK2zbGpJIlN7G3v966PQjyx/dPt1T9km2wj+EUBqgrxCk3uX4Kct16MIm9gGxfKRcfax2hVf5jvlTzA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/@swc/helpers/-/helpers-0.4.3.tgz} + resolution: {integrity: sha512-6JrF+fdUK2zbGpJIlN7G3v966PQjyx/dPt1T9km2wj+EUBqgrxCk3uX4Kct16MIm9gGxfKRcfax2hVf5jvlTzA==} dependencies: tslib: 2.4.0 dev: false @@ -6208,6 +7082,21 @@ packages: pretty-format: 27.5.1 dev: true + /@testing-library/jest-dom/5.16.5: + resolution: {integrity: sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==} + engines: {node: '>=8', npm: '>=6', yarn: '>=1'} + dependencies: + '@adobe/css-tools': 4.0.1 + '@babel/runtime': 7.18.9 + '@types/testing-library__jest-dom': 5.14.5 + aria-query: 5.0.0 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.5.14 + lodash: 4.17.21 + redent: 3.0.0 + dev: true + /@testing-library/react/13.3.0_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-DB79aA426+deFgGSjnf5grczDPiL4taK3hFaa+M5q7q20Kcve9eQottOG5kZ74KEr55v0tU2CQormSSDK87zYQ==} engines: {node: '>=12'} @@ -6251,12 +7140,29 @@ packages: resolution: {integrity: sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==} dev: true + /@types/babel__core/7.1.19: + resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==} + dependencies: + '@babel/parser': 7.18.11 + '@babel/types': 7.18.10 + '@types/babel__generator': 7.6.4 + '@types/babel__template': 7.4.1 + '@types/babel__traverse': 7.17.1 + dev: true + /@types/babel__generator/7.6.4: resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} dependencies: '@babel/types': 7.18.10 dev: true + /@types/babel__template/7.4.1: + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + dependencies: + '@babel/parser': 7.18.11 + '@babel/types': 7.18.10 + dev: true + /@types/babel__traverse/7.17.1: resolution: {integrity: sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==} dependencies: @@ -6267,12 +7173,12 @@ packages: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 17.0.27 + '@types/node': 17.0.45 /@types/bonjour/3.5.10: resolution: {integrity: sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==} dependencies: - '@types/node': 17.0.27 + '@types/node': 17.0.45 /@types/braces/3.0.1: resolution: {integrity: sha512-+euflG6ygo4bn0JHtn4pYqcXwRtLvElQ7/nnjDu7iYG56H0+OhCd7d6Ug0IE3WcFpZozBKW2+80FUbv5QGk5AQ==} @@ -6298,12 +7204,12 @@ packages: resolution: {integrity: sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==} dependencies: '@types/express-serve-static-core': 4.17.28 - '@types/node': 17.0.27 + '@types/node': 17.0.45 /@types/connect/3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 17.0.27 + '@types/node': 17.0.45 /@types/cross-spawn/6.0.2: resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} @@ -6322,28 +7228,21 @@ packages: /@types/eslint-scope/3.7.3: resolution: {integrity: sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==} dependencies: - '@types/eslint': 8.4.1 - '@types/estree': 0.0.51 + '@types/eslint': 8.4.5 + '@types/estree': 1.0.0 /@types/eslint/7.29.0: resolution: {integrity: sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==} dependencies: - '@types/estree': 0.0.51 + '@types/estree': 1.0.0 '@types/json-schema': 7.0.11 dev: true - /@types/eslint/8.4.1: - resolution: {integrity: sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==} - dependencies: - '@types/estree': 0.0.51 - '@types/json-schema': 7.0.11 - /@types/eslint/8.4.5: resolution: {integrity: sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ==} dependencies: '@types/estree': 1.0.0 '@types/json-schema': 7.0.11 - dev: true /@types/estree/0.0.39: resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} @@ -6354,12 +7253,11 @@ packages: /@types/estree/1.0.0: resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} - dev: true /@types/express-serve-static-core/4.17.28: resolution: {integrity: sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==} dependencies: - '@types/node': 17.0.27 + '@types/node': 17.0.45 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 @@ -6391,6 +7289,12 @@ packages: '@types/node': 17.0.45 dev: true + /@types/graceful-fs/4.1.5: + resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} + dependencies: + '@types/node': 17.0.45 + dev: true + /@types/hast/2.3.4: resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==} dependencies: @@ -6412,17 +7316,44 @@ packages: /@types/http-proxy/1.17.8: resolution: {integrity: sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==} dependencies: - '@types/node': 17.0.27 + '@types/node': 17.0.45 /@types/istanbul-lib-coverage/2.0.4: resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} dev: true - /@types/js-cookie/2.2.7: - resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} - dev: false + /@types/istanbul-lib-report/3.0.0: + resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + dev: true - /@types/json-schema/7.0.11: + /@types/istanbul-reports/3.0.1: + resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + dependencies: + '@types/istanbul-lib-report': 3.0.0 + dev: true + + /@types/jest/29.0.3: + resolution: {integrity: sha512-F6ukyCTwbfsEX5F2YmVYmM5TcTHy1q9P5rWlRbrk56KyMh3v9xRGUO3aa8+SkvMi0SHXtASJv1283enXimC0Og==} + dependencies: + expect: 29.0.3 + pretty-format: 29.0.3 + dev: true + + /@types/js-cookie/2.2.7: + resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} + dev: false + + /@types/jsdom/20.0.0: + resolution: {integrity: sha512-YfAchFs0yM1QPDrLm2VHe+WHGtqms3NXnXAMolrgrVP6fgBHHXy1ozAbo/dFtPNtZC/m66bPiCTWYmqp1F14gA==} + dependencies: + '@types/node': 17.0.45 + '@types/tough-cookie': 4.0.2 + parse5: 7.0.0 + dev: true + + /@types/json-schema/7.0.11: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} /@types/json5/0.0.29: @@ -6494,6 +7425,10 @@ packages: /@types/parse5/5.0.3: resolution: {integrity: sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==} + /@types/prettier/2.7.0: + resolution: {integrity: sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==} + dev: true + /@types/prop-types/15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} @@ -6552,14 +7487,14 @@ packages: resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} dependencies: '@types/history': 4.7.11 - '@types/react': 18.0.17 + '@types/react': 18.0.20 '@types/react-router': 5.1.18 /@types/react-router/5.1.18: resolution: {integrity: sha512-YYknwy0D0iOwKQgz9v8nOzt2J6l4gouBmDnWqUUznltOTaon+r8US8ky8HvN0tXvc38U9m6z/t2RsVsnd1zM0g==} dependencies: '@types/history': 4.7.11 - '@types/react': 18.0.17 + '@types/react': 18.0.20 /@types/react/17.0.48: resolution: {integrity: sha512-zJ6IYlJ8cYYxiJfUaZOQee4lh99mFihBoqkOSEGV+dFi9leROW6+PgstzQ+w3gWTnUfskALtQPGHK6dYmPj+2A==} @@ -6581,6 +7516,14 @@ packages: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.2 csstype: 3.1.0 + dev: true + + /@types/react/18.0.20: + resolution: {integrity: sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA==} + dependencies: + '@types/prop-types': 15.7.5 + '@types/scheduler': 0.16.2 + csstype: 3.1.0 /@types/react/18.0.8: resolution: {integrity: sha512-+j2hk9BzCOrrOSJASi5XiOyBbERk9jG5O73Ya4M0env5Ixi6vUNli4qy994AINcEF+1IEHISYFfIT4zwr++LKw==} @@ -6619,8 +7562,8 @@ packages: /@types/scheduler/0.16.2: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} - /@types/semver/7.3.11: - resolution: {integrity: sha512-R9HhjC4aKx3jL0FLwU7x6qMTysTvLh7jesRslXmxgCOXZwyh5dsnmrPQQToMyess8D4U+8G9x9mBFZoC/1o/Tw==} + /@types/semver/7.3.12: + resolution: {integrity: sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==} dev: true /@types/serve-index/1.9.1: @@ -6632,12 +7575,16 @@ packages: resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==} dependencies: '@types/mime': 1.3.2 - '@types/node': 17.0.27 + '@types/node': 17.0.45 /@types/sockjs/0.3.33: resolution: {integrity: sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==} dependencies: - '@types/node': 17.0.27 + '@types/node': 17.0.45 + + /@types/stack-utils/2.0.1: + resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + dev: true /@types/temp/0.9.1: resolution: {integrity: sha512-yDQ8Y+oQi9V7VkexwE6NBSVyNuyNFeGI275yWXASc2DjmxNicMi9O50KxDpNlST1kBbV9jKYBHGXhgNYFMPqtA==} @@ -6645,6 +7592,16 @@ packages: '@types/node': 17.0.27 dev: true + /@types/testing-library__jest-dom/5.14.5: + resolution: {integrity: sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==} + dependencies: + '@types/jest': 29.0.3 + dev: true + + /@types/tough-cookie/4.0.2: + resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} + dev: true + /@types/unist/2.0.6: resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} @@ -6653,7 +7610,7 @@ packages: dependencies: '@types/node': 17.0.27 tapable: 2.2.1 - webpack: 5.73.0_@swc+core@1.2.210 + webpack: 5.74.0_@swc+core@1.2.210 transitivePeerDependencies: - '@swc/core' - esbuild @@ -6666,7 +7623,7 @@ packages: dependencies: '@types/node': 17.0.27 tapable: 2.2.1 - webpack: 5.72.1 + webpack: 5.74.0 transitivePeerDependencies: - '@swc/core' - esbuild @@ -6677,7 +7634,17 @@ packages: /@types/ws/8.5.3: resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} dependencies: - '@types/node': 17.0.27 + '@types/node': 17.0.45 + + /@types/yargs-parser/21.0.0: + resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + dev: true + + /@types/yargs/17.0.12: + resolution: {integrity: sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==} + dependencies: + '@types/yargs-parser': 21.0.0 + dev: true /@types/yauzl/2.10.0: resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} @@ -6687,7 +7654,7 @@ packages: dev: true optional: true - /@typescript-eslint/eslint-plugin/5.33.0_njno5y7ry2l2lcmiu4tywxkwnq: + /@typescript-eslint/eslint-plugin/5.33.0_utqslv3yrrmokmopolieguuyui: resolution: {integrity: sha512-jHvZNSW2WZ31OPJ3enhLrEKvAZNyAFWZ6rx9tUwaessTc4sx9KmgMNhVcqVAl1ETnT5rU5fpXTLmY9YvC1DCNg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -6698,12 +7665,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + '@typescript-eslint/parser': 5.33.0_sorwav4hsh5vncerguqybud76i '@typescript-eslint/scope-manager': 5.33.0 - '@typescript-eslint/type-utils': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq - '@typescript-eslint/utils': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + '@typescript-eslint/type-utils': 5.33.0_sorwav4hsh5vncerguqybud76i + '@typescript-eslint/utils': 5.33.0_sorwav4hsh5vncerguqybud76i debug: 4.3.4 - eslint: 8.21.0 + eslint: 8.23.0 functional-red-black-tree: 1.0.1 ignore: 5.2.0 regexpp: 3.2.0 @@ -6714,7 +7681,7 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq: + /@typescript-eslint/parser/5.33.0_sorwav4hsh5vncerguqybud76i: resolution: {integrity: sha512-cgM5cJrWmrDV2KpvlcSkelTBASAs1mgqq+IUGKJvFxWrapHpaRy5EXPQz9YaKF3nZ8KY18ILTiVpUtbIac86/w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -6728,7 +7695,7 @@ packages: '@typescript-eslint/types': 5.33.0 '@typescript-eslint/typescript-estree': 5.33.0_typescript@4.7.4 debug: 4.3.4 - eslint: 8.21.0 + eslint: 8.23.0 typescript: 4.7.4 transitivePeerDependencies: - supports-color @@ -6742,7 +7709,7 @@ packages: '@typescript-eslint/visitor-keys': 5.33.0 dev: true - /@typescript-eslint/type-utils/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq: + /@typescript-eslint/type-utils/5.33.0_sorwav4hsh5vncerguqybud76i: resolution: {integrity: sha512-2zB8uEn7hEH2pBeyk3NpzX1p3lF9dKrEbnXq1F7YkpZ6hlyqb2yZujqgRGqXgRBTHWIUG3NGx/WeZk224UKlIA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -6752,9 +7719,9 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/utils': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + '@typescript-eslint/utils': 5.33.0_sorwav4hsh5vncerguqybud76i debug: 4.3.4 - eslint: 8.21.0 + eslint: 8.23.0 tsutils: 3.21.0_typescript@4.7.4 typescript: 4.7.4 transitivePeerDependencies: @@ -6787,7 +7754,7 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq: + /@typescript-eslint/utils/5.33.0_sorwav4hsh5vncerguqybud76i: resolution: {integrity: sha512-JxOAnXt9oZjXLIiXb5ZIcZXiwVHCkqZgof0O8KPgz7C7y0HS42gi75PdPlqh1Tf109M0fyUw45Ao6JLo7S5AHw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -6797,9 +7764,9 @@ packages: '@typescript-eslint/scope-manager': 5.33.0 '@typescript-eslint/types': 5.33.0 '@typescript-eslint/typescript-estree': 5.33.0_typescript@4.7.4 - eslint: 8.21.0 + eslint: 8.23.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.21.0 + eslint-utils: 3.0.0_eslint@8.23.0 transitivePeerDependencies: - supports-color - typescript @@ -6814,7 +7781,7 @@ packages: dev: true /@uni/env/1.1.0: - resolution: {integrity: sha512-2GVgUzxIaO2vGElXEuc45+I7L6Jbw8inLDDFuC0K4htjKtPmYywKSE6oDhvmdAXb4GCOH8hmxECYtAh1rjsgoQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/@uni/env/-/env-1.1.0.tgz} + resolution: {integrity: sha512-2GVgUzxIaO2vGElXEuc45+I7L6Jbw8inLDDFuC0K4htjKtPmYywKSE6oDhvmdAXb4GCOH8hmxECYtAh1rjsgoQ==} dev: false /@use-gesture/core/10.2.15: @@ -6835,6 +7802,39 @@ packages: hasBin: true dev: true + /@vitejs/plugin-react/1.3.2: + resolution: {integrity: sha512-aurBNmMo0kz1O4qRoY+FM4epSA39y3ShWGuqfLRA/3z0oEJAdtoSfgA3aO98/PCCHAqMaduLxIxErWrVKIFzXA==} + engines: {node: '>=12.0.0'} + dependencies: + '@babel/core': 7.18.10 + '@babel/plugin-transform-react-jsx': 7.18.10_@babel+core@7.18.10 + '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.18.10 + '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.18.10 + '@babel/plugin-transform-react-jsx-source': 7.18.6_@babel+core@7.18.10 + '@rollup/pluginutils': 4.2.1 + react-refresh: 0.13.0 + resolve: 1.22.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@vitest/coverage-c8/0.23.2_jsdom@20.0.0: + resolution: {integrity: sha512-VWT6zGj9iXEZCimnRLAUhf3siYVGIG9VryyMoo7B8zMOd+bnAbH8/7PhqvmjedVwa9wh61nkxqgG7/3Y/mzofQ==} + dependencies: + c8: 7.12.0 + vitest: 0.23.2_jsdom@20.0.0 + transitivePeerDependencies: + - '@edge-runtime/vm' + - '@vitest/browser' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - sass + - stylus + - supports-color + dev: true + /@webassemblyjs/ast/1.11.1: resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==} dependencies: @@ -6958,21 +7958,6 @@ packages: acorn-walk: 7.2.0 dev: true - /acorn-import-assertions/1.8.0_acorn@8.7.0: - resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==} - peerDependencies: - acorn: ^8 - dependencies: - acorn: 8.7.0 - dev: true - - /acorn-import-assertions/1.8.0_acorn@8.7.1: - resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==} - peerDependencies: - acorn: ^8 - dependencies: - acorn: 8.7.1 - /acorn-import-assertions/1.8.0_acorn@8.8.0: resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==} peerDependencies: @@ -6980,14 +7965,6 @@ packages: dependencies: acorn: 8.8.0 - /acorn-jsx/5.3.2_acorn@8.7.1: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.7.1 - dev: true - /acorn-jsx/5.3.2_acorn@8.8.0: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -7028,6 +8005,7 @@ packages: resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==} engines: {node: '>=0.4.0'} hasBin: true + dev: false /acorn/8.8.0: resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==} @@ -7075,6 +8053,22 @@ packages: screenfull: 5.2.0 dev: false + /ahooks/3.4.1: + resolution: {integrity: sha512-PMxCDO6JsFdNrAyN3cW1J/2qt/vy2EJ/9KhxGOxj41hJhQddjgaBJjZKf/FrrnZmL+3yGPioZtbC4C7q7ru3yA==} + engines: {node: '>=8.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@types/js-cookie': 2.2.7 + ahooks-v3-count: 1.0.0 + dayjs: 1.11.2 + intersection-observer: 0.12.0 + js-cookie: 2.2.1 + lodash: 4.17.21 + resize-observer-polyfill: 1.5.1 + screenfull: 5.2.0 + dev: false + /ahooks/3.4.1_react@18.2.0: resolution: {integrity: sha512-PMxCDO6JsFdNrAyN3cW1J/2qt/vy2EJ/9KhxGOxj41hJhQddjgaBJjZKf/FrrnZmL+3yGPioZtbC4C7q7ru3yA==} engines: {node: '>=8.0.0'} @@ -7423,6 +8417,17 @@ packages: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} dev: false + /asn1/0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + dependencies: + safer-buffer: 2.1.2 + dev: false + + /assert-plus/1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + dev: false + /assertion-error/1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true @@ -7444,6 +8449,7 @@ packages: resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} dependencies: lodash: 4.17.21 + dev: true /async/3.2.3: resolution: {integrity: sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==} @@ -7451,14 +8457,13 @@ packages: /asynckit/0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: true /at-least-node/1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} /atob/2.1.2: - resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/atob/-/atob-2.1.2.tgz} engines: {node: '>= 4.5.0'} hasBin: true dev: false @@ -7515,6 +8520,14 @@ packages: engines: {node: '>= 0.4'} dev: false + /aws-sign2/0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + dev: false + + /aws4/1.11.0: + resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==} + dev: false + /axe-core/4.4.3: resolution: {integrity: sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==} engines: {node: '>=4'} @@ -7543,10 +8556,55 @@ packages: - debug dev: false + /axios/0.27.2: + resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} + dependencies: + follow-redirects: 1.15.1 + form-data: 4.0.0 + transitivePeerDependencies: + - debug + dev: false + /axobject-query/2.2.0: resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==} dev: true + /babel-jest/28.1.3_@babel+core@7.18.10: + resolution: {integrity: sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.18.10 + '@jest/transform': 28.1.3 + '@types/babel__core': 7.1.19 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 28.1.3_@babel+core@7.18.10 + chalk: 4.1.2 + graceful-fs: 4.2.10 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-jest/29.0.3_@babel+core@7.18.10: + resolution: {integrity: sha512-ApPyHSOhS/sVzwUOQIWJmdvDhBsMG01HX9z7ogtkp1TToHGGUWFlnXJUIzCgKPSfiYLn3ibipCYzsKSURHEwLg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.18.10 + '@jest/transform': 29.0.3 + '@types/babel__core': 7.1.19 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.0.2_@babel+core@7.18.10 + chalk: 4.1.2 + graceful-fs: 4.2.10 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /babel-loader/8.2.5_xc6oct4hcywdrbo4ned6ytbybm: resolution: {integrity: sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==} engines: {node: '>= 8.9'} @@ -7580,6 +8638,39 @@ packages: dependencies: '@babel/helper-plugin-utils': 7.10.4 + /babel-plugin-istanbul/6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + dependencies: + '@babel/helper-plugin-utils': 7.18.9 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.0 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-jest-hoist/28.1.3: + resolution: {integrity: sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@babel/template': 7.18.10 + '@babel/types': 7.18.10 + '@types/babel__core': 7.1.19 + '@types/babel__traverse': 7.17.1 + dev: true + + /babel-plugin-jest-hoist/29.0.2: + resolution: {integrity: sha512-eBr2ynAEFjcebVvu8Ktx580BD1QKCrBG1XwEUTXJe285p9HA/4hOhfWCFRQhTKSyBV0VzjhG7H91Eifz9s29hg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/template': 7.18.10 + '@babel/types': 7.18.10 + '@types/babel__core': 7.1.19 + '@types/babel__traverse': 7.17.1 + dev: true + /babel-plugin-polyfill-corejs2/0.3.1_@babel+core@7.18.2: resolution: {integrity: sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==} peerDependencies: @@ -7649,6 +8740,85 @@ packages: transitivePeerDependencies: - supports-color + /babel-plugin-transform-jsx-class/0.1.3: + resolution: {integrity: sha512-Udi3d5qzwEyteqchxKoV/JfgktZZ8O3SLlADO936Os8LXolkuhl3joq71KiU0yMip8wz7+3zBKU+7otK1iZCLw==} + dev: false + + /babel-plugin-transform-jsx-condition/0.1.2: + resolution: {integrity: sha512-2JEcwfz8cqIaq42f5d2Ye8QKCesNCUVPx5SZHELiEcIMMNUOchh1jHNDbn61p8wouGGIPXdlFKSIPq16ADgDaw==} + dev: false + + /babel-plugin-transform-jsx-fragment/0.1.4: + resolution: {integrity: sha512-h1731C6uvAPCYzjLLR9GpTvtQuVKDcT4DqePvMV3FBIT1f7wrVDqv9LJ/wrMyIdh3k0hXsbpJw+qQls8H728wQ==} + dev: false + + /babel-plugin-transform-jsx-list/0.1.2: + resolution: {integrity: sha512-6ajrUOorIkdKwHWAeN8ZUp67yaFl0PYyHKUGY31Pw/ZtF0EIygfD8oxjcbFp0rZpTcVEYTMmh+s1xc6cnKy79g==} + dev: false + + /babel-plugin-transform-jsx-memo/0.1.4: + resolution: {integrity: sha512-v9L9oFFbPjaVytLhxsmuFLm3USIoTeZQHz4xid2qnT87/C5cCbE8GtE26xbPXTc2LBj1roSDIO3hgR+2JAv1vA==} + dev: false + + /babel-plugin-transform-jsx-slot/0.1.2: + resolution: {integrity: sha512-ske7KaYo4w4p2w1q7C3653pNje765P24vLF59qmXlgvlPYuFVCTaGS+PYEyb5xIDRDhgiSO2KtDdYK6f6ONxkQ==} + dependencies: + '@babel/types': 7.18.10 + dev: false + + /babel-plugin-transform-jsx-stylesheet/1.0.6: + resolution: {integrity: sha512-kRtGnLohBzuaTbBFfBPUgX1yhiXs3+K+qBFczSf1fa6cJS2YRwwvMEt894jnF4ihcqz1DJRQ5EhHM9c5+2QsIA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/babel-plugin-transform-jsx-stylesheet/-/babel-plugin-transform-jsx-stylesheet-1.0.6.tgz} + engines: {npm: '>=3.0.0'} + dependencies: + camelcase: 3.0.0 + dev: false + + /babel-preset-current-node-syntax/1.0.1_@babel+core@7.18.10: + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.18.10 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.18.10 + '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.18.10 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.18.10 + '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.18.10 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.18.10 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.18.10 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.18.10 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.18.10 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.18.10 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.18.10 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.18.10 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.18.10 + dev: true + + /babel-preset-jest/28.1.3_@babel+core@7.18.10: + resolution: {integrity: sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.18.10 + babel-plugin-jest-hoist: 28.1.3 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.18.10 + dev: true + + /babel-preset-jest/29.0.2_@babel+core@7.18.10: + resolution: {integrity: sha512-BeVXp7rH5TK96ofyEnHjznjLMQ2nAeDJ+QzxKnHAAMs0RgrQsCywjAN8m4mOm5Di0pxU//3AoEeJJrerMH5UeA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.18.10 + babel-plugin-jest-hoist: 29.0.2 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.18.10 + dev: true + + /babel-runtime-jsx-plus/0.1.5: + resolution: {integrity: sha512-5qjZDfUzZGxHgX8o0tkS9o0HbyBvnUuaAtqHC9IN5CgjWFGJBg6a0Xp31wiG7btiHV0dP5t1t8cthlTCYwtnig==} + dev: false + /babel-runtime/6.26.0: resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==} dependencies: @@ -7675,7 +8845,13 @@ packages: dev: true /batch/0.6.1: - resolution: {integrity: sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=} + resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} + + /bcrypt-pbkdf/1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + dependencies: + tweetnacl: 0.14.5 + dev: false /big.js/5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} @@ -7700,6 +8876,10 @@ packages: readable-stream: 3.6.0 dev: true + /bluebird/3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + dev: false + /body-parser/1.20.0: resolution: {integrity: sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -7727,6 +8907,15 @@ packages: fast-deep-equal: 3.1.3 multicast-dns: 7.2.4 + /bonjour-service/1.0.13: + resolution: {integrity: sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA==} + dependencies: + array-flatten: 2.1.2 + dns-equal: 1.0.0 + fast-deep-equal: 3.1.3 + multicast-dns: 7.2.5 + dev: true + /boolbase/1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -7798,6 +8987,19 @@ packages: node-releases: 2.0.6 update-browserslist-db: 1.0.5_browserslist@4.21.3 + /bs-logger/0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + dependencies: + fast-json-stable-stringify: 2.1.0 + dev: true + + /bser/2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + dev: true + /buffer-crc32/0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} dev: true @@ -7833,12 +9035,6 @@ packages: engines: {node: '>=6'} dev: true - /builtins/4.1.0: - resolution: {integrity: sha512-1bPRZQtmKaO6h7qV1YHXNtr6nCK28k0Zo95KM4dXfILcZZwoHJBN1m3lfLv9LPkcOZlrSr+J1bzMaZFO98Yq0w==} - dependencies: - semver: 7.3.7 - dev: true - /busboy/1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -7847,7 +9043,7 @@ packages: dev: false /bytes/3.0.0: - resolution: {integrity: sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=} + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} engines: {node: '>= 0.8'} /bytes/3.1.2: @@ -7946,7 +9142,7 @@ packages: dev: true /camelcase/3.0.0: - resolution: {integrity: sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==} + resolution: {integrity: sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/camelcase/-/camelcase-3.0.0.tgz} engines: {node: '>=0.10.0'} dev: false @@ -7961,7 +9157,7 @@ packages: /caniuse-api/3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 caniuse-lite: 1.0.30001332 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 @@ -7978,6 +9174,10 @@ packages: /caniuse-lite/1.0.30001375: resolution: {integrity: sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw==} + /caseless/0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + dev: false + /ccount/1.1.0: resolution: {integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==} @@ -8013,6 +9213,14 @@ packages: escape-string-regexp: 1.0.5 supports-color: 5.5.0 + /chalk/3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + /chalk/4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -8020,6 +9228,11 @@ packages: ansi-styles: 4.3.0 supports-color: 7.2.0 + /char-regex/1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + dev: true + /character-entities-legacy/1.1.4: resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} @@ -8089,6 +9302,14 @@ packages: /ci-info/2.0.0: resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + /ci-info/3.4.0: + resolution: {integrity: sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==} + dev: true + + /cjs-module-lexer/1.2.2: + resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} + dev: true + /classnames/2.3.1: resolution: {integrity: sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==} dev: false @@ -8186,6 +9407,11 @@ packages: resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} engines: {node: '>=6'} + /co/4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: true + /coa/2.0.2: resolution: {integrity: sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==} engines: {node: '>= 4.0'} @@ -8202,6 +9428,10 @@ packages: /collapse-white-space/1.0.6: resolution: {integrity: sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==} + /collect-v8-coverage/1.0.1: + resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} + dev: true + /color-convert/1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: @@ -8231,7 +9461,6 @@ packages: /colorette/2.0.19: resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} - dev: true /combine-promises/1.1.0: resolution: {integrity: sha512-ZI9jvcLDxqwaXEixOhArm3r7ReIivsXkpbyEWyeOhzz1QS0iSgBPnWvEqvIQtYyamGCYA88gFhmUrs9hrrQ0pg==} @@ -8242,7 +9471,6 @@ packages: engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 - dev: true /comma-separated-tokens/1.0.8: resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} @@ -8278,7 +9506,7 @@ packages: /common-path-prefix/3.0.0: resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} - dev: false + dev: true /commondir/1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} @@ -8347,6 +9575,7 @@ packages: /connect-history-api-fallback/1.6.0: resolution: {integrity: sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==} engines: {node: '>=0.8'} + dev: true /connect-history-api-fallback/2.0.0: resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} @@ -8416,7 +9645,7 @@ packages: safe-buffer: 5.1.2 /cookie-signature/1.0.6: - resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=} + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} /cookie/0.5.0: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} @@ -8438,7 +9667,7 @@ packages: toggle-selection: 1.0.6 dev: false - /copy-webpack-plugin/10.2.4_webpack@5.73.0: + /copy-webpack-plugin/10.2.4_webpack@5.74.0: resolution: {integrity: sha512-xFVltahqlsRcyyJqQbDY6EYTtyQZF9rf+JPjwHObLdPFMEISqkFkr7mFoVOC6BfYS/dNThyoQKvziugm+OnwBg==} engines: {node: '>= 12.20.0'} peerDependencies: @@ -8450,7 +9679,7 @@ packages: normalize-path: 3.0.0 schema-utils: 4.0.0 serialize-javascript: 6.0.0 - webpack: 5.73.0_@swc+core@1.2.210 + webpack: 5.74.0_@swc+core@1.2.210 dev: true /copy-webpack-plugin/11.0.0_webpack@5.74.0: @@ -8473,11 +9702,6 @@ packages: browserslist: 4.20.3 semver: 7.0.0 - /core-js-pure/3.22.2: - resolution: {integrity: sha512-Lb+/XT4WC4PaCWWtZpNPaXmjiNDUe5CJuUtbkMrIM1kb1T/jJoAIp+bkVP/r5lHzMr+ZAAF8XHp7+my6Ol0ysQ==} - requiresBuild: true - dev: false - /core-js-pure/3.24.1: resolution: {integrity: sha512-r1nJk41QLLPyozHUUPmILCEMtMw24NG4oWK6RbsDdjzQgg9ZvrUsPBj1MnG0wXXp1DCDU6j+wUvEmBSrtRbLXg==} requiresBuild: true @@ -8492,6 +9716,10 @@ packages: resolution: {integrity: sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg==} requiresBuild: true + /core-util-is/1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + dev: false + /core-util-is/1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -8614,23 +9842,6 @@ packages: postcss-selector-parser: 6.0.10 dev: true - /css-loader/6.7.1_webpack@5.73.0: - resolution: {integrity: sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==} - engines: {node: '>= 12.13.0'} - peerDependencies: - webpack: ^5.0.0 - dependencies: - icss-utils: 5.1.0_postcss@8.4.12 - postcss: 8.4.12 - postcss-modules-extract-imports: 3.0.0_postcss@8.4.12 - postcss-modules-local-by-default: 4.0.0_postcss@8.4.12 - postcss-modules-scope: 3.0.0_postcss@8.4.12 - postcss-modules-values: 4.0.0_postcss@8.4.12 - postcss-value-parser: 4.2.0 - semver: 7.3.7 - webpack: 5.73.0_@swc+core@1.2.210 - dev: true - /css-loader/6.7.1_webpack@5.74.0: resolution: {integrity: sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==} engines: {node: '>= 12.13.0'} @@ -8645,9 +9856,9 @@ packages: postcss-modules-values: 4.0.0_postcss@8.4.12 postcss-value-parser: 4.2.0 semver: 7.3.7 - webpack: 5.74.0 + webpack: 5.74.0_@swc+core@1.2.210 - /css-minimizer-webpack-plugin/3.4.1_webpack@5.73.0: + /css-minimizer-webpack-plugin/3.4.1_webpack@5.74.0: resolution: {integrity: sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -8672,7 +9883,7 @@ packages: schema-utils: 4.0.0 serialize-javascript: 6.0.0 source-map: 0.6.1 - webpack: 5.73.0_@swc+core@1.2.210 + webpack: 5.74.0_@swc+core@1.2.210 dev: true /css-minimizer-webpack-plugin/4.0.0_zvbyxxpfojwcdldcsxjlwltq7e: @@ -8768,8 +9979,12 @@ packages: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} + /css.escape/1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + dev: true + /css/2.2.4: - resolution: {integrity: sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==} + resolution: {integrity: sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/css/-/css-2.2.4.tgz} dependencies: inherits: 2.0.4 source-map: 0.6.1 @@ -9011,6 +10226,13 @@ packages: engines: {node: '>=8'} dev: true + /dashdash/1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + dependencies: + assert-plus: 1.0.0 + dev: false + /data-urls/3.0.2: resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} engines: {node: '>=12'} @@ -9078,7 +10300,7 @@ packages: dev: true /decode-uri-component/0.2.0: - resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} + resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz} engines: {node: '>=0.10'} dev: false @@ -9088,6 +10310,10 @@ packages: dependencies: mimic-response: 1.0.1 + /dedent/0.7.0: + resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + dev: true + /deep-eql/3.0.1: resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==} engines: {node: '>=0.12'} @@ -9153,7 +10379,6 @@ packages: /delayed-stream/1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - dev: true /delegates/1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} @@ -9202,6 +10427,11 @@ packages: minimist: 0.1.0 dev: true + /detect-newline/3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + dev: true + /detect-node/2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} @@ -9239,6 +10469,16 @@ packages: resolution: {integrity: sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==} dev: true + /diff-sequences/28.1.1: + resolution: {integrity: sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dev: true + + /diff-sequences/29.0.0: + resolution: {integrity: sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + /diff/4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} @@ -9383,7 +10623,7 @@ packages: dev: false /driver-server/1.0.0: - resolution: {integrity: sha512-H5nhMzsSJYaug+PDPyXiVW2KvK5k7B7K+yVW3FuHESq494Soh1cfomquJ2pk5RiApQr1z0e+0tif11TVRlM+PQ==} + resolution: {integrity: sha512-H5nhMzsSJYaug+PDPyXiVW2KvK5k7B7K+yVW3FuHESq494Soh1cfomquJ2pk5RiApQr1z0e+0tif11TVRlM+PQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/driver-server/-/driver-server-1.0.0.tgz} dev: false /dts-bundle/0.7.3: @@ -9410,8 +10650,15 @@ packages: /eastasianwidth/0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + /ecc-jsbn/0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + dev: false + /ee-first/1.1.1: - resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} /ejs/3.1.7: resolution: {integrity: sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==} @@ -9427,6 +10674,11 @@ packages: /electron-to-chromium/1.4.215: resolution: {integrity: sha512-vqZxT8C5mlDZ//hQFhneHmOLnj1LhbzxV0+I1yqHV8SB1Oo4Y5Ne9+qQhwHl7O1s9s9cRuo2l5CoLEHdhMTwZg==} + /emittery/0.10.2: + resolution: {integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==} + engines: {node: '>=12'} + dev: true + /emoji-regex/8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -9456,13 +10708,6 @@ packages: graceful-fs: 4.2.10 tapable: 2.2.1 - /enhanced-resolve/5.9.3: - resolution: {integrity: sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==} - engines: {node: '>=10.13.0'} - dependencies: - graceful-fs: 4.2.10 - tapable: 2.2.1 - /entities/2.2.0: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} @@ -9491,7 +10736,6 @@ packages: resolution: {integrity: sha512-chLOW0ZGRf4s8raLrDxa5sdkvPec5YdvwbFnqJme4rk0rFajP8mPtrDL1+I+CwrQDCjswDA5sREX7jYQDQs9vA==} dependencies: stackframe: 1.2.1 - dev: false /es-abstract/1.19.5: resolution: {integrity: sha512-Aa2G2+Rd3b6kxEUKTF4TaW67czBLyAv3z7VOhYRU50YBx+bbsYZ9xQP4lMNazePuFlybXI0V4MruPos7qUo5fA==} @@ -9576,14 +10820,6 @@ packages: is-date-object: 1.0.5 is-symbol: 1.0.4 - /esbuild-android-64/0.14.38: - resolution: {integrity: sha512-aRFxR3scRKkbmNuGAK+Gee3+yFxkTJO/cx83Dkyzo4CnQl/2zVSurtG6+G86EQIZ+w+VYngVyK7P3HyTBKu3nw==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - optional: true - /esbuild-android-64/0.14.54: resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} engines: {node: '>=12'} @@ -9592,8 +10828,8 @@ packages: requiresBuild: true optional: true - /esbuild-android-64/0.15.1: - resolution: {integrity: sha512-q5kkJZsgLIkyh5e2ZJl4/kXKIueBKtjVMEihP9WCHadqhH6+F9qiycE7fBwUb/g2B15mYlmMBXjp8VmOT3J2gA==} + /esbuild-android-64/0.15.5: + resolution: {integrity: sha512-dYPPkiGNskvZqmIK29OPxolyY3tp+c47+Fsc2WYSOVjEPWNCHNyqhtFqQadcXMJDQt8eN0NMDukbyQgFcHquXg==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -9601,14 +10837,6 @@ packages: dev: true optional: true - /esbuild-android-arm64/0.14.38: - resolution: {integrity: sha512-L2NgQRWuHFI89IIZIlpAcINy9FvBk6xFVZ7xGdOwIm8VyhX1vNCEqUJO3DPSSy945Gzdg98cxtNt8Grv1CsyhA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - optional: true - /esbuild-android-arm64/0.14.54: resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==} engines: {node: '>=12'} @@ -9617,8 +10845,8 @@ packages: requiresBuild: true optional: true - /esbuild-android-arm64/0.15.1: - resolution: {integrity: sha512-IQuZOzqMaFceLlKJJA27CXAdh+Mzh2ZblHMmcNIu/wxb6iX1zgYXlPWle62iHnmNCtfAux1mzQvmNsP9aLhemA==} + /esbuild-android-arm64/0.15.5: + resolution: {integrity: sha512-YyEkaQl08ze3cBzI/4Cm1S+rVh8HMOpCdq8B78JLbNFHhzi4NixVN93xDrHZLztlocEYqi45rHHCgA8kZFidFg==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -9626,14 +10854,6 @@ packages: dev: true optional: true - /esbuild-darwin-64/0.14.38: - resolution: {integrity: sha512-5JJvgXkX87Pd1Og0u/NJuO7TSqAikAcQQ74gyJ87bqWRVeouky84ICoV4sN6VV53aTW+NE87qLdGY4QA2S7KNA==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - optional: true - /esbuild-darwin-64/0.14.54: resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==} engines: {node: '>=12'} @@ -9642,8 +10862,8 @@ packages: requiresBuild: true optional: true - /esbuild-darwin-64/0.15.1: - resolution: {integrity: sha512-tyouWLyxwM/Y2fy/reuIvAvVB+KVQwuY9IVyV7LH5CGkJYxgtLb8xVEiwHFF8TG2uo9a2fqdgWffados4YA6Aw==} + /esbuild-darwin-64/0.15.5: + resolution: {integrity: sha512-Cr0iIqnWKx3ZTvDUAzG0H/u9dWjLE4c2gTtRLz4pqOBGjfjqdcZSfAObFzKTInLLSmD0ZV1I/mshhPoYSBMMCQ==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -9651,14 +10871,6 @@ packages: dev: true optional: true - /esbuild-darwin-arm64/0.14.38: - resolution: {integrity: sha512-eqF+OejMI3mC5Dlo9Kdq/Ilbki9sQBw3QlHW3wjLmsLh+quNfHmGMp3Ly1eWm981iGBMdbtSS9+LRvR2T8B3eQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - optional: true - /esbuild-darwin-arm64/0.14.54: resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==} engines: {node: '>=12'} @@ -9667,8 +10879,8 @@ packages: requiresBuild: true optional: true - /esbuild-darwin-arm64/0.15.1: - resolution: {integrity: sha512-fb4V1eB1nir3zJwsS75itsbahkbM71XuqUDJVH8iyBLS8VIQD7MWWAAekea2l9keueGfsn0+wTyDluMT+kg8Cw==} + /esbuild-darwin-arm64/0.15.5: + resolution: {integrity: sha512-WIfQkocGtFrz7vCu44ypY5YmiFXpsxvz2xqwe688jFfSVCnUsCn2qkEVDo7gT8EpsLOz1J/OmqjExePL1dr1Kg==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -9676,14 +10888,6 @@ packages: dev: true optional: true - /esbuild-freebsd-64/0.14.38: - resolution: {integrity: sha512-epnPbhZUt93xV5cgeY36ZxPXDsQeO55DppzsIgWM8vgiG/Rz+qYDLmh5ts3e+Ln1wA9dQ+nZmVHw+RjaW3I5Ig==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - optional: true - /esbuild-freebsd-64/0.14.54: resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==} engines: {node: '>=12'} @@ -9692,8 +10896,8 @@ packages: requiresBuild: true optional: true - /esbuild-freebsd-64/0.15.1: - resolution: {integrity: sha512-1KxEv/FUPlQtUSOjFCwR8FVNEskB5LmkbfW9FNJ7lhpG+4RsLiHWw4Sl2Y1/S+aKX7inyWxLA05zYV6XAzO8DA==} + /esbuild-freebsd-64/0.15.5: + resolution: {integrity: sha512-M5/EfzV2RsMd/wqwR18CELcenZ8+fFxQAAEO7TJKDmP3knhWSbD72ILzrXFMMwshlPAS1ShCZ90jsxkm+8FlaA==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -9701,14 +10905,6 @@ packages: dev: true optional: true - /esbuild-freebsd-arm64/0.14.38: - resolution: {integrity: sha512-/9icXUYJWherhk+y5fjPI5yNUdFPtXHQlwP7/K/zg8t8lQdHVj20SqU9/udQmeUo5pDFHMYzcEFfJqgOVeKNNQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - optional: true - /esbuild-freebsd-arm64/0.14.54: resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==} engines: {node: '>=12'} @@ -9717,8 +10913,8 @@ packages: requiresBuild: true optional: true - /esbuild-freebsd-arm64/0.15.1: - resolution: {integrity: sha512-ueUMGSNrcuHwAadioxBdfOCO4+bTVeI68a147BQ/AFFIrf4XJNow4UXxguvQlZO+ZYaVz6EztaL6mHslKie2Rw==} + /esbuild-freebsd-arm64/0.15.5: + resolution: {integrity: sha512-2JQQ5Qs9J0440F/n/aUBNvY6lTo4XP/4lt1TwDfHuo0DY3w5++anw+jTjfouLzbJmFFiwmX7SmUhMnysocx96w==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -9726,14 +10922,6 @@ packages: dev: true optional: true - /esbuild-linux-32/0.14.38: - resolution: {integrity: sha512-QfgfeNHRFvr2XeHFzP8kOZVnal3QvST3A0cgq32ZrHjSMFTdgXhMhmWdKzRXP/PKcfv3e2OW9tT9PpcjNvaq6g==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - optional: true - /esbuild-linux-32/0.14.54: resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==} engines: {node: '>=12'} @@ -9742,8 +10930,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-32/0.15.1: - resolution: {integrity: sha512-K5WWcN2OZkZ6arFN3+hi1leKc0at9ukKGrXK9Ia94kQOesBphTSmsNK/Gy/AoVoIa0bWrHtxDijS9j9+dz86oA==} + /esbuild-linux-32/0.15.5: + resolution: {integrity: sha512-gO9vNnIN0FTUGjvTFucIXtBSr1Woymmx/aHQtuU+2OllGU6YFLs99960UD4Dib1kFovVgs59MTXwpFdVoSMZoQ==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -9751,14 +10939,6 @@ packages: dev: true optional: true - /esbuild-linux-64/0.14.38: - resolution: {integrity: sha512-uuZHNmqcs+Bj1qiW9k/HZU3FtIHmYiuxZ/6Aa+/KHb/pFKr7R3aVqvxlAudYI9Fw3St0VCPfv7QBpUITSmBR1Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - optional: true - /esbuild-linux-64/0.14.54: resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==} engines: {node: '>=12'} @@ -9767,8 +10947,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-64/0.15.1: - resolution: {integrity: sha512-+haiVm83DfRi9x8M+GgR4f4LtSN8lnEIG8XMGK8/FYpkYNQiKb398GxeHp2yvoMpX8IPvmWCt215tAm5BBNfZQ==} + /esbuild-linux-64/0.15.5: + resolution: {integrity: sha512-ne0GFdNLsm4veXbTnYAWjbx3shpNKZJUd6XpNbKNUZaNllDZfYQt0/zRqOg0sc7O8GQ+PjSMv9IpIEULXVTVmg==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -9776,14 +10956,6 @@ packages: dev: true optional: true - /esbuild-linux-arm/0.14.38: - resolution: {integrity: sha512-FiFvQe8J3VKTDXG01JbvoVRXQ0x6UZwyrU4IaLBZeq39Bsbatd94Fuc3F1RGqPF5RbIWW7RvkVQjn79ejzysnA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - optional: true - /esbuild-linux-arm/0.14.54: resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==} engines: {node: '>=12'} @@ -9792,8 +10964,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-arm/0.15.1: - resolution: {integrity: sha512-qjAkEDcFhVNYwG2xgaDg/hA8JABoMvjzAzE6g1K8kR516oNkKbVf6rN68UrsQaV1zq1qR3dbVeMv/Ul2bheppA==} + /esbuild-linux-arm/0.15.5: + resolution: {integrity: sha512-wvAoHEN+gJ/22gnvhZnS/+2H14HyAxM07m59RSLn3iXrQsdS518jnEWRBnJz3fR6BJa+VUTo0NxYjGaNt7RA7Q==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -9801,14 +10973,6 @@ packages: dev: true optional: true - /esbuild-linux-arm64/0.14.38: - resolution: {integrity: sha512-HlMGZTEsBrXrivr64eZ/EO0NQM8H8DuSENRok9d+Jtvq8hOLzrxfsAT9U94K3KOGk2XgCmkaI2KD8hX7F97lvA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - optional: true - /esbuild-linux-arm64/0.14.54: resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==} engines: {node: '>=12'} @@ -9817,8 +10981,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-arm64/0.15.1: - resolution: {integrity: sha512-TP0BCVZEVu/aoVaZe2sn1vpvo63j0LPiH8rvd7AegqOfTwb+mcxLxpgyYwkibafUCMxnIrKdUTsSJeusoMhcLg==} + /esbuild-linux-arm64/0.15.5: + resolution: {integrity: sha512-7EgFyP2zjO065XTfdCxiXVEk+f83RQ1JsryN1X/VSX2li9rnHAt2swRbpoz5Vlrl6qjHrCmq5b6yxD13z6RheA==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -9826,14 +10990,6 @@ packages: dev: true optional: true - /esbuild-linux-mips64le/0.14.38: - resolution: {integrity: sha512-qd1dLf2v7QBiI5wwfil9j0HG/5YMFBAmMVmdeokbNAMbcg49p25t6IlJFXAeLzogv1AvgaXRXvgFNhScYEUXGQ==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - optional: true - /esbuild-linux-mips64le/0.14.54: resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==} engines: {node: '>=12'} @@ -9842,8 +10998,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-mips64le/0.15.1: - resolution: {integrity: sha512-8vzQzp+kwrn1Y+OjvfFaLS8uL8aR39WnAtxOHwjB72s9g18kHFlE8IQLS9dWDQgKpBSFq9kazsJE65dSVmz+VA==} + /esbuild-linux-mips64le/0.15.5: + resolution: {integrity: sha512-KdnSkHxWrJ6Y40ABu+ipTZeRhFtc8dowGyFsZY5prsmMSr1ZTG9zQawguN4/tunJ0wy3+kD54GaGwdcpwWAvZQ==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -9851,14 +11007,6 @@ packages: dev: true optional: true - /esbuild-linux-ppc64le/0.14.38: - resolution: {integrity: sha512-mnbEm7o69gTl60jSuK+nn+pRsRHGtDPfzhrqEUXyCl7CTOCLtWN2bhK8bgsdp6J/2NyS/wHBjs1x8aBWwP2X9Q==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - optional: true - /esbuild-linux-ppc64le/0.14.54: resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==} engines: {node: '>=12'} @@ -9867,8 +11015,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-ppc64le/0.15.1: - resolution: {integrity: sha512-QlWSOgC2Ad53Xvf7ZivXU7wM2y29YhQUrd50PjK0QJ3psh/eYSQx77PTe1iWm7Ovjiqv1wPKEAyC7CbyJUgriw==} + /esbuild-linux-ppc64le/0.15.5: + resolution: {integrity: sha512-QdRHGeZ2ykl5P0KRmfGBZIHmqcwIsUKWmmpZTOq573jRWwmpfRmS7xOhmDHBj9pxv+6qRMH8tLr2fe+ZKQvCYw==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -9876,14 +11024,6 @@ packages: dev: true optional: true - /esbuild-linux-riscv64/0.14.38: - resolution: {integrity: sha512-+p6YKYbuV72uikChRk14FSyNJZ4WfYkffj6Af0/Tw63/6TJX6TnIKE+6D3xtEc7DeDth1fjUOEqm+ApKFXbbVQ==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - optional: true - /esbuild-linux-riscv64/0.14.54: resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==} engines: {node: '>=12'} @@ -9892,8 +11032,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-riscv64/0.15.1: - resolution: {integrity: sha512-/PRNgNsiwb7G2n3rB5WcHinCwKj0OqUmtu8cdakV4CLNWnFnfChEGEJX1x5n8RcGD3xPUlI5CgqFe0/oBcUh+A==} + /esbuild-linux-riscv64/0.15.5: + resolution: {integrity: sha512-p+WE6RX+jNILsf+exR29DwgV6B73khEQV0qWUbzxaycxawZ8NE0wA6HnnTxbiw5f4Gx9sJDUBemh9v49lKOORA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -9901,14 +11041,6 @@ packages: dev: true optional: true - /esbuild-linux-s390x/0.14.38: - resolution: {integrity: sha512-0zUsiDkGJiMHxBQ7JDU8jbaanUY975CdOW1YDrurjrM0vWHfjv9tLQsW9GSyEb/heSK1L5gaweRjzfUVBFoybQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - optional: true - /esbuild-linux-s390x/0.14.54: resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==} engines: {node: '>=12'} @@ -9917,8 +11049,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-s390x/0.15.1: - resolution: {integrity: sha512-TScRbO4mi4AUUXzIQ8sb6ZXhGkCb/PlJ82qFfBE6xxsioae/d6XaSdaha/+OUTvmPeoro3lNf3vwdw27v3wEgw==} + /esbuild-linux-s390x/0.15.5: + resolution: {integrity: sha512-J2ngOB4cNzmqLHh6TYMM/ips8aoZIuzxJnDdWutBw5482jGXiOzsPoEF4j2WJ2mGnm7FBCO4StGcwzOgic70JQ==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -9926,14 +11058,6 @@ packages: dev: true optional: true - /esbuild-netbsd-64/0.14.38: - resolution: {integrity: sha512-cljBAApVwkpnJZfnRVThpRBGzCi+a+V9Ofb1fVkKhtrPLDYlHLrSYGtmnoTVWDQdU516qYI8+wOgcGZ4XIZh0Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - optional: true - /esbuild-netbsd-64/0.14.54: resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==} engines: {node: '>=12'} @@ -9942,8 +11066,8 @@ packages: requiresBuild: true optional: true - /esbuild-netbsd-64/0.15.1: - resolution: {integrity: sha512-ES2pbK8QfsMZbdPkgjkLwWfnEGtPa0vYzVFLQn7GFgP+RiemY+ulH7WWQ8ezMt9rZl4XAR3y14yKLGX0gsBLaw==} + /esbuild-netbsd-64/0.15.5: + resolution: {integrity: sha512-MmKUYGDizYjFia0Rwt8oOgmiFH7zaYlsoQ3tIOfPxOqLssAsEgG0MUdRDm5lliqjiuoog8LyDu9srQk5YwWF3w==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -9951,20 +11075,6 @@ packages: dev: true optional: true - /esbuild-node-loader/0.6.5: - resolution: {integrity: sha512-uPP+dllWm38cFvDysdocutN3lfe5pTIbddAHp1ENyLzpHYqE2r+3Wo+pfg9X3p8DFWwzIisft5YkeBIthIcixw==} - dependencies: - esbuild: 0.15.1 - dev: true - - /esbuild-openbsd-64/0.14.38: - resolution: {integrity: sha512-CDswYr2PWPGEPpLDUO50mL3WO/07EMjnZDNKpmaxUPsrW+kVM3LoAqr/CE8UbzugpEiflYqJsGPLirThRB18IQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - optional: true - /esbuild-openbsd-64/0.14.54: resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==} engines: {node: '>=12'} @@ -9973,8 +11083,8 @@ packages: requiresBuild: true optional: true - /esbuild-openbsd-64/0.15.1: - resolution: {integrity: sha512-DxNWji11AxSEny4HzSKu21Skia8tEPQI1N+XO/RqVOJComOvsFLq+QeooKsK2caOsQIKl9mO14Hh+px+zFabMA==} + /esbuild-openbsd-64/0.15.5: + resolution: {integrity: sha512-2mMFfkLk3oPWfopA9Plj4hyhqHNuGyp5KQyTT9Rc8hFd8wAn5ZrbJg+gNcLMo2yzf8Uiu0RT6G9B15YN9WQyMA==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -9982,30 +11092,14 @@ packages: dev: true optional: true - /esbuild-register/3.3.2_esbuild@0.14.38: + /esbuild-register/3.3.2_esbuild@0.14.54: resolution: {integrity: sha512-jceAtTO6zxPmCfSD5cBb3rgIK1vmuqCKYwgylHiS1BF4pq0jJiJb4K2QMuqF4BEw7XDBRatYzip0upyTzfkgsQ==} peerDependencies: esbuild: '>=0.12 <1' dependencies: - esbuild: 0.14.38 + esbuild: 0.14.54 dev: false - /esbuild-register/3.3.3_esbuild@0.15.1: - resolution: {integrity: sha512-eFHOkutgIMJY5gc8LUp/7c+LLlDqzNi9T6AwCZ2WKKl3HmT+5ef3ZRyPPxDOynInML0fgaC50yszPKfPnjC0NQ==} - peerDependencies: - esbuild: '>=0.12 <1' - dependencies: - esbuild: 0.15.1 - dev: true - - /esbuild-sunos-64/0.14.38: - resolution: {integrity: sha512-2mfIoYW58gKcC3bck0j7lD3RZkqYA7MmujFYmSn9l6TiIcAMpuEvqksO+ntBgbLep/eyjpgdplF7b+4T9VJGOA==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - optional: true - /esbuild-sunos-64/0.14.54: resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==} engines: {node: '>=12'} @@ -10014,8 +11108,8 @@ packages: requiresBuild: true optional: true - /esbuild-sunos-64/0.15.1: - resolution: {integrity: sha512-lwZoWlv893qtQQx5H4QQCh2mcYzGbxEz09ESFdd4cHcUCfjb193bSAy6jPxW2efBx2fHEo2sw43TRtAkpCf+XQ==} + /esbuild-sunos-64/0.15.5: + resolution: {integrity: sha512-2sIzhMUfLNoD+rdmV6AacilCHSxZIoGAU2oT7XmJ0lXcZWnCvCtObvO6D4puxX9YRE97GodciRGDLBaiC6x1SA==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -10023,14 +11117,6 @@ packages: dev: true optional: true - /esbuild-windows-32/0.14.38: - resolution: {integrity: sha512-L2BmEeFZATAvU+FJzJiRLFUP+d9RHN+QXpgaOrs2klshoAm1AE6Us4X6fS9k33Uy5SzScn2TpcgecbqJza1Hjw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - optional: true - /esbuild-windows-32/0.14.54: resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==} engines: {node: '>=12'} @@ -10039,8 +11125,8 @@ packages: requiresBuild: true optional: true - /esbuild-windows-32/0.15.1: - resolution: {integrity: sha512-jEFz8DxP+Hh67fk9XMoyLUqPjjoCT6m4bnl36aze0XpPZDuQm0SBDlG/ciOBCjzHDsu/MYUNwxVezvUT3sXh1A==} + /esbuild-windows-32/0.15.5: + resolution: {integrity: sha512-e+duNED9UBop7Vnlap6XKedA/53lIi12xv2ebeNS4gFmu7aKyTrok7DPIZyU5w/ftHD4MUDs5PJUkQPP9xJRzg==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -10048,14 +11134,6 @@ packages: dev: true optional: true - /esbuild-windows-64/0.14.38: - resolution: {integrity: sha512-Khy4wVmebnzue8aeSXLC+6clo/hRYeNIm0DyikoEqX+3w3rcvrhzpoix0S+MF9vzh6JFskkIGD7Zx47ODJNyCw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - optional: true - /esbuild-windows-64/0.14.54: resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==} engines: {node: '>=12'} @@ -10064,8 +11142,8 @@ packages: requiresBuild: true optional: true - /esbuild-windows-64/0.15.1: - resolution: {integrity: sha512-bUetnfw4xXKBTOQx4sTzoENJVEdgAN29ZTLRtnMseRzsMO8pjObQMsRPpPL3Cstt6FJhj3k3uScHc5VnfC9QkA==} + /esbuild-windows-64/0.15.5: + resolution: {integrity: sha512-v+PjvNtSASHOjPDMIai9Yi+aP+Vwox+3WVdg2JB8N9aivJ7lyhp4NVU+J0MV2OkWFPnVO8AE/7xH+72ibUUEnw==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -10073,14 +11151,6 @@ packages: dev: true optional: true - /esbuild-windows-arm64/0.14.38: - resolution: {integrity: sha512-k3FGCNmHBkqdJXuJszdWciAH77PukEyDsdIryEHn9cKLQFxzhT39dSumeTuggaQcXY57UlmLGIkklWZo2qzHpw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - optional: true - /esbuild-windows-arm64/0.14.54: resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==} engines: {node: '>=12'} @@ -10089,8 +11159,8 @@ packages: requiresBuild: true optional: true - /esbuild-windows-arm64/0.15.1: - resolution: {integrity: sha512-oN0JMj7fQZOiqJ/f/wc8lkxjvWwj5Yz0ZhOeU90JFaPZAfafNnysi6GS95glY5uwLUUJz/RNc84cb0dK2qT89A==} + /esbuild-windows-arm64/0.15.5: + resolution: {integrity: sha512-Yz8w/D8CUPYstvVQujByu6mlf48lKmXkq6bkeSZZxTA626efQOJb26aDGLzmFWx6eg/FwrXgt6SZs9V8Pwy/aA==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -10098,33 +11168,6 @@ packages: dev: true optional: true - /esbuild/0.14.38: - resolution: {integrity: sha512-12fzJ0fsm7gVZX1YQ1InkOE5f9Tl7cgf6JPYXRJtPIoE0zkWAbHdPHVPPaLi9tYAcEBqheGzqLn/3RdTOyBfcA==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - esbuild-android-64: 0.14.38 - esbuild-android-arm64: 0.14.38 - esbuild-darwin-64: 0.14.38 - esbuild-darwin-arm64: 0.14.38 - esbuild-freebsd-64: 0.14.38 - esbuild-freebsd-arm64: 0.14.38 - esbuild-linux-32: 0.14.38 - esbuild-linux-64: 0.14.38 - esbuild-linux-arm: 0.14.38 - esbuild-linux-arm64: 0.14.38 - esbuild-linux-mips64le: 0.14.38 - esbuild-linux-ppc64le: 0.14.38 - esbuild-linux-riscv64: 0.14.38 - esbuild-linux-s390x: 0.14.38 - esbuild-netbsd-64: 0.14.38 - esbuild-openbsd-64: 0.14.38 - esbuild-sunos-64: 0.14.38 - esbuild-windows-32: 0.14.38 - esbuild-windows-64: 0.14.38 - esbuild-windows-arm64: 0.14.38 - /esbuild/0.14.54: resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==} engines: {node: '>=12'} @@ -10153,33 +11196,33 @@ packages: esbuild-windows-64: 0.14.54 esbuild-windows-arm64: 0.14.54 - /esbuild/0.15.1: - resolution: {integrity: sha512-zgxo2st9wSbdiR6rTo44l/L7ohttqdXFmhUi5tE6yWahgdBjCwZjBgIkm/gr/TcBTTIwyzd7em8WI37yZ+F2Mg==} + /esbuild/0.15.5: + resolution: {integrity: sha512-VSf6S1QVqvxfIsSKb3UKr3VhUCis7wgDbtF4Vd9z84UJr05/Sp2fRKmzC+CSPG/dNAPPJZ0BTBLTT1Fhd6N9Gg==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/linux-loong64': 0.15.1 - esbuild-android-64: 0.15.1 - esbuild-android-arm64: 0.15.1 - esbuild-darwin-64: 0.15.1 - esbuild-darwin-arm64: 0.15.1 - esbuild-freebsd-64: 0.15.1 - esbuild-freebsd-arm64: 0.15.1 - esbuild-linux-32: 0.15.1 - esbuild-linux-64: 0.15.1 - esbuild-linux-arm: 0.15.1 - esbuild-linux-arm64: 0.15.1 - esbuild-linux-mips64le: 0.15.1 - esbuild-linux-ppc64le: 0.15.1 - esbuild-linux-riscv64: 0.15.1 - esbuild-linux-s390x: 0.15.1 - esbuild-netbsd-64: 0.15.1 - esbuild-openbsd-64: 0.15.1 - esbuild-sunos-64: 0.15.1 - esbuild-windows-32: 0.15.1 - esbuild-windows-64: 0.15.1 - esbuild-windows-arm64: 0.15.1 + '@esbuild/linux-loong64': 0.15.5 + esbuild-android-64: 0.15.5 + esbuild-android-arm64: 0.15.5 + esbuild-darwin-64: 0.15.5 + esbuild-darwin-arm64: 0.15.5 + esbuild-freebsd-64: 0.15.5 + esbuild-freebsd-arm64: 0.15.5 + esbuild-linux-32: 0.15.5 + esbuild-linux-64: 0.15.5 + esbuild-linux-arm: 0.15.5 + esbuild-linux-arm64: 0.15.5 + esbuild-linux-mips64le: 0.15.5 + esbuild-linux-ppc64le: 0.15.5 + esbuild-linux-riscv64: 0.15.5 + esbuild-linux-s390x: 0.15.5 + esbuild-netbsd-64: 0.15.5 + esbuild-openbsd-64: 0.15.5 + esbuild-sunos-64: 0.15.5 + esbuild-windows-32: 0.15.5 + esbuild-windows-64: 0.15.5 + esbuild-windows-arm64: 0.15.5 dev: true /escalade/3.1.1: @@ -10197,6 +11240,11 @@ packages: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} + /escape-string-regexp/2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + /escape-string-regexp/4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -10219,12 +11267,12 @@ packages: source-map: 0.6.1 dev: true - /eslint-config-ali/13.1.0_eslint@8.21.0: + /eslint-config-ali/13.1.0_eslint@8.23.0: resolution: {integrity: sha512-ZjWrpiKADEmNhtfB64iVN3ejlDS5sS9OZx9+jN3mF+oqaroWqrTPvqQvY472M4ykL0JgT+AqsZdG+kWDqUw/6g==} peerDependencies: eslint: '>=6.8.0' dependencies: - eslint: 8.21.0 + eslint: 8.23.0 dev: true /eslint-import-resolver-node/0.3.6: @@ -10254,7 +11302,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + '@typescript-eslint/parser': 5.33.0_sorwav4hsh5vncerguqybud76i debug: 3.2.7 eslint-import-resolver-node: 0.3.6 find-up: 2.1.0 @@ -10262,7 +11310,7 @@ packages: - supports-color dev: true - /eslint-plugin-import/2.26.0_qfqnhzzittf54udqwes54xx65q: + /eslint-plugin-import/2.26.0_2oek2lsxxydv5vqayc4g7edtsi: resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} peerDependencies: @@ -10272,12 +11320,12 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + '@typescript-eslint/parser': 5.33.0_sorwav4hsh5vncerguqybud76i array-includes: 3.1.5 array.prototype.flat: 1.3.0 debug: 2.6.9 doctrine: 2.1.0 - eslint: 8.21.0 + eslint: 8.23.0 eslint-import-resolver-node: 0.3.6 eslint-module-utils: 2.7.3_oh3tx5uf4prsskzvqzbn7hm6ya has: 1.0.3 @@ -10293,7 +11341,7 @@ packages: - supports-color dev: true - /eslint-plugin-jsx-a11y/6.6.1_eslint@8.21.0: + /eslint-plugin-jsx-a11y/6.6.1_eslint@8.23.0: resolution: {integrity: sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==} engines: {node: '>=4.0'} peerDependencies: @@ -10307,7 +11355,7 @@ packages: axobject-query: 2.2.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 8.21.0 + eslint: 8.23.0 has: 1.0.3 jsx-ast-utils: 3.3.3 language-tags: 1.0.5 @@ -10330,16 +11378,16 @@ packages: requireindex: 1.1.0 dev: true - /eslint-plugin-react-hooks/4.6.0_eslint@8.21.0: + /eslint-plugin-react-hooks/4.6.0_eslint@8.23.0: resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.21.0 + eslint: 8.23.0 dev: true - /eslint-plugin-react/7.30.1_eslint@8.21.0: + /eslint-plugin-react/7.30.1_eslint@8.23.0: resolution: {integrity: sha512-NbEvI9jtqO46yJA3wcRF9Mo0lF9T/jhdHqhCHXiXtD+Zcb98812wvokjWpU7Q4QH5edo6dmqrukxVvWWXHlsUg==} engines: {node: '>=4'} peerDependencies: @@ -10348,7 +11396,7 @@ packages: array-includes: 3.1.5 array.prototype.flatmap: 1.3.0 doctrine: 2.1.0 - eslint: 8.21.0 + eslint: 8.23.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.3 minimatch: 3.1.2 @@ -10362,19 +11410,19 @@ packages: string.prototype.matchall: 4.0.7 dev: true - /eslint-plugin-vue/8.7.1_eslint@8.21.0: + /eslint-plugin-vue/8.7.1_eslint@8.23.0: resolution: {integrity: sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 dependencies: - eslint: 8.21.0 - eslint-utils: 3.0.0_eslint@8.21.0 + eslint: 8.23.0 + eslint-utils: 3.0.0_eslint@8.23.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.0.10 semver: 7.3.7 - vue-eslint-parser: 8.3.0_eslint@8.21.0 + vue-eslint-parser: 8.3.0_eslint@8.23.0 transitivePeerDependencies: - supports-color dev: true @@ -10404,13 +11452,13 @@ packages: eslint-visitor-keys: 2.1.0 dev: true - /eslint-utils/3.0.0_eslint@8.21.0: + /eslint-utils/3.0.0_eslint@8.23.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.21.0 + eslint: 8.23.0 eslint-visitor-keys: 2.1.0 dev: true @@ -10424,7 +11472,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint-webpack-plugin/3.1.1_7fh3pplfe77vb5lwiuqfjafe74: + /eslint-webpack-plugin/3.1.1_asfk4lnnm2udvewr2geiu7gcyy: resolution: {integrity: sha512-xSucskTN9tOkfW7so4EaiFIkulWLXwCB/15H917lR6pTv0Zot6/fetFucmENRb7J5whVSFKIvwnrnsa78SG2yg==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -10437,7 +11485,7 @@ packages: micromatch: 4.0.5 normalize-path: 3.0.0 schema-utils: 3.1.1 - webpack: 5.73.0_@swc+core@1.2.210 + webpack: 5.74.0_@swc+core@1.2.210 dev: true /eslint/8.14.0: @@ -10484,14 +11532,15 @@ packages: - supports-color dev: true - /eslint/8.21.0: - resolution: {integrity: sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==} + /eslint/8.23.0: + resolution: {integrity: sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint/eslintrc': 1.3.0 + '@eslint/eslintrc': 1.3.1 '@humanwhocodes/config-array': 0.10.4 '@humanwhocodes/gitignore-to-minimatch': 1.0.2 + '@humanwhocodes/module-importer': 1.0.1 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 @@ -10499,9 +11548,9 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.21.0 + eslint-utils: 3.0.0_eslint@8.23.0 eslint-visitor-keys: 3.3.0 - espree: 9.3.3 + espree: 9.4.0 esquery: 1.4.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -10527,28 +11576,16 @@ packages: strip-ansi: 6.0.1 strip-json-comments: 3.1.1 text-table: 0.2.0 - v8-compile-cache: 2.3.0 transitivePeerDependencies: - supports-color dev: true - /esno/0.14.1: - resolution: {integrity: sha512-yDFYw6dGUjCT1qKsdG7WOc/RzIh/qwxUEVZ+ohCltaxBxEFMNqeqbQL9xjRl6Yvdwrfc5OCjUA9JbFmuu/8BKg==} - hasBin: true - dependencies: - cross-spawn: 7.0.3 - esbuild: 0.15.1 - esbuild-node-loader: 0.6.5 - esbuild-register: 3.3.3_esbuild@0.15.1 - import-meta-resolve: 1.1.1 - dev: true - /espree/9.3.1: resolution: {integrity: sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.7.1 - acorn-jsx: 5.3.2_acorn@8.7.1 + acorn: 8.8.0 + acorn-jsx: 5.3.2_acorn@8.8.0 eslint-visitor-keys: 3.3.0 dev: true @@ -10561,6 +11598,15 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /espree/9.4.0: + resolution: {integrity: sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.8.0 + acorn-jsx: 5.3.2_acorn@8.8.0 + eslint-visitor-keys: 3.3.0 + dev: true + /esprima/4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} @@ -10653,6 +11699,33 @@ packages: strip-final-newline: 3.0.0 dev: true + /exit/0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + dev: true + + /expect/28.1.3: + resolution: {integrity: sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/expect-utils': 28.1.3 + jest-get-type: 28.0.2 + jest-matcher-utils: 28.1.3 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + dev: true + + /expect/29.0.3: + resolution: {integrity: sha512-t8l5DTws3212VbmPL+tBFXhjRHLmctHB0oQbL8eUc6S7NzZtYUhycrFO9mkxA0ZUC6FAWdNi7JchJSkODtcu1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/expect-utils': 29.0.3 + jest-get-type: 29.0.0 + jest-matcher-utils: 29.0.3 + jest-message-util: 29.0.3 + jest-util: 29.0.3 + dev: true + /express/4.18.1: resolution: {integrity: sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==} engines: {node: '>= 0.10.0'} @@ -10709,6 +11782,17 @@ packages: tmp: 0.0.33 dev: false + /extract-css-assets-webpack-plugin/0.2.10: + resolution: {integrity: sha512-eSZDqyRyB99gdQzite2ABI/WNQZy/bpnoNJFK6KLP4d7Tpo2tWtyAj22c3NWj/NQ8XI6yu56qRuIPZR06hpE+g==} + dependencies: + chalk: 2.4.2 + file-type: 8.1.0 + postcss: 7.0.39 + request: 2.88.2 + request-promise: 4.2.6_request@2.88.2 + webpack-sources: 2.3.1 + dev: false + /extract-zip/2.0.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} engines: {node: '>= 10.17.0'} @@ -10723,6 +11807,11 @@ packages: - supports-color dev: true + /extsprintf/1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + dev: false + /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -10764,6 +11853,12 @@ packages: dependencies: websocket-driver: 0.7.4 + /fb-watchman/2.0.1: + resolution: {integrity: sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==} + dependencies: + bser: 2.1.1 + dev: true + /fbemitter/3.0.0: resolution: {integrity: sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw==} dependencies: @@ -10826,6 +11921,11 @@ packages: schema-utils: 3.1.1 webpack: 5.74.0 + /file-type/8.1.0: + resolution: {integrity: sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==} + engines: {node: '>=6'} + dev: false + /filelist/1.0.3: resolution: {integrity: sha512-LwjCsruLWQULGYKy7TX0OPtrL9kLpojOFKc5VCTxdFTV7w5zbsgqVKfnkKG7Qgjtq50gKfO56hJv88OfcGb70Q==} dependencies: @@ -10915,27 +12015,6 @@ packages: - encoding dev: false - /follow-redirects/1.14.9: - resolution: {integrity: sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - /follow-redirects/1.14.9_debug@4.3.4: - resolution: {integrity: sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dependencies: - debug: 4.3.4 - dev: false - /follow-redirects/1.15.1: resolution: {integrity: sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==} engines: {node: '>=4.0'} @@ -10969,6 +12048,10 @@ packages: signal-exit: 3.0.7 dev: true + /forever-agent/0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + dev: false + /fork-ts-checker-webpack-plugin/6.5.2_xnp4kzegbjokq62cajex2ovgkm: resolution: {integrity: sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==} engines: {node: '>=10', yarn: '>=1.0.0'} @@ -10999,7 +12082,7 @@ packages: typescript: 4.7.4 webpack: 5.74.0 - /fork-ts-checker-webpack-plugin/7.2.6_dydffymiyrgjbmyedhp7lreziy: + /fork-ts-checker-webpack-plugin/7.2.6_spx7prkkl7pj6nxt6g3ewnbaqu: resolution: {integrity: sha512-q5rdvy7CaqEWyK3ly/AjSMQ+e3DGkjuqP0pkTwJcg+PHLhQfTJXqkmRIeA2y0TPfX4U00Et+AxS2ObAsVcm0hQ==} engines: {node: '>=12.13.0', yarn: '>=1.0.0'} peerDependencies: @@ -11022,9 +12105,18 @@ packages: semver: 7.3.7 tapable: 2.2.1 typescript: 4.6.4 - webpack: 5.73.0_@swc+core@1.2.210 + webpack: 5.74.0_@swc+core@1.2.210 dev: true + /form-data/2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + /form-data/4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -11032,7 +12124,6 @@ packages: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - dev: true /forwarded/0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} @@ -11042,7 +12133,7 @@ packages: resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} /fresh/0.5.2: - resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} /fs-constants/1.0.0: @@ -11162,7 +12253,12 @@ packages: /get-own-enumerable-property-symbols/3.0.2: resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} - /get-port/6.1.2: + /get-package-type/0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + dev: true + + /get-port/6.1.2: resolution: {integrity: sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true @@ -11195,6 +12291,16 @@ packages: call-bind: 1.0.2 get-intrinsic: 1.1.2 + /get-tsconfig/4.2.0: + resolution: {integrity: sha512-X8u8fREiYOE6S8hLbq99PeykTDoLVnxvF4DjWKJmz9xy2nNRdUcV8ZN9tniJFeKyTU3qnC9lL8n4Chd6LmVKHg==} + dev: true + + /getpass/0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + dependencies: + assert-plus: 1.0.0 + dev: false + /git-raw-commits/2.0.11: resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} engines: {node: '>=10'} @@ -11414,6 +12520,20 @@ packages: /handle-thing/2.0.1: resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} + /har-schema/2.0.0: + resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} + engines: {node: '>=4'} + dev: false + + /har-validator/5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + dependencies: + ajv: 6.12.6 + har-schema: 2.0.0 + dev: false + /hard-rejection/2.1.0: resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} engines: {node: '>=6'} @@ -11539,7 +12659,6 @@ packages: resolution: {integrity: sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==} dependencies: '@babel/runtime': 7.17.9 - dev: false /hoist-non-react-statics/3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} @@ -11667,6 +12786,24 @@ packages: - supports-color dev: true + /http-proxy-middleware/2.0.6: + resolution: {integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/express': ^4.17.13 + peerDependenciesMeta: + '@types/express': + optional: true + dependencies: + '@types/http-proxy': 1.17.8 + http-proxy: 1.18.1 + is-glob: 4.0.3 + is-plain-obj: 3.0.0 + micromatch: 4.0.5 + transitivePeerDependencies: + - debug + dev: true + /http-proxy-middleware/2.0.6_@types+express@4.17.13: resolution: {integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==} engines: {node: '>=12.0.0'} @@ -11709,7 +12846,7 @@ packages: engines: {node: '>=8.0.0'} dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.14.9 + follow-redirects: 1.15.1 requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -11719,12 +12856,21 @@ packages: engines: {node: '>=8.0.0'} dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.14.9_debug@4.3.4 + follow-redirects: 1.15.1_debug@4.3.4 requires-port: 1.0.0 transitivePeerDependencies: - debug dev: false + /http-signature/1.2.0: + resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} + engines: {node: '>=0.8', npm: '>=1.3.7'} + dependencies: + assert-plus: 1.0.0 + jsprim: 1.4.2 + sshpk: 1.17.0 + dev: false + /https-proxy-agent/5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -11865,10 +13011,13 @@ packages: engines: {node: '>=8'} dev: true - /import-meta-resolve/1.1.1: - resolution: {integrity: sha512-JiTuIvVyPaUg11eTrNDx5bgQ/yMKMZffc7YSjvQeSMXy58DO2SQ8BtAf3xteZvmzvjYh14wnqNjL8XVeDy2o9A==} + /import-local/3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true dependencies: - builtins: 4.1.0 + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 dev: true /imurmurhash/0.1.4: @@ -12070,6 +13219,11 @@ packages: engines: {node: '>=12'} dev: true + /is-generator-fn/2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + dev: true + /is-generator-function/1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} @@ -12294,11 +13448,28 @@ packages: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} + /isstream/0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + dev: false + /istanbul-lib-coverage/3.2.0: resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} engines: {node: '>=8'} dev: true + /istanbul-lib-instrument/5.2.0: + resolution: {integrity: sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.18.10 + '@babel/parser': 7.18.11 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + /istanbul-lib-report/3.0.0: resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} engines: {node: '>=8'} @@ -12308,6 +13479,17 @@ packages: supports-color: 7.2.0 dev: true + /istanbul-lib-source-maps/4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.4 + istanbul-lib-coverage: 3.2.0 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + /istanbul-reports/3.1.5: resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} engines: {node: '>=8'} @@ -12327,149 +13509,1079 @@ packages: minimatch: 3.1.2 dev: false - /jest-worker/27.5.1: - resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} - engines: {node: '>= 10.13.0'} + /jest-changed-files/28.1.3: + resolution: {integrity: sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} dependencies: - '@types/node': 17.0.27 - merge-stream: 2.0.0 - supports-color: 8.1.1 + execa: 5.1.1 + p-limit: 3.1.0 + dev: true - /joi/17.6.0: - resolution: {integrity: sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==} + /jest-changed-files/29.0.0: + resolution: {integrity: sha512-28/iDMDrUpGoCitTURuDqUzWQoWmOmOKOFST1mi2lwh62X4BFf6khgH3uSuo1e49X/UDjuApAj3w0wLOex4VPQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@hapi/hoek': 9.3.0 - '@hapi/topo': 5.1.0 - '@sideway/address': 4.1.4 - '@sideway/formula': 3.0.0 - '@sideway/pinpoint': 2.0.0 - - /js-base64/3.7.2: - resolution: {integrity: sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==} + execa: 5.1.1 + p-limit: 3.1.0 dev: true - /js-cookie/2.2.1: - resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} - dev: false - - /js-tokens/4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - /js-yaml/3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true + /jest-circus/28.1.3: + resolution: {integrity: sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} dependencies: - argparse: 1.0.10 - esprima: 4.0.1 + '@jest/environment': 28.1.3 + '@jest/expect': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 17.0.45 + chalk: 4.1.2 + co: 4.6.0 + dedent: 0.7.0 + is-generator-fn: 2.1.0 + jest-each: 28.1.3 + jest-matcher-utils: 28.1.3 + jest-message-util: 28.1.3 + jest-runtime: 28.1.3 + jest-snapshot: 28.1.3 + jest-util: 28.1.3 + p-limit: 3.1.0 + pretty-format: 28.1.3 + slash: 3.0.0 + stack-utils: 2.0.5 + transitivePeerDependencies: + - supports-color + dev: true - /js-yaml/4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true + /jest-circus/29.0.3: + resolution: {integrity: sha512-QeGzagC6Hw5pP+df1+aoF8+FBSgkPmraC1UdkeunWh0jmrp7wC0Hr6umdUAOELBQmxtKAOMNC3KAdjmCds92Zg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - argparse: 2.0.1 + '@jest/environment': 29.0.3 + '@jest/expect': 29.0.3 + '@jest/test-result': 29.0.3 + '@jest/types': 29.0.3 + '@types/node': 17.0.45 + chalk: 4.1.2 + co: 4.6.0 + dedent: 0.7.0 + is-generator-fn: 2.1.0 + jest-each: 29.0.3 + jest-matcher-utils: 29.0.3 + jest-message-util: 29.0.3 + jest-runtime: 29.0.3 + jest-snapshot: 29.0.3 + jest-util: 29.0.3 + p-limit: 3.1.0 + pretty-format: 29.0.3 + slash: 3.0.0 + stack-utils: 2.0.5 + transitivePeerDependencies: + - supports-color + dev: true - /jsdom/20.0.0: - resolution: {integrity: sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA==} - engines: {node: '>=14'} + /jest-cli/28.1.3: + resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + hasBin: true peerDependencies: - canvas: ^2.5.0 + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: - canvas: + node-notifier: optional: true dependencies: - abab: 2.0.6 - acorn: 8.8.0 - acorn-globals: 6.0.0 - cssom: 0.5.0 - cssstyle: 2.3.0 - data-urls: 3.0.2 - decimal.js: 10.3.1 - domexception: 4.0.0 - escodegen: 2.0.0 - form-data: 4.0.0 - html-encoding-sniffer: 3.0.0 - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.1 - parse5: 7.0.0 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 4.0.0 - w3c-hr-time: 1.0.2 - w3c-xmlserializer: 3.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 2.0.0 - whatwg-mimetype: 3.0.0 - whatwg-url: 11.0.0 - ws: 8.8.1 - xml-name-validator: 4.0.0 + '@jest/core': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/types': 28.1.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.10 + import-local: 3.1.0 + jest-config: 28.1.3 + jest-util: 28.1.3 + jest-validate: 28.1.3 + prompts: 2.4.2 + yargs: 17.5.1 transitivePeerDependencies: - - bufferutil + - '@types/node' - supports-color - - utf-8-validate + - ts-node dev: true - /jsesc/0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} - hasBin: true - - /jsesc/2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} + /jest-cli/29.0.3: + resolution: {integrity: sha512-aUy9Gd/Kut1z80eBzG10jAn6BgS3BoBbXyv+uXEqBJ8wnnuZ5RpNfARoskSrTIy1GY4a8f32YGuCMwibtkl9CQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true - - /json-buffer/3.0.0: - resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} - - /json-parse-even-better-errors/2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - - /json-schema-traverse/0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - /json-schema-traverse/1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - - /json-stable-stringify-without-jsonify/1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true - - /json2mq/0.2.0: - resolution: {integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true dependencies: - string-convert: 0.2.1 - dev: false + '@jest/core': 29.0.3 + '@jest/test-result': 29.0.3 + '@jest/types': 29.0.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.10 + import-local: 3.1.0 + jest-config: 29.0.3 + jest-util: 29.0.3 + jest-validate: 29.0.3 + prompts: 2.4.2 + yargs: 17.5.1 + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true - /json5/1.0.1: - resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} - hasBin: true + /jest-config/28.1.3: + resolution: {integrity: sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true dependencies: - minimist: 1.2.6 - - /json5/2.2.1: - resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} - engines: {node: '>=6'} - hasBin: true - - /jsonfile/4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - optionalDependencies: + '@babel/core': 7.18.10 + '@jest/test-sequencer': 28.1.3 + '@jest/types': 28.1.3 + babel-jest: 28.1.3_@babel+core@7.18.10 + chalk: 4.1.2 + ci-info: 3.4.0 + deepmerge: 4.2.2 + glob: 7.2.3 graceful-fs: 4.2.10 + jest-circus: 28.1.3 + jest-environment-node: 28.1.3 + jest-get-type: 28.0.2 + jest-regex-util: 28.0.2 + jest-resolve: 28.1.3 + jest-runner: 28.1.3 + jest-util: 28.1.3 + jest-validate: 28.1.3 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 28.1.3 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true - /jsonfile/6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + /jest-config/28.1.3_@types+node@17.0.45: + resolution: {integrity: sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true dependencies: - universalify: 2.0.0 - optionalDependencies: + '@babel/core': 7.18.10 + '@jest/test-sequencer': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 17.0.45 + babel-jest: 28.1.3_@babel+core@7.18.10 + chalk: 4.1.2 + ci-info: 3.4.0 + deepmerge: 4.2.2 + glob: 7.2.3 graceful-fs: 4.2.10 - - /jsonparse/1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} + jest-circus: 28.1.3 + jest-environment-node: 28.1.3 + jest-get-type: 28.0.2 + jest-regex-util: 28.0.2 + jest-resolve: 28.1.3 + jest-runner: 28.1.3 + jest-util: 28.1.3 + jest-validate: 28.1.3 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 28.1.3 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color dev: true - /jsx-ast-utils/2.4.1: + /jest-config/29.0.3: + resolution: {integrity: sha512-U5qkc82HHVYe3fNu2CRXLN4g761Na26rWKf7CjM8LlZB3In1jadEkZdMwsE37rd9RSPV0NfYaCjHdk/gu3v+Ew==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.18.10 + '@jest/test-sequencer': 29.0.3 + '@jest/types': 29.0.3 + babel-jest: 29.0.3_@babel+core@7.18.10 + chalk: 4.1.2 + ci-info: 3.4.0 + deepmerge: 4.2.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-circus: 29.0.3 + jest-environment-node: 29.0.3 + jest-get-type: 29.0.0 + jest-regex-util: 29.0.0 + jest-resolve: 29.0.3 + jest-runner: 29.0.3 + jest-util: 29.0.3 + jest-validate: 29.0.3 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.0.3 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-config/29.0.3_@types+node@17.0.45: + resolution: {integrity: sha512-U5qkc82HHVYe3fNu2CRXLN4g761Na26rWKf7CjM8LlZB3In1jadEkZdMwsE37rd9RSPV0NfYaCjHdk/gu3v+Ew==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.18.10 + '@jest/test-sequencer': 29.0.3 + '@jest/types': 29.0.3 + '@types/node': 17.0.45 + babel-jest: 29.0.3_@babel+core@7.18.10 + chalk: 4.1.2 + ci-info: 3.4.0 + deepmerge: 4.2.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-circus: 29.0.3 + jest-environment-node: 29.0.3 + jest-get-type: 29.0.0 + jest-regex-util: 29.0.0 + jest-resolve: 29.0.3 + jest-runner: 29.0.3 + jest-util: 29.0.3 + jest-validate: 29.0.3 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.0.3 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-diff/28.1.3: + resolution: {integrity: sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 28.1.1 + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + dev: true + + /jest-diff/29.0.3: + resolution: {integrity: sha512-+X/AIF5G/vX9fWK+Db9bi9BQas7M9oBME7egU7psbn4jlszLFCu0dW63UgeE6cs/GANq4fLaT+8sGHQQ0eCUfg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 29.0.0 + jest-get-type: 29.0.0 + pretty-format: 29.0.3 + dev: true + + /jest-docblock/28.1.1: + resolution: {integrity: sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + detect-newline: 3.1.0 + dev: true + + /jest-docblock/29.0.0: + resolution: {integrity: sha512-s5Kpra/kLzbqu9dEjov30kj1n4tfu3e7Pl8v+f8jOkeWNqM6Ds8jRaJfZow3ducoQUrf2Z4rs2N5S3zXnb83gw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + detect-newline: 3.1.0 + dev: true + + /jest-each/28.1.3: + resolution: {integrity: sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + chalk: 4.1.2 + jest-get-type: 28.0.2 + jest-util: 28.1.3 + pretty-format: 28.1.3 + dev: true + + /jest-each/29.0.3: + resolution: {integrity: sha512-wILhZfESURHHBNvPMJ0lZlYZrvOQJxAo3wNHi+ycr90V7M+uGR9Gh4+4a/BmaZF0XTyZsk4OiYEf3GJN7Ltqzg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.0.3 + chalk: 4.1.2 + jest-get-type: 29.0.0 + jest-util: 29.0.3 + pretty-format: 29.0.3 + dev: true + + /jest-environment-jsdom/29.0.3: + resolution: {integrity: sha512-KIGvpm12c71hoYTjL4wC2c8K6KfhOHJqJtaHc1IApu5rG047YWZoEP13BlbucWfzGISBrmli8KFqdhdQEa8Wnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.0.3 + '@jest/fake-timers': 29.0.3 + '@jest/types': 29.0.3 + '@types/jsdom': 20.0.0 + '@types/node': 17.0.45 + jest-mock: 29.0.3 + jest-util: 29.0.3 + jsdom: 20.0.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + dev: true + + /jest-environment-node/28.1.3: + resolution: {integrity: sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/environment': 28.1.3 + '@jest/fake-timers': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 17.0.45 + jest-mock: 28.1.3 + jest-util: 28.1.3 + dev: true + + /jest-environment-node/29.0.3: + resolution: {integrity: sha512-cdZqRCnmIlTXC+9vtvmfiY/40Cj6s2T0czXuq1whvQdmpzAnj4sbqVYuZ4zFHk766xTTJ+Ij3uUqkk8KCfXoyg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.0.3 + '@jest/fake-timers': 29.0.3 + '@jest/types': 29.0.3 + '@types/node': 17.0.45 + jest-mock: 29.0.3 + jest-util: 29.0.3 + dev: true + + /jest-get-type/28.0.2: + resolution: {integrity: sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dev: true + + /jest-get-type/29.0.0: + resolution: {integrity: sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-haste-map/28.1.3: + resolution: {integrity: sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + '@types/graceful-fs': 4.1.5 + '@types/node': 17.0.45 + anymatch: 3.1.2 + fb-watchman: 2.0.1 + graceful-fs: 4.2.10 + jest-regex-util: 28.0.2 + jest-util: 28.1.3 + jest-worker: 28.1.3 + micromatch: 4.0.5 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /jest-haste-map/29.0.3: + resolution: {integrity: sha512-uMqR99+GuBHo0RjRhOE4iA6LmsxEwRdgiIAQgMU/wdT2XebsLDz5obIwLZm/Psj+GwSEQhw9AfAVKGYbh2G55A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.0.3 + '@types/graceful-fs': 4.1.5 + '@types/node': 17.0.45 + anymatch: 3.1.2 + fb-watchman: 2.0.1 + graceful-fs: 4.2.10 + jest-regex-util: 29.0.0 + jest-util: 29.0.3 + jest-worker: 29.0.3 + micromatch: 4.0.5 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /jest-leak-detector/28.1.3: + resolution: {integrity: sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + dev: true + + /jest-leak-detector/29.0.3: + resolution: {integrity: sha512-YfW/G63dAuiuQ3QmQlh8hnqLDe25WFY3eQhuc/Ev1AGmkw5zREblTh7TCSKLoheyggu6G9gxO2hY8p9o6xbaRQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.0.0 + pretty-format: 29.0.3 + dev: true + + /jest-matcher-utils/28.1.3: + resolution: {integrity: sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 28.1.3 + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + dev: true + + /jest-matcher-utils/29.0.3: + resolution: {integrity: sha512-RsR1+cZ6p1hDV4GSCQTg+9qjeotQCgkaleIKLK7dm+U4V/H2bWedU3RAtLm8+mANzZ7eDV33dMar4pejd7047w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 29.0.3 + jest-get-type: 29.0.0 + pretty-format: 29.0.3 + dev: true + + /jest-message-util/28.1.3: + resolution: {integrity: sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@babel/code-frame': 7.18.6 + '@jest/types': 28.1.3 + '@types/stack-utils': 2.0.1 + chalk: 4.1.2 + graceful-fs: 4.2.10 + micromatch: 4.0.5 + pretty-format: 28.1.3 + slash: 3.0.0 + stack-utils: 2.0.5 + dev: true + + /jest-message-util/29.0.3: + resolution: {integrity: sha512-7T8JiUTtDfppojosORAflABfLsLKMLkBHSWkjNQrjIltGoDzNGn7wEPOSfjqYAGTYME65esQzMJxGDjuLBKdOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/code-frame': 7.18.6 + '@jest/types': 29.0.3 + '@types/stack-utils': 2.0.1 + chalk: 4.1.2 + graceful-fs: 4.2.10 + micromatch: 4.0.5 + pretty-format: 29.0.3 + slash: 3.0.0 + stack-utils: 2.0.5 + dev: true + + /jest-mock/28.1.3: + resolution: {integrity: sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + '@types/node': 17.0.45 + dev: true + + /jest-mock/29.0.3: + resolution: {integrity: sha512-ort9pYowltbcrCVR43wdlqfAiFJXBx8l4uJDsD8U72LgBcetvEp+Qxj1W9ZYgMRoeAo+ov5cnAGF2B6+Oth+ww==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.0.3 + '@types/node': 17.0.45 + dev: true + + /jest-pnp-resolver/1.2.2_jest-resolve@28.1.3: + resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 28.1.3 + dev: true + + /jest-pnp-resolver/1.2.2_jest-resolve@29.0.3: + resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 29.0.3 + dev: true + + /jest-regex-util/28.0.2: + resolution: {integrity: sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dev: true + + /jest-regex-util/29.0.0: + resolution: {integrity: sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-resolve-dependencies/28.1.3: + resolution: {integrity: sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + jest-regex-util: 28.0.2 + jest-snapshot: 28.1.3 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-resolve-dependencies/29.0.3: + resolution: {integrity: sha512-KzuBnXqNvbuCdoJpv8EanbIGObk7vUBNt/PwQPPx2aMhlv/jaXpUJsqWYRpP/0a50faMBY7WFFP8S3/CCzwfDw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-regex-util: 29.0.0 + jest-snapshot: 29.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-resolve/28.1.3: + resolution: {integrity: sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.10 + jest-haste-map: 28.1.3 + jest-pnp-resolver: 1.2.2_jest-resolve@28.1.3 + jest-util: 28.1.3 + jest-validate: 28.1.3 + resolve: 1.22.1 + resolve.exports: 1.1.0 + slash: 3.0.0 + dev: true + + /jest-resolve/29.0.3: + resolution: {integrity: sha512-toVkia85Y/BPAjJasTC9zIPY6MmVXQPtrCk8SmiheC4MwVFE/CMFlOtMN6jrwPMC6TtNh8+sTMllasFeu1wMPg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.10 + jest-haste-map: 29.0.3 + jest-pnp-resolver: 1.2.2_jest-resolve@29.0.3 + jest-util: 29.0.3 + jest-validate: 29.0.3 + resolve: 1.22.1 + resolve.exports: 1.1.0 + slash: 3.0.0 + dev: true + + /jest-runner/28.1.3: + resolution: {integrity: sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/console': 28.1.3 + '@jest/environment': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 17.0.45 + chalk: 4.1.2 + emittery: 0.10.2 + graceful-fs: 4.2.10 + jest-docblock: 28.1.1 + jest-environment-node: 28.1.3 + jest-haste-map: 28.1.3 + jest-leak-detector: 28.1.3 + jest-message-util: 28.1.3 + jest-resolve: 28.1.3 + jest-runtime: 28.1.3 + jest-util: 28.1.3 + jest-watcher: 28.1.3 + jest-worker: 28.1.3 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-runner/29.0.3: + resolution: {integrity: sha512-Usu6VlTOZlCZoNuh3b2Tv/yzDpKqtiNAetG9t3kJuHfUyVMNW7ipCCJOUojzKkjPoaN7Bl1f7Buu6PE0sGpQxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.0.3 + '@jest/environment': 29.0.3 + '@jest/test-result': 29.0.3 + '@jest/transform': 29.0.3 + '@jest/types': 29.0.3 + '@types/node': 17.0.45 + chalk: 4.1.2 + emittery: 0.10.2 + graceful-fs: 4.2.10 + jest-docblock: 29.0.0 + jest-environment-node: 29.0.3 + jest-haste-map: 29.0.3 + jest-leak-detector: 29.0.3 + jest-message-util: 29.0.3 + jest-resolve: 29.0.3 + jest-runtime: 29.0.3 + jest-util: 29.0.3 + jest-watcher: 29.0.3 + jest-worker: 29.0.3 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-runtime/28.1.3: + resolution: {integrity: sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/environment': 28.1.3 + '@jest/fake-timers': 28.1.3 + '@jest/globals': 28.1.3 + '@jest/source-map': 28.1.2 + '@jest/test-result': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + chalk: 4.1.2 + cjs-module-lexer: 1.2.2 + collect-v8-coverage: 1.0.1 + execa: 5.1.1 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-haste-map: 28.1.3 + jest-message-util: 28.1.3 + jest-mock: 28.1.3 + jest-regex-util: 28.0.2 + jest-resolve: 28.1.3 + jest-snapshot: 28.1.3 + jest-util: 28.1.3 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-runtime/29.0.3: + resolution: {integrity: sha512-12gZXRQ7ozEeEHKTY45a+YLqzNDR/x4c//X6AqwKwKJPpWM8FY4vwn4VQJOcLRS3Nd1fWwgP7LU4SoynhuUMHQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.0.3 + '@jest/fake-timers': 29.0.3 + '@jest/globals': 29.0.3 + '@jest/source-map': 29.0.0 + '@jest/test-result': 29.0.3 + '@jest/transform': 29.0.3 + '@jest/types': 29.0.3 + '@types/node': 17.0.45 + chalk: 4.1.2 + cjs-module-lexer: 1.2.2 + collect-v8-coverage: 1.0.1 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-haste-map: 29.0.3 + jest-message-util: 29.0.3 + jest-mock: 29.0.3 + jest-regex-util: 29.0.0 + jest-resolve: 29.0.3 + jest-snapshot: 29.0.3 + jest-util: 29.0.3 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-snapshot/28.1.3: + resolution: {integrity: sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@babel/core': 7.18.10 + '@babel/generator': 7.18.12 + '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.18.10 + '@babel/traverse': 7.18.11 + '@babel/types': 7.18.10 + '@jest/expect-utils': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + '@types/babel__traverse': 7.17.1 + '@types/prettier': 2.7.0 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.18.10 + chalk: 4.1.2 + expect: 28.1.3 + graceful-fs: 4.2.10 + jest-diff: 28.1.3 + jest-get-type: 28.0.2 + jest-haste-map: 28.1.3 + jest-matcher-utils: 28.1.3 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + natural-compare: 1.4.0 + pretty-format: 28.1.3 + semver: 7.3.7 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-snapshot/29.0.3: + resolution: {integrity: sha512-52q6JChm04U3deq+mkQ7R/7uy7YyfVIrebMi6ZkBoDJ85yEjm/sJwdr1P0LOIEHmpyLlXrxy3QP0Zf5J2kj0ew==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.18.10 + '@babel/generator': 7.18.12 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.18.10 + '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.18.10 + '@babel/traverse': 7.18.11 + '@babel/types': 7.18.10 + '@jest/expect-utils': 29.0.3 + '@jest/transform': 29.0.3 + '@jest/types': 29.0.3 + '@types/babel__traverse': 7.17.1 + '@types/prettier': 2.7.0 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.18.10 + chalk: 4.1.2 + expect: 29.0.3 + graceful-fs: 4.2.10 + jest-diff: 29.0.3 + jest-get-type: 29.0.0 + jest-haste-map: 29.0.3 + jest-matcher-utils: 29.0.3 + jest-message-util: 29.0.3 + jest-util: 29.0.3 + natural-compare: 1.4.0 + pretty-format: 29.0.3 + semver: 7.3.7 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-util/28.1.3: + resolution: {integrity: sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + '@types/node': 17.0.45 + chalk: 4.1.2 + ci-info: 3.4.0 + graceful-fs: 4.2.10 + picomatch: 2.3.1 + dev: true + + /jest-util/29.0.3: + resolution: {integrity: sha512-Q0xaG3YRG8QiTC4R6fHjHQPaPpz9pJBEi0AeOE4mQh/FuWOijFjGXMMOfQEaU9i3z76cNR7FobZZUQnL6IyfdQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.0.3 + '@types/node': 17.0.45 + chalk: 4.1.2 + ci-info: 3.4.0 + graceful-fs: 4.2.10 + picomatch: 2.3.1 + dev: true + + /jest-validate/28.1.3: + resolution: {integrity: sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 28.0.2 + leven: 3.1.0 + pretty-format: 28.1.3 + dev: true + + /jest-validate/29.0.3: + resolution: {integrity: sha512-OebiqqT6lK8cbMPtrSoS3aZP4juID762lZvpf1u+smZnwTEBCBInan0GAIIhv36MxGaJvmq5uJm7dl5gVt+Zrw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.0.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.0.0 + leven: 3.1.0 + pretty-format: 29.0.3 + dev: true + + /jest-watcher/28.1.3: + resolution: {integrity: sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/test-result': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 17.0.45 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.10.2 + jest-util: 28.1.3 + string-length: 4.0.2 + dev: true + + /jest-watcher/29.0.3: + resolution: {integrity: sha512-tQX9lU91A+9tyUQKUMp0Ns8xAcdhC9fo73eqA3LFxP2bSgiF49TNcc+vf3qgGYYK9qRjFpXW9+4RgF/mbxyOOw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.0.3 + '@jest/types': 29.0.3 + '@types/node': 17.0.45 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.10.2 + jest-util: 29.0.3 + string-length: 4.0.2 + dev: true + + /jest-worker/27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 17.0.27 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + /jest-worker/28.1.3: + resolution: {integrity: sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@types/node': 17.0.45 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jest-worker/29.0.3: + resolution: {integrity: sha512-Tl/YWUugQOjoTYwjKdfJWkSOfhufJHO5LhXTSZC3TRoQKO+fuXnZAdoXXBlpLXKGODBL3OvdUasfDD4PcMe6ng==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@types/node': 17.0.45 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jest/28.1.3: + resolution: {integrity: sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 28.1.3 + '@jest/types': 28.1.3 + import-local: 3.1.0 + jest-cli: 28.1.3 + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true + + /jest/29.0.3: + resolution: {integrity: sha512-ElgUtJBLgXM1E8L6K1RW1T96R897YY/3lRYqq9uVcPWtP2AAl/nQ16IYDh/FzQOOQ12VEuLdcPU83mbhG2C3PQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.0.3 + '@jest/types': 29.0.3 + import-local: 3.1.0 + jest-cli: 29.0.3 + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true + + /joi/17.6.0: + resolution: {integrity: sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==} + dependencies: + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.4 + '@sideway/formula': 3.0.0 + '@sideway/pinpoint': 2.0.0 + + /js-base64/3.7.2: + resolution: {integrity: sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==} + dev: true + + /js-cookie/2.2.1: + resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} + dev: false + + /js-tokens/4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + /js-yaml/3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + /js-yaml/4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + + /jsbn/0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + dev: false + + /jsdom/20.0.0: + resolution: {integrity: sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA==} + engines: {node: '>=14'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + dependencies: + abab: 2.0.6 + acorn: 8.8.0 + acorn-globals: 6.0.0 + cssom: 0.5.0 + cssstyle: 2.3.0 + data-urls: 3.0.2 + decimal.js: 10.3.1 + domexception: 4.0.0 + escodegen: 2.0.0 + form-data: 4.0.0 + html-encoding-sniffer: 3.0.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.1 + parse5: 7.0.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 4.0.0 + w3c-hr-time: 1.0.2 + w3c-xmlserializer: 3.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 2.0.0 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + ws: 8.8.1 + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /jsesc/0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + + /jsesc/2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + /json-buffer/3.0.0: + resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} + + /json-parse-even-better-errors/2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + /json-schema-traverse/0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + /json-schema-traverse/1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + /json-schema/0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + dev: false + + /json-stable-stringify-without-jsonify/1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json-stringify-safe/5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: false + + /json2mq/0.2.0: + resolution: {integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==} + dependencies: + string-convert: 0.2.1 + dev: false + + /json5/1.0.1: + resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} + hasBin: true + dependencies: + minimist: 1.2.6 + + /json5/2.2.1: + resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} + engines: {node: '>=6'} + hasBin: true + + /jsonfile/4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.10 + + /jsonfile/6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.10 + + /jsonparse/1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: true + + /jsprim/1.4.2: + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} + engines: {node: '>=0.6.0'} + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + dev: false + + /jsx-ast-utils/2.4.1: resolution: {integrity: sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==} engines: {node: '>=4.0'} dependencies: @@ -12528,7 +14640,7 @@ packages: dependencies: package-json: 6.5.0 - /less-loader/10.2.0_less@4.1.2+webpack@5.73.0: + /less-loader/10.2.0_less@4.1.2+webpack@5.74.0: resolution: {integrity: sha512-AV5KHWvCezW27GT90WATaDnfXBv99llDbtaj4bshq6DvAihMdNjaPDcUMa6EXKLRF+P2opFenJp89BXg91XLYg==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -12537,7 +14649,7 @@ packages: dependencies: klona: 2.0.5 less: 4.1.2 - webpack: 5.73.0_@swc+core@1.2.210 + webpack: 5.74.0_@swc+core@1.2.210 dev: true /less/4.1.2: @@ -12714,6 +14826,10 @@ packages: /lodash.merge/4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + /lodash.sortby/4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + dev: true + /lodash.truncate/4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} dev: true @@ -12830,6 +14946,12 @@ packages: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: true + /makeerror/1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + dependencies: + tmpl: 1.0.5 + dev: true + /map-obj/1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -12887,7 +15009,7 @@ packages: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} /media-typer/0.3.0: - resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} /memfs/3.4.1: @@ -12936,7 +15058,7 @@ packages: dev: true /merge-descriptors/1.0.1: - resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=} + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} /merge-stream/2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -13011,15 +15133,6 @@ packages: react: 17.0.2 tiny-warning: 1.0.3 - /mini-css-extract-plugin/2.6.0_webpack@5.73.0: - resolution: {integrity: sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==} - engines: {node: '>= 12.13.0'} - peerDependencies: - webpack: ^5.0.0 - dependencies: - schema-utils: 4.0.0 - webpack: 5.73.0_@swc+core@1.2.210 - /mini-css-extract-plugin/2.6.1_webpack@5.74.0: resolution: {integrity: sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==} engines: {node: '>= 12.13.0'} @@ -13027,7 +15140,7 @@ packages: webpack: ^5.0.0 dependencies: schema-utils: 4.0.0 - webpack: 5.74.0 + webpack: 5.74.0_@swc+core@1.2.210 /minimalistic-assert/1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} @@ -13164,6 +15277,14 @@ packages: dns-packet: 5.3.1 thunky: 1.1.0 + /multicast-dns/7.2.5: + resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true + dependencies: + dns-packet: 5.3.1 + thunky: 1.1.0 + dev: true + /mute-stream/0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} dev: false @@ -13233,6 +15354,10 @@ packages: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} + /node-int64/0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + dev: true + /node-releases/2.0.3: resolution: {integrity: sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw==} @@ -13327,6 +15452,10 @@ packages: resolution: {integrity: sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==} dev: true + /oauth-sign/0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + dev: false + /object-assign/4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -13705,6 +15834,14 @@ packages: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} dev: true + /performance-now/2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + dev: false + + /picocolors/0.2.1: + resolution: {integrity: sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==} + dev: false + /picocolors/1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -13728,6 +15865,11 @@ packages: engines: {node: '>=10'} dev: true + /pirates/4.0.5: + resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} + engines: {node: '>= 6'} + dev: true + /pkg-dir/4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -13749,6 +15891,7 @@ packages: mkdirp: 0.5.6 transitivePeerDependencies: - supports-color + dev: true /postcss-attribute-case-insensitive/5.0.0_postcss@8.4.12: resolution: {integrity: sha512-b4g9eagFGq9T5SWX4+USfVyjIb3liPnjhHHRMP7FMB2kFVpYyfEscV0wP3eaXhKlcHKUut8lt5BGoeylWA/dBQ==} @@ -13834,7 +15977,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 caniuse-api: 3.0.0 colord: 2.9.2 postcss: 8.4.12 @@ -13847,7 +15990,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 caniuse-api: 3.0.0 colord: 2.9.2 postcss: 8.4.14 @@ -13859,7 +16002,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 caniuse-api: 3.0.0 colord: 2.9.2 postcss: 8.4.16 @@ -14162,7 +16305,7 @@ packages: yaml: 1.10.2 dev: true - /postcss-loader/6.2.1_x2aj2q6umelkzhlylaf35s6ot4: + /postcss-loader/6.2.1_l7cnarxuwtifxq3zndacrkp2tq: resolution: {integrity: sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -14173,7 +16316,7 @@ packages: klona: 2.0.5 postcss: 8.4.12 semver: 7.3.7 - webpack: 5.73.0_@swc+core@1.2.210 + webpack: 5.74.0_@swc+core@1.2.210 dev: true /postcss-loader/7.0.1_m6qh27jiicejwnzfgs742cokpe: @@ -14259,7 +16402,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 caniuse-api: 3.0.0 cssnano-utils: 3.1.0_postcss@8.4.12 postcss: 8.4.12 @@ -14361,7 +16504,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 cssnano-utils: 3.1.0_postcss@8.4.12 postcss: 8.4.12 postcss-value-parser: 4.2.0 @@ -14726,7 +16869,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 postcss: 8.4.12 postcss-value-parser: 4.2.0 dev: true @@ -14737,7 +16880,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 postcss: 8.4.14 postcss-value-parser: 4.2.0 @@ -14747,7 +16890,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 postcss: 8.4.16 postcss-value-parser: 4.2.0 dev: true @@ -14962,7 +17105,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 caniuse-api: 3.0.0 postcss: 8.4.12 dev: true @@ -14973,7 +17116,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 caniuse-api: 3.0.0 postcss: 8.4.14 @@ -14983,7 +17126,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 caniuse-api: 3.0.0 postcss: 8.4.16 dev: true @@ -15144,6 +17287,14 @@ packages: dependencies: postcss: 8.4.14 + /postcss/7.0.39: + resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==} + engines: {node: '>=6.0.0'} + dependencies: + picocolors: 0.2.1 + source-map: 0.6.1 + dev: false + /postcss/8.4.12: resolution: {integrity: sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==} engines: {node: ^10 || ^12 || >=14} @@ -15204,6 +17355,25 @@ packages: react-is: 17.0.2 dev: true + /pretty-format/28.1.3: + resolution: {integrity: sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/schemas': 28.1.3 + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 18.2.0 + dev: true + + /pretty-format/29.0.3: + resolution: {integrity: sha512-cHudsvQr1K5vNVLbvYF/nv3Qy/F/BcEKxGuIeMiVMRHxPOO1RxXooP8g/ZrwAp7Dx+KdMZoOc7NxLHhMrP2f9Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.0.0 + ansi-styles: 5.2.0 + react-is: 18.2.0 + dev: true + /pretty-time/1.1.0: resolution: {integrity: sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==} engines: {node: '>=4'} @@ -15284,7 +17454,6 @@ packages: /psl/1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - dev: true /pump/3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} @@ -15343,6 +17512,11 @@ packages: dependencies: side-channel: 1.0.4 + /qs/6.5.3: + resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} + engines: {node: '>=0.6'} + dev: false + /queue-microtask/1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -15384,7 +17558,7 @@ packages: unpipe: 1.0.0 /rax-children/1.0.0_rax@1.2.2: - resolution: {integrity: sha512-sBKEXAMj9ik6SsPfPGgcQnqggmbWFyBdvAV/Cz/0f04bRA86BtWgbMri/9Dce0k8nkEC/BGWiiTdyA8Q49zIiw==} + resolution: {integrity: sha512-sBKEXAMj9ik6SsPfPGgcQnqggmbWFyBdvAV/Cz/0f04bRA86BtWgbMri/9Dce0k8nkEC/BGWiiTdyA8Q49zIiw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/rax-children/-/rax-children-1.0.0.tgz} engines: {npm: '>=3.0.0'} peerDependencies: rax: ^1.0.0 @@ -15393,7 +17567,7 @@ packages: dev: false /rax-clone-element/1.0.0_rax@1.2.2: - resolution: {integrity: sha512-TaQMVuzoglvCTjbWATlvvwARmeWnG8kpENWNXrNDv0++x29GHNND/TBbx7sdtVs/QmYwYc8YmwRUhaBwKQi5eQ==} + resolution: {integrity: sha512-TaQMVuzoglvCTjbWATlvvwARmeWnG8kpENWNXrNDv0++x29GHNND/TBbx7sdtVs/QmYwYc8YmwRUhaBwKQi5eQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/rax-clone-element/-/rax-clone-element-1.0.0.tgz} engines: {npm: '>=3.0.0'} peerDependencies: rax: ^1.0.0 @@ -15403,7 +17577,7 @@ packages: dev: false /rax-create-factory/1.0.0_rax@1.2.2: - resolution: {integrity: sha512-blBaVrurj/BOWelJhQWiuc0Kk8Ons1jsNsX78omaPBLkSOL7OkyJ3NC/0iKXHu425yWrGB6e5vho/qabROC7VQ==} + resolution: {integrity: sha512-blBaVrurj/BOWelJhQWiuc0Kk8Ons1jsNsX78omaPBLkSOL7OkyJ3NC/0iKXHu425yWrGB6e5vho/qabROC7VQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/rax-create-factory/-/rax-create-factory-1.0.0.tgz} engines: {npm: '>=3.0.0'} peerDependencies: rax: ^1.0.0 @@ -15412,7 +17586,7 @@ packages: dev: false /rax-image/2.4.1_rax@1.2.2: - resolution: {integrity: sha512-IVpFELlcj5LH3QfkfNE0hpOp28M4sPxB+4k3Y3Sq/8mUOuO1dhzM/C2+gfEz6UUB+rhFkTYKmmloguk9VtFAiQ==} + resolution: {integrity: sha512-IVpFELlcj5LH3QfkfNE0hpOp28M4sPxB+4k3Y3Sq/8mUOuO1dhzM/C2+gfEz6UUB+rhFkTYKmmloguk9VtFAiQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/rax-image/-/rax-image-2.4.1.tgz} peerDependencies: rax: ^1.0.0 dependencies: @@ -15421,12 +17595,12 @@ packages: dev: false /rax-is-valid-element/1.0.0: - resolution: {integrity: sha512-MM3IUAQRKn3EJ0D2vjxgobOJLplLAw3YxE7/IRM6ytDYzlPq5iIZ8wsXoPAp/qW3Y+n23HLQUIljmLKywcCEIA==} + resolution: {integrity: sha512-MM3IUAQRKn3EJ0D2vjxgobOJLplLAw3YxE7/IRM6ytDYzlPq5iIZ8wsXoPAp/qW3Y+n23HLQUIljmLKywcCEIA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/rax-is-valid-element/-/rax-is-valid-element-1.0.0.tgz} engines: {npm: '>=3.0.0'} dev: false /rax-text/2.2.0_rax@1.2.2: - resolution: {integrity: sha512-Li2Db3Q2o1gbo8D7gUDAvCONJkjQH7b1SjBL+FPLxIaQ6BZJ8KMYjBXzzbVneUR8VhXe4qBgNfsTonm8Lpvjkg==} + resolution: {integrity: sha512-Li2Db3Q2o1gbo8D7gUDAvCONJkjQH7b1SjBL+FPLxIaQ6BZJ8KMYjBXzzbVneUR8VhXe4qBgNfsTonm8Lpvjkg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/rax-text/-/rax-text-2.2.0.tgz} peerDependencies: rax: ^1.0.0 dependencies: @@ -15435,7 +17609,7 @@ packages: dev: false /rax-view/2.3.0_rax@1.2.2: - resolution: {integrity: sha512-8mzCiNvGu4RtcvWkZoFuWZNSTFac9peWwS+p+UtEsr8fLjhlgVmEFDTo+DbuQLDFtMIj8qfBdBJ9h6IRHCFXdg==} + resolution: {integrity: sha512-8mzCiNvGu4RtcvWkZoFuWZNSTFac9peWwS+p+UtEsr8fLjhlgVmEFDTo+DbuQLDFtMIj8qfBdBJ9h6IRHCFXdg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/rax-view/-/rax-view-2.3.0.tgz} peerDependencies: rax: ^1.0.0 dependencies: @@ -15445,10 +17619,10 @@ packages: dev: false /rax/1.2.2: - resolution: {integrity: sha512-SKUKSXoG2Dp+sFyiFyYzTGmhZlYGxusRSigcokAYTN3r4WTySreXs2WE+6nBBGg26aFyiCsBVHNeI86SQbVsQg==} + resolution: {integrity: sha512-SKUKSXoG2Dp+sFyiFyYzTGmhZlYGxusRSigcokAYTN3r4WTySreXs2WE+6nBBGg26aFyiCsBVHNeI86SQbVsQg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/rax/-/rax-1.2.2.tgz} engines: {npm: '>=3.0.0'} dependencies: - '@babel/runtime': 7.18.3 + '@babel/runtime': 7.18.9 driver-server: 1.0.0 prop-types: 15.8.1 rax-children: 1.0.0_rax@1.2.2 @@ -16106,6 +18280,10 @@ packages: /react-is/17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + /react-is/18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + dev: true + /react-json-view/1.21.3_sk3eihvpffgp52mstba5zhq3vu: resolution: {integrity: sha512-13p8IREj9/x/Ye4WI/JpjhoIwuzEgUAtgJZNBJckfzJt1qyh24BdTm6UQNGnyTq9dapQdrqvquZTo3dz1X6Cjw==} peerDependencies: @@ -16158,10 +18336,14 @@ packages: react-is: 17.0.2 dev: false - /react-refresh/0.12.0: - resolution: {integrity: sha512-suLIhrU2IHKL5JEKR/fAwJv7bbeq4kJ+pJopf77jHwuR+HmJS/HbrPIGsTBUVfw7tXPOmYv7UJ7PCaN49e8x4A==} + /react-refresh/0.13.0: + resolution: {integrity: sha512-XP8A9BT0CpRBD+NYLLeIhld/RqG9+gktUjW1FkE+Vm7OCinbG1SshcK5tb9ls4kzvjZr9mOQc7HYgBngEyPAXg==} + engines: {node: '>=0.10.0'} + dev: true + + /react-refresh/0.14.0: + resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} engines: {node: '>=0.10.0'} - dev: false /react-router-config/5.1.1_oyuskl3t7voyrff2xstzuy4hqu: resolution: {integrity: sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==} @@ -16197,7 +18379,6 @@ packages: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 react-router: 6.3.0_react@18.2.0 - dev: false /react-router/5.3.3_react@17.0.2: resolution: {integrity: sha512-mzQGUvS3bM84TnbtMYR8ZjKnuPJ71IjSzR+DE6UkUqvN4czWIqEs17yLL8xkAycv4ev0AiN+IGrWu88vJs/p2w==} @@ -16223,7 +18404,6 @@ packages: dependencies: history: 5.3.0 react: 18.2.0 - dev: false /react-textarea-autosize/8.3.4_skqlhrap4das3cz5b6iqdn2lqi: resolution: {integrity: sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==} @@ -16499,6 +18679,57 @@ packages: resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} engines: {node: '>=0.10'} + /request-promise-core/1.1.4_request@2.88.2: + resolution: {integrity: sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==} + engines: {node: '>=0.10.0'} + peerDependencies: + request: ^2.34 + dependencies: + lodash: 4.17.21 + request: 2.88.2 + dev: false + + /request-promise/4.2.6_request@2.88.2: + resolution: {integrity: sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==} + engines: {node: '>=0.10.0'} + deprecated: request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 + peerDependencies: + request: ^2.34 + dependencies: + bluebird: 3.7.2 + request: 2.88.2 + request-promise-core: 1.1.4_request@2.88.2 + stealthy-require: 1.1.1 + tough-cookie: 2.5.0 + dev: false + + /request/2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + dependencies: + aws-sign2: 0.7.0 + aws4: 1.11.0 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + har-validator: 5.1.5 + http-signature: 1.2.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + oauth-sign: 0.9.0 + performance-now: 2.1.0 + qs: 6.5.3 + safe-buffer: 5.2.1 + tough-cookie: 2.5.0 + tunnel-agent: 0.6.0 + uuid: 3.4.0 + dev: false + /require-all/3.0.0: resolution: {integrity: sha512-jPGN876lc5exWYrMcgZSd7U42P0PmVQzxnQB13fCSzmyGnqQWW4WUz5DosZ/qe24hz+5o9lSvW2epBNZ1xa6Fw==} engines: {node: '>= 0.8'} @@ -16533,6 +18764,13 @@ packages: resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} dev: false + /resolve-cwd/3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + dependencies: + resolve-from: 5.0.0 + dev: true + /resolve-from/4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -16553,14 +18791,13 @@ packages: resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==} /resolve-url/0.2.1: - resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/resolve-url/-/resolve-url-0.2.1.tgz} deprecated: https://github.com/lydell/resolve-url#deprecated dev: false /resolve.exports/1.1.0: resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==} engines: {node: '>=10'} - dev: false /resolve/1.22.0: resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==} @@ -16711,7 +18948,7 @@ packages: /safer-buffer/2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - /sass-loader/12.6.0_sass@1.50.0+webpack@5.73.0: + /sass-loader/12.6.0_sass@1.50.0+webpack@5.74.0: resolution: {integrity: sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -16733,7 +18970,7 @@ packages: klona: 2.0.5 neo-async: 2.6.2 sass: 1.50.0 - webpack: 5.73.0_@swc+core@1.2.210 + webpack: 5.74.0_@swc+core@1.2.210 dev: true /sass/1.50.0: @@ -17050,12 +19287,16 @@ packages: resolution: {integrity: sha512-PAIsEK/XupCQwitjv7XxoMvYhT7EAfyzI3hsy/MyDgTvc+Ft55ctdkctJLOy6cQejaIC+zjpUL4djFVm2ivOOw==} engines: {node: '>= 6.3.0'} + /source-list-map/2.0.1: + resolution: {integrity: sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==} + dev: false + /source-map-js/1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} /source-map-resolve/0.5.3: - resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz} deprecated: See https://github.com/lydell/source-map-resolve#deprecated dependencies: atob: 2.1.2 @@ -17065,6 +19306,13 @@ packages: urix: 0.1.0 dev: false + /source-map-support/0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + /source-map-support/0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: @@ -17072,7 +19320,7 @@ packages: source-map: 0.6.1 /source-map-url/0.4.1: - resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/source-map-url/-/source-map-url-0.4.1.tgz} deprecated: See https://github.com/lydell/source-map-url#deprecated dev: false @@ -17089,6 +19337,13 @@ packages: resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==} engines: {node: '>= 8'} + /source-map/0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + dependencies: + whatwg-url: 7.1.0 + dev: true + /sourcemap-codec/1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} @@ -17141,14 +19396,14 @@ packages: transitivePeerDependencies: - supports-color - /speed-measure-webpack-plugin/1.5.0_webpack@5.73.0: + /speed-measure-webpack-plugin/1.5.0_webpack@5.74.0: resolution: {integrity: sha512-Re0wX5CtM6gW7bZA64ONOfEPEhwbiSF/vz6e2GvadjuaPrQcHTQdRGsD8+BE7iUOysXH8tIenkPCQBEcspXsNg==} engines: {node: '>=6.0.0'} peerDependencies: webpack: ^1 || ^2 || ^3 || ^4 || ^5 dependencies: chalk: 4.1.2 - webpack: 5.73.0 + webpack: 5.74.0 dev: true /split2/3.2.2: @@ -17160,6 +19415,22 @@ packages: /sprintf-js/1.0.3: resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=} + /sshpk/1.17.0: + resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + dev: false + /ssri/9.0.0: resolution: {integrity: sha512-Y1Z6J8UYnexKFN1R/hxUaYoY2LVdKEzziPmVAFKiKX8fiwvCJTVzn/xYE9TEWod5OVyNfIHHuVfIEuBClL/uJQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -17171,9 +19442,15 @@ packages: resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + /stack-utils/2.0.5: + resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + /stackframe/1.2.1: resolution: {integrity: sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg==} - dev: false /staged-components/1.1.3_react@18.2.0: resolution: {integrity: sha512-9EIswzDqjwlEu+ymkV09TTlJfzSbKgEnNteUnZSTxkpMgr5Wx2CzzA9WcMFWBNCldqVPsHVnRGGrApduq2Se5A==} @@ -17197,6 +19474,11 @@ packages: /std-env/3.1.1: resolution: {integrity: sha512-/c645XdExBypL01TpFKiG/3RAa/Qmu+zRi0MwAmrdEkwHNuN0ebo8ccAXBBDa5Z0QOJgBskUIbuCK91x0sCVEw==} + /stealthy-require/1.1.1: + resolution: {integrity: sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==} + engines: {node: '>=0.10.0'} + dev: false + /streamsearch/1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -17215,6 +19497,14 @@ packages: resolution: {integrity: sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=} dev: true + /string-length/4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + dev: true + /string-width/1.0.2: resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} engines: {node: '>=0.10.0'} @@ -17325,6 +19615,11 @@ packages: engines: {node: '>=4'} dev: true + /strip-bom/4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + dev: true + /strip-final-newline/2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} @@ -17349,6 +19644,12 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + /strip-literal/0.4.1: + resolution: {integrity: sha512-z+F/xmDM8GOdvA5UoZXFxEnxdvMOZ+XEBIwjfLfc8hMSuHpGxjXAUCfuEo+t1GOHSb8+qgI/IBRpxXVMaABYWA==} + dependencies: + acorn: 8.8.0 + dev: true + /style-equal/1.0.0: resolution: {integrity: sha512-gf20kfwh7eXsgPcwvYqViCBHr+GXIlpXOZR1wQftNH4/ee2P/yolWUVA/MdMdmMp+0BMfvaMKSIR1DQlY64Btw==} dev: false @@ -17386,7 +19687,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 postcss: 8.4.12 postcss-selector-parser: 6.0.10 dev: true @@ -17397,7 +19698,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 postcss: 8.4.14 postcss-selector-parser: 6.0.10 @@ -17407,7 +19708,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - browserslist: 4.20.3 + browserslist: 4.21.3 postcss: 8.4.16 postcss-selector-parser: 6.0.10 dev: true @@ -17620,32 +19921,16 @@ packages: rimraf: 2.6.3 dev: false - /terser-webpack-plugin/5.3.1_4upc34oiflw3lduyjvrzpjntau: - resolution: {integrity: sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==} - engines: {node: '>= 10.13.0'} - peerDependencies: - '@swc/core': '*' - esbuild: '*' - uglify-js: '*' - webpack: ^5.1.0 - peerDependenciesMeta: - '@swc/core': - optional: true - esbuild: - optional: true - uglify-js: - optional: true + /terminal-link/2.1.1: + resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} + engines: {node: '>=8'} dependencies: - esbuild: 0.14.38 - jest-worker: 27.5.1 - schema-utils: 3.1.1 - serialize-javascript: 6.0.0 - source-map: 0.6.1 - terser: 5.12.1 - webpack: 5.73.0_esbuild@0.14.38 + ansi-escapes: 4.3.2 + supports-hyperlinks: 2.2.0 + dev: true - /terser-webpack-plugin/5.3.1_cr5ideiic2hpdwwauzasyctjxa: - resolution: {integrity: sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==} + /terser-webpack-plugin/5.3.3_webpack@5.74.0: + resolution: {integrity: sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -17660,16 +19945,15 @@ packages: uglify-js: optional: true dependencies: - '@swc/core': 1.2.210 + '@jridgewell/trace-mapping': 0.3.14 jest-worker: 27.5.1 schema-utils: 3.1.1 serialize-javascript: 6.0.0 - source-map: 0.6.1 terser: 5.12.1 - webpack: 5.73.0_@swc+core@1.2.210 + webpack: 5.74.0 - /terser-webpack-plugin/5.3.1_t4m2gfathmr3tyn5ako5vwnfhq: - resolution: {integrity: sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==} + /terser-webpack-plugin/5.3.5_3qmdnfoccgmcaqi5n264fyeyfi: + resolution: {integrity: sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -17684,17 +19968,16 @@ packages: uglify-js: optional: true dependencies: - '@swc/core': 1.2.210 - esbuild: 0.14.38 + '@jridgewell/trace-mapping': 0.3.14 + esbuild: 0.14.54 jest-worker: 27.5.1 schema-utils: 3.1.1 serialize-javascript: 6.0.0 - source-map: 0.6.1 - terser: 5.12.1 - webpack: 5.73.0_ohfecwmx44wixok6ry5c6snfbe + terser: 5.14.2 + webpack: 5.74.0_esbuild@0.14.54 - /terser-webpack-plugin/5.3.1_webpack@5.72.1: - resolution: {integrity: sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==} + /terser-webpack-plugin/5.3.5_vwzmvoh3samqo2nn3x7mqt365m: + resolution: {integrity: sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -17709,16 +19992,16 @@ packages: uglify-js: optional: true dependencies: + '@jridgewell/trace-mapping': 0.3.14 + '@swc/core': 1.2.210 jest-worker: 27.5.1 schema-utils: 3.1.1 serialize-javascript: 6.0.0 - source-map: 0.6.1 - terser: 5.12.1 - webpack: 5.72.1 - dev: true + terser: 5.14.2 + webpack: 5.74.0_@swc+core@1.2.210 - /terser-webpack-plugin/5.3.1_webpack@5.73.0: - resolution: {integrity: sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==} + /terser-webpack-plugin/5.3.5_webpack@5.74.0: + resolution: {integrity: sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -17733,16 +20016,15 @@ packages: uglify-js: optional: true dependencies: + '@jridgewell/trace-mapping': 0.3.14 jest-worker: 27.5.1 schema-utils: 3.1.1 serialize-javascript: 6.0.0 - source-map: 0.6.1 - terser: 5.12.1 - webpack: 5.73.0 - dev: true + terser: 5.14.2 + webpack: 5.74.0 - /terser-webpack-plugin/5.3.3_webpack@5.74.0: - resolution: {integrity: sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ==} + /terser-webpack-plugin/5.3.5_x4l7hn2bakumthvsejxf6gccjy: + resolution: {integrity: sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -17758,11 +20040,14 @@ packages: optional: true dependencies: '@jridgewell/trace-mapping': 0.3.14 + '@swc/core': 1.2.210 + esbuild: 0.14.54 jest-worker: 27.5.1 schema-utils: 3.1.1 serialize-javascript: 6.0.0 - terser: 5.12.1 - webpack: 5.74.0 + terser: 5.14.2 + webpack: 5.74.0_3cawqt5e67dzz3yqkvwzyd4tq4 + dev: true /terser/5.12.1: resolution: {integrity: sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==} @@ -17774,6 +20059,16 @@ packages: source-map: 0.7.3 source-map-support: 0.5.21 + /terser/5.14.2: + resolution: {integrity: sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.2 + acorn: 8.8.0 + commander: 2.20.3 + source-map-support: 0.5.21 + /test-exclude/6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -17809,16 +20104,30 @@ packages: /tiny-warning/1.0.3: resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + /tinybench/2.1.5: + resolution: {integrity: sha512-ak+PZZEuH3mw6CCFOgf5S90YH0MARnZNhxjhjguAmoJimEMAJuNip/rJRd6/wyylHItomVpKTzZk9zrhTrQCoQ==} + dev: true + /tinypool/0.1.3: resolution: {integrity: sha512-2IfcQh7CP46XGWGGbdyO4pjcKqsmVqFAPcXfPxcPXmOWt9cYkTP9HcDmGgsfijYoAEc4z9qcpM/BaBz46Y9/CQ==} engines: {node: '>=14.0.0'} dev: true + /tinypool/0.3.0: + resolution: {integrity: sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==} + engines: {node: '>=14.0.0'} + dev: true + /tinyspy/0.3.3: resolution: {integrity: sha512-gRiUR8fuhUf0W9lzojPf1N1euJYA30ISebSfgca8z76FOvXtVXqd5ojEIaKLWbDQhAaC3ibxZIjqbyi4ybjcTw==} engines: {node: '>=14.0.0'} dev: true + /tinyspy/1.0.2: + resolution: {integrity: sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==} + engines: {node: '>=14.0.0'} + dev: true + /tmp/0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -17826,6 +20135,10 @@ packages: os-tmpdir: 1.0.2 dev: false + /tmpl/1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + dev: true + /to-fast-properties/2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -17852,6 +20165,14 @@ packages: resolution: {integrity: sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==} engines: {node: '>=6'} + /tough-cookie/2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + dependencies: + psl: 1.9.0 + punycode: 2.1.1 + dev: false + /tough-cookie/4.0.0: resolution: {integrity: sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==} engines: {node: '>=6'} @@ -17864,6 +20185,12 @@ packages: /tr46/0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + /tr46/1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + dependencies: + punycode: 2.1.1 + dev: true + /tr46/3.0.0: resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} engines: {node: '>=12'} @@ -17905,6 +20232,39 @@ packages: - supports-color dev: false + /ts-jest/28.0.8_oavexkd2euoi6eueqpz7c42uqe: + resolution: {integrity: sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/types': ^28.0.0 + babel-jest: ^28.0.0 + esbuild: '*' + jest: ^28.0.0 + typescript: '>=4.3' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + jest: 28.1.3 + jest-util: 28.1.3 + json5: 2.2.1 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.3.7 + typescript: 4.8.3 + yargs-parser: 21.1.1 + dev: true + /ts-node/10.9.1_x2utdhayajzrh747hktprshhby: resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true @@ -17961,6 +20321,27 @@ packages: typescript: 4.7.4 dev: true + /tsx/3.9.0: + resolution: {integrity: sha512-ofxsE+qjqCYYq4UBt5khglvb+ESgxef1YpuNcdQI92kvcAT2tZVrnSK3g4bRXTUhLmKHcC5q8vIZA47os/stng==} + hasBin: true + dependencies: + '@esbuild-kit/cjs-loader': 2.3.3 + '@esbuild-kit/core-utils': 2.3.0 + '@esbuild-kit/esm-loader': 2.4.2 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /tunnel-agent/0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /tweetnacl/0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + dev: false + /type-check/0.3.2: resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} engines: {node: '>= 0.8.0'} @@ -18034,6 +20415,12 @@ packages: engines: {node: '>=4.2.0'} hasBin: true + /typescript/4.8.3: + resolution: {integrity: sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + /ua-parser-js/0.7.31: resolution: {integrity: sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==} dev: false @@ -18180,7 +20567,32 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - /unplugin/0.9.5_4upc34oiflw3lduyjvrzpjntau: + /unplugin/0.9.5_3qmdnfoccgmcaqi5n264fyeyfi: + resolution: {integrity: sha512-luraheyfxwtvkvHpsOvMNv7IjLdORTWKZp0gWYNHGLi2ImON3iIZOj464qEyyEwLA/EMt12fC415HW9zRpOfTg==} + peerDependencies: + esbuild: '>=0.13' + rollup: ^2.50.0 + vite: ^2.3.0 || ^3.0.0-0 + webpack: 4 || 5 + peerDependenciesMeta: + esbuild: + optional: true + rollup: + optional: true + vite: + optional: true + webpack: + optional: true + dependencies: + acorn: 8.8.0 + chokidar: 3.5.3 + esbuild: 0.14.54 + webpack: 5.74.0_3cawqt5e67dzz3yqkvwzyd4tq4 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.4.4 + dev: true + + /unplugin/0.9.5_webpack@5.74.0: resolution: {integrity: sha512-luraheyfxwtvkvHpsOvMNv7IjLdORTWKZp0gWYNHGLi2ImON3iIZOj464qEyyEwLA/EMt12fC415HW9zRpOfTg==} peerDependencies: esbuild: '>=0.13' @@ -18199,10 +20611,10 @@ packages: dependencies: acorn: 8.8.0 chokidar: 3.5.3 - esbuild: 0.14.38 - webpack: 5.73.0_esbuild@0.14.38 + webpack: 5.74.0_@swc+core@1.2.210 webpack-sources: 3.2.3 webpack-virtual-modules: 0.4.4 + dev: true /unquote/1.1.1: resolution: {integrity: sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==} @@ -18243,7 +20655,7 @@ packages: punycode: 2.1.1 /urix/0.1.0: - resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.com/urix/-/urix-0.1.0.tgz} deprecated: Please see https://github.com/lydell/urix#deprecated dev: false @@ -18347,9 +20759,15 @@ packages: engines: {node: '>= 4'} /utils-merge/1.0.1: - resolution: {integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=} + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + /uuid/3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + dev: false + /uuid/8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -18385,6 +20803,15 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + /verror/1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + dev: false + /vfile-location/3.2.0: resolution: {integrity: sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==} @@ -18463,14 +20890,91 @@ packages: - supports-color dev: true - /vue-eslint-parser/8.3.0_eslint@8.21.0: + /vitest/0.15.2_jsdom@20.0.0: + resolution: {integrity: sha512-cMabuUqu+nNHafkdN7H8Z20+UZTrrUfqjGwAoLwUwrqFGWBz3gXwxndjbLf6mgSFs9lF/JWjKeNM1CXKwtk26w==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@vitest/ui': '*' + c8: '*' + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@vitest/ui': + optional: true + c8: + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/chai': 4.3.3 + '@types/chai-subset': 1.3.3 + '@types/node': 17.0.45 + chai: 4.3.6 + debug: 4.3.4 + jsdom: 20.0.0 + local-pkg: 0.4.2 + tinypool: 0.1.3 + tinyspy: 0.3.3 + vite: 2.9.14 + transitivePeerDependencies: + - less + - sass + - stylus + - supports-color + dev: true + + /vitest/0.23.2_jsdom@20.0.0: + resolution: {integrity: sha512-kTBKp3ROPDkYC+x2zWt4znkDtnT08W1FQ6ngRFuqxpBGNuNVS+eWZKfffr8y2JGvEzZ9EzMAOcNaiqMj/FZqMw==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/chai': 4.3.3 + '@types/chai-subset': 1.3.3 + '@types/node': 17.0.45 + chai: 4.3.6 + debug: 4.3.4 + jsdom: 20.0.0 + local-pkg: 0.4.2 + strip-literal: 0.4.1 + tinybench: 2.1.5 + tinypool: 0.3.0 + tinyspy: 1.0.2 + vite: 2.9.14 + transitivePeerDependencies: + - less + - sass + - stylus + - supports-color + dev: true + + /vue-eslint-parser/8.3.0_eslint@8.23.0: resolution: {integrity: sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' dependencies: debug: 4.3.4 - eslint: 8.21.0 + eslint: 8.23.0 eslint-scope: 7.1.1 eslint-visitor-keys: 3.3.0 espree: 9.3.3 @@ -18521,12 +21025,11 @@ packages: - debug dev: false - /watchpack/2.3.1: - resolution: {integrity: sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==} - engines: {node: '>=10.13.0'} + /walker/1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} dependencies: - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.10 + makeerror: 1.0.12 + dev: true /watchpack/2.4.0: resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} @@ -18552,6 +21055,10 @@ packages: /webidl-conversions/3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + /webidl-conversions/4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + dev: true + /webidl-conversions/7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} @@ -18575,34 +21082,21 @@ packages: - bufferutil - utf-8-validate - /webpack-dev-middleware/5.3.1_webpack@5.73.0: - resolution: {integrity: sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==} - engines: {node: '>= 12.13.0'} - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - dependencies: - colorette: 2.0.16 - memfs: 3.4.1 - mime-types: 2.1.35 - range-parser: 1.2.1 - schema-utils: 4.0.0 - webpack: 5.73.0_@swc+core@1.2.210 - /webpack-dev-middleware/5.3.1_webpack@5.74.0: resolution: {integrity: sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==} engines: {node: '>= 12.13.0'} peerDependencies: webpack: ^4.0.0 || ^5.0.0 dependencies: - colorette: 2.0.16 + colorette: 2.0.19 memfs: 3.4.1 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.0.0 - webpack: 5.74.0 + webpack: 5.74.0_@swc+core@1.2.210 - /webpack-dev-server/4.8.1_webpack@5.73.0: - resolution: {integrity: sha512-dwld70gkgNJa33czmcj/PlKY/nOy/BimbrgZRaR9vDATBQAYgLzggR0nxDtPLJiLrMgZwbE6RRfJ5vnBBasTyg==} + /webpack-dev-server/4.10.0_webpack@5.74.0: + resolution: {integrity: sha512-7dezwAs+k6yXVFZ+MaL8VnE+APobiO3zvpp3rBHe/HmWQ+avwh0Q3d0xxacOiBybZZ3syTZw9HXzpa3YNbAZDQ==} engines: {node: '>= 12.13.0'} hasBin: true peerDependencies: @@ -18616,14 +21110,15 @@ packages: '@types/connect-history-api-fallback': 1.3.5 '@types/express': 4.17.13 '@types/serve-index': 1.9.1 + '@types/serve-static': 1.13.10 '@types/sockjs': 0.3.33 '@types/ws': 8.5.3 ansi-html-community: 0.0.8 - bonjour-service: 1.0.12 + bonjour-service: 1.0.13 chokidar: 3.5.3 - colorette: 2.0.16 + colorette: 2.0.19 compression: 1.7.4 - connect-history-api-fallback: 1.6.0 + connect-history-api-fallback: 2.0.0 default-gateway: 6.0.3 express: 4.18.1 graceful-fs: 4.2.10 @@ -18632,24 +21127,24 @@ packages: ipaddr.js: 2.0.1 open: 8.4.0 p-retry: 4.6.1 - portfinder: 1.0.28 rimraf: 3.0.2 schema-utils: 4.0.0 selfsigned: 2.0.1 serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack: 5.73.0_@swc+core@1.2.210 - webpack-dev-middleware: 5.3.1_webpack@5.73.0 - ws: 8.5.0 + webpack: 5.74.0_@swc+core@1.2.210 + webpack-dev-middleware: 5.3.1_webpack@5.74.0 + ws: 8.8.1 transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate + dev: true - /webpack-dev-server/4.9.3_debug@4.3.4+webpack@5.74.0: - resolution: {integrity: sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw==} + /webpack-dev-server/4.8.1_webpack@5.74.0: + resolution: {integrity: sha512-dwld70gkgNJa33czmcj/PlKY/nOy/BimbrgZRaR9vDATBQAYgLzggR0nxDtPLJiLrMgZwbE6RRfJ5vnBBasTyg==} engines: {node: '>= 12.13.0'} hasBin: true peerDependencies: @@ -18663,7 +21158,6 @@ packages: '@types/connect-history-api-fallback': 1.3.5 '@types/express': 4.17.13 '@types/serve-index': 1.9.1 - '@types/serve-static': 1.13.10 '@types/sockjs': 0.3.33 '@types/ws': 8.5.3 ansi-html-community: 0.0.8 @@ -18671,22 +21165,23 @@ packages: chokidar: 3.5.3 colorette: 2.0.16 compression: 1.7.4 - connect-history-api-fallback: 2.0.0 + connect-history-api-fallback: 1.6.0 default-gateway: 6.0.3 express: 4.18.1 graceful-fs: 4.2.10 html-entities: 2.3.3 - http-proxy-middleware: 2.0.6_vw7eq5saxorls4jwsr6ncij7dm + http-proxy-middleware: 2.0.6_@types+express@4.17.13 ipaddr.js: 2.0.1 open: 8.4.0 p-retry: 4.6.1 + portfinder: 1.0.28 rimraf: 3.0.2 schema-utils: 4.0.0 selfsigned: 2.0.1 serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack: 5.74.0 + webpack: 5.74.0_3cawqt5e67dzz3yqkvwzyd4tq4 webpack-dev-middleware: 5.3.1_webpack@5.74.0 ws: 8.5.0 transitivePeerDependencies: @@ -18694,9 +21189,9 @@ packages: - debug - supports-color - utf-8-validate - dev: false + dev: true - /webpack-dev-server/4.9.3_webpack@5.73.0: + /webpack-dev-server/4.9.3_debug@4.3.4+webpack@5.74.0: resolution: {integrity: sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw==} engines: {node: '>= 12.13.0'} hasBin: true @@ -18724,7 +21219,7 @@ packages: express: 4.18.1 graceful-fs: 4.2.10 html-entities: 2.3.3 - http-proxy-middleware: 2.0.6_@types+express@4.17.13 + http-proxy-middleware: 2.0.6_vw7eq5saxorls4jwsr6ncij7dm ipaddr.js: 2.0.1 open: 8.4.0 p-retry: 4.6.1 @@ -18734,15 +21229,15 @@ packages: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack: 5.73.0_esbuild@0.14.38 - webpack-dev-middleware: 5.3.1_webpack@5.73.0 + webpack: 5.74.0 + webpack-dev-middleware: 5.3.1_webpack@5.74.0 ws: 8.5.0 transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - dev: true + dev: false /webpack-dev-server/4.9.3_webpack@5.74.0: resolution: {integrity: sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw==} @@ -18782,7 +21277,7 @@ packages: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack: 5.74.0 + webpack: 5.74.0_esbuild@0.14.54 webpack-dev-middleware: 5.3.1_webpack@5.74.0 ws: 8.5.0 transitivePeerDependencies: @@ -18798,95 +21293,24 @@ packages: clone-deep: 4.0.1 wildcard: 2.0.0 + /webpack-sources/2.3.1: + resolution: {integrity: sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==} + engines: {node: '>=10.13.0'} + dependencies: + source-list-map: 2.0.1 + source-map: 0.6.1 + dev: false + /webpack-sources/3.2.3: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} /webpack-virtual-modules/0.4.4: resolution: {integrity: sha512-h9atBP/bsZohWpHnr+2sic8Iecb60GxftXsWNLLLSqewgIsGzByd2gcIID4nXcG+3tNe4GQG3dLcff3kXupdRA==} - - /webpack/5.72.1: - resolution: {integrity: sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - dependencies: - '@types/eslint-scope': 3.7.3 - '@types/estree': 0.0.51 - '@webassemblyjs/ast': 1.11.1 - '@webassemblyjs/wasm-edit': 1.11.1 - '@webassemblyjs/wasm-parser': 1.11.1 - acorn: 8.7.0 - acorn-import-assertions: 1.8.0_acorn@8.7.0 - browserslist: 4.20.3 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.9.3 - es-module-lexer: 0.9.3 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.10 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.1.1 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.1_webpack@5.72.1 - watchpack: 2.3.1 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - dev: true - - /webpack/5.73.0: - resolution: {integrity: sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - dependencies: - '@types/eslint-scope': 3.7.3 - '@types/estree': 0.0.51 - '@webassemblyjs/ast': 1.11.1 - '@webassemblyjs/wasm-edit': 1.11.1 - '@webassemblyjs/wasm-parser': 1.11.1 - acorn: 8.7.1 - acorn-import-assertions: 1.8.0_acorn@8.7.1 - browserslist: 4.20.3 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.9.3 - es-module-lexer: 0.9.3 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.10 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.1.1 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.1_webpack@5.73.0 - watchpack: 2.3.1 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js dev: true - /webpack/5.73.0_@swc+core@1.2.210: - resolution: {integrity: sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==} + /webpack/5.74.0: + resolution: {integrity: sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -18900,11 +21324,11 @@ packages: '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/wasm-edit': 1.11.1 '@webassemblyjs/wasm-parser': 1.11.1 - acorn: 8.7.1 - acorn-import-assertions: 1.8.0_acorn@8.7.1 - browserslist: 4.20.3 + acorn: 8.8.0 + acorn-import-assertions: 1.8.0_acorn@8.8.0 + browserslist: 4.21.3 chrome-trace-event: 1.0.3 - enhanced-resolve: 5.9.3 + enhanced-resolve: 5.10.0 es-module-lexer: 0.9.3 eslint-scope: 5.1.1 events: 3.3.0 @@ -18916,16 +21340,16 @@ packages: neo-async: 2.6.2 schema-utils: 3.1.1 tapable: 2.2.1 - terser-webpack-plugin: 5.3.1_cr5ideiic2hpdwwauzasyctjxa - watchpack: 2.3.1 + terser-webpack-plugin: 5.3.5_webpack@5.74.0 + watchpack: 2.4.0 webpack-sources: 3.2.3 transitivePeerDependencies: - '@swc/core' - esbuild - uglify-js - /webpack/5.73.0_esbuild@0.14.38: - resolution: {integrity: sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==} + /webpack/5.74.0_3cawqt5e67dzz3yqkvwzyd4tq4: + resolution: {integrity: sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -18939,11 +21363,11 @@ packages: '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/wasm-edit': 1.11.1 '@webassemblyjs/wasm-parser': 1.11.1 - acorn: 8.7.1 - acorn-import-assertions: 1.8.0_acorn@8.7.1 - browserslist: 4.20.3 + acorn: 8.8.0 + acorn-import-assertions: 1.8.0_acorn@8.8.0 + browserslist: 4.21.3 chrome-trace-event: 1.0.3 - enhanced-resolve: 5.9.3 + enhanced-resolve: 5.10.0 es-module-lexer: 0.9.3 eslint-scope: 5.1.1 events: 3.3.0 @@ -18955,16 +21379,17 @@ packages: neo-async: 2.6.2 schema-utils: 3.1.1 tapable: 2.2.1 - terser-webpack-plugin: 5.3.1_4upc34oiflw3lduyjvrzpjntau - watchpack: 2.3.1 + terser-webpack-plugin: 5.3.5_x4l7hn2bakumthvsejxf6gccjy + watchpack: 2.4.0 webpack-sources: 3.2.3 transitivePeerDependencies: - '@swc/core' - esbuild - uglify-js + dev: true - /webpack/5.73.0_ohfecwmx44wixok6ry5c6snfbe: - resolution: {integrity: sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==} + /webpack/5.74.0_@swc+core@1.2.210: + resolution: {integrity: sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -18978,11 +21403,11 @@ packages: '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/wasm-edit': 1.11.1 '@webassemblyjs/wasm-parser': 1.11.1 - acorn: 8.7.1 - acorn-import-assertions: 1.8.0_acorn@8.7.1 - browserslist: 4.20.3 + acorn: 8.8.0 + acorn-import-assertions: 1.8.0_acorn@8.8.0 + browserslist: 4.21.3 chrome-trace-event: 1.0.3 - enhanced-resolve: 5.9.3 + enhanced-resolve: 5.10.0 es-module-lexer: 0.9.3 eslint-scope: 5.1.1 events: 3.3.0 @@ -18994,15 +21419,15 @@ packages: neo-async: 2.6.2 schema-utils: 3.1.1 tapable: 2.2.1 - terser-webpack-plugin: 5.3.1_t4m2gfathmr3tyn5ako5vwnfhq - watchpack: 2.3.1 + terser-webpack-plugin: 5.3.5_vwzmvoh3samqo2nn3x7mqt365m + watchpack: 2.4.0 webpack-sources: 3.2.3 transitivePeerDependencies: - '@swc/core' - esbuild - uglify-js - /webpack/5.74.0: + /webpack/5.74.0_esbuild@0.14.54: resolution: {integrity: sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==} engines: {node: '>=10.13.0'} hasBin: true @@ -19033,7 +21458,7 @@ packages: neo-async: 2.6.2 schema-utils: 3.1.1 tapable: 2.2.1 - terser-webpack-plugin: 5.3.3_webpack@5.74.0 + terser-webpack-plugin: 5.3.5_3qmdnfoccgmcaqi5n264fyeyfi watchpack: 2.4.0 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -19091,6 +21516,14 @@ packages: tr46: 0.0.3 webidl-conversions: 3.0.1 + /whatwg-url/7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + dev: true + /which-boxed-primitive/1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: diff --git a/tests/integration/app-config.test.ts b/tests/integration/app-config.test.ts new file mode 100644 index 000000000..c06ee3ad5 --- /dev/null +++ b/tests/integration/app-config.test.ts @@ -0,0 +1,38 @@ +import { expect, test, describe, afterAll } from 'vitest'; +import { buildFixture, setupBrowser } from '../utils/build'; +import { startFixture, setupStartBrowser } from '../utils/start'; +import type { Page } from '../utils/browser'; +import type Browser from '../utils/browser'; + +const example = 'app-config'; + +describe(`build ${example}`, () => { + test('open /', async () => { + await buildFixture(example); + await setupBrowser({ example }); + }, 120000); +}); + +describe(`start ${example}`, () => { + let page: Page; + let browser: Browser; + + test('setup devServer', async () => { + const { devServer, port } = await startFixture(example); + const res = await setupStartBrowser({ server: devServer, port }); + page = res.page; + browser = res.browser; + await page.push('/ice'); + expect(await page.$$text('h1')).toStrictEqual(['home']); + }, 120000); + + test('error page', async () => { + await page.push('/ice/error'); + await page.waitForNetworkIdle(); + expect(await page.$$text('h1')).toStrictEqual(['Something went wrong.']); + }, 120000); + + afterAll(async () => { + await browser.close(); + }); +}); diff --git a/tests/integration/basic-project.test.ts b/tests/integration/basic-project.test.ts index 2063607ac..2dc550797 100644 --- a/tests/integration/basic-project.test.ts +++ b/tests/integration/basic-project.test.ts @@ -1,10 +1,11 @@ -import { expect, test, describe, afterAll } from 'vitest'; import * as path from 'path'; import * as fs from 'fs'; import { fileURLToPath } from 'url'; +import { expect, test, describe, afterAll } from 'vitest'; import { buildFixture, setupBrowser } from '../utils/build'; import { startFixture, setupStartBrowser } from '../utils/start'; -import Browser, { Page } from '../utils/browser'; +import type { Page } from '../utils/browser'; +import type Browser from '../utils/browser'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -44,7 +45,7 @@ describe(`build ${example}`, () => { test('disable splitChunks', async () => { await buildFixture(example, { - config: 'splitChunks.config.mts' + config: 'splitChunks.config.mts', }); const res = await setupBrowser({ example }); page = res.page; @@ -62,47 +63,73 @@ describe(`build ${example}`, () => { describe(`start ${example}`, () => { let page: Page; let browser: Browser; + const rootDir = path.join(__dirname, `../../examples/${example}`); test('setup devServer', async () => { - const { devServer, port } = await startFixture(example); + const { devServer, port } = await startFixture(example, { + mock: true, + force: true, + https: false, + analyzer: false, + open: false, + mode: 'start', + }); const res = await setupStartBrowser({ server: devServer, port }); page = res.page; browser = res.browser; expect(await page.$$text('h2')).toStrictEqual(['Home Page']); expect(await page.$$text('#data-from')).toStrictEqual(['getServerData']); }, 120000); - // TODO: fix waitForNetworkIdle not resolved - test.skip('should update config during client routing', async () => { - const { devServer, port } = await startFixture(example); - const res = await setupStartBrowser({ server: devServer, port }); - page = res.page; - browser = res.browser; + test('update route', async () => { + const targetPath = path.join(rootDir, 'src/pages/blog.tsx'); + const routeContent = fs.readFileSync(targetPath, 'utf-8'); + const routeManifest = fs.readFileSync(path.join(rootDir, '.ice/route-manifest.json'), 'utf-8'); + fs.writeFileSync(targetPath, routeContent); + await page.reload(); + expect(JSON.parse(routeManifest)[0].children.length).toBe(3); + }, 120000); + + test('update watched file: global.css', async () => { + const targetPath = path.join(rootDir, 'src/global.css'); + const cssContent = fs.readFileSync(targetPath, 'utf-8'); + fs.writeFileSync(targetPath, cssContent); + await page.reload(); + }); + + test('update watched file: app.ts', async () => { + const targetPath = path.join(rootDir, 'src/app.tsx'); + const appContent = fs.readFileSync(targetPath, 'utf-8'); + fs.writeFileSync(targetPath, appContent); + await page.reload(); + }); + + test('should update config during client routing', async () => { expect( - await page.title() + await page.title(), ).toBe('Home'); expect( - await page.$$attr('meta[name="theme-color"]', 'content') + await page.$$attr('meta[name="theme-color"]', 'content'), ).toStrictEqual(['#000']); - await page.click('a[href="/about"]'); + await page.push('/about'); await page.waitForNetworkIdle(); expect( - await page.title() + await page.title(), ).toBe('About'); expect( - await page.$$attr('meta[name="theme-color"]', 'content') + await page.$$attr('meta[name="theme-color"]', 'content'), ).toStrictEqual(['#eee']); expect( - await page.$$eval('link[href*="bootstrap"]', (els) => els.length) + await page.$$eval('link[href*="bootstrap"]', (els) => els.length), ).toBe(1); expect( - await page.$$eval('script[src*="lodash"]', (els) => els.length) + await page.$$eval('script[src*="lodash"]', (els) => els.length), ).toBe(1); }, 120000); diff --git a/tests/integration/hash-router.test.ts b/tests/integration/hash-router.test.ts index 01bb2d4ba..7f857be1d 100644 --- a/tests/integration/hash-router.test.ts +++ b/tests/integration/hash-router.test.ts @@ -1,7 +1,7 @@ import { expect, test, describe, afterAll } from 'vitest'; import { buildFixture, setupBrowser } from '../utils/build'; import { startFixture, setupStartBrowser } from '../utils/start'; -import Browser from '../utils/browser'; +import type Browser from '../utils/browser'; import type { Page } from '../utils/browser'; const example = 'hash-router'; @@ -15,8 +15,8 @@ describe(`build ${example}`, () => { const res = await setupBrowser({ example, disableJS: false }); page = res.page as Page; browser = res.browser; - await page.waitForFunction(`document.getElementsByTagName('h1').length > 0`); - await page.waitForFunction(`document.getElementsByTagName('h2').length > 0`); + await page.waitForFunction('document.getElementsByTagName(\'h1\').length > 0'); + await page.waitForFunction('document.getElementsByTagName(\'h2\').length > 0'); expect(await page.$$text('h1')).toStrictEqual(['Layout']); expect(await page.$$text('h2')).toStrictEqual(['Home']); }, 120000); @@ -28,15 +28,13 @@ describe(`build ${example}`, () => { describe(`start ${example}`, () => { let page: Page; - let browser: Browser; test('open /', async () => { const { devServer, port } = await startFixture(example); const res = await setupStartBrowser({ server: devServer, port }); page = res.page; - browser = res.browser; - await page.waitForFunction(`document.getElementsByTagName('h1').length > 0`); - await page.waitForFunction(`document.getElementsByTagName('h2').length > 0`); + await page.waitForFunction('document.getElementsByTagName(\'h1\').length > 0'); + await page.waitForFunction('document.getElementsByTagName(\'h2\').length > 0'); expect(await page.$$text('h1')).toStrictEqual(['Layout']); expect(await page.$$text('h2')).toStrictEqual(['Home']); }, 120000); diff --git a/tests/integration/rax-inline-style.test.ts b/tests/integration/rax-inline-style.test.ts new file mode 100644 index 000000000..93c53d2d3 --- /dev/null +++ b/tests/integration/rax-inline-style.test.ts @@ -0,0 +1,57 @@ +import { expect, test, describe, afterAll } from 'vitest'; +import { buildFixture, setupBrowser } from '../utils/build'; +import { startFixture, setupStartBrowser } from '../utils/start'; +import type { Page } from '../utils/browser'; + +const example = 'rax-inline-style'; + +describe(`build ${example}`, () => { + let page: Page = null; + let browser = null; + + test('open /', async () => { + await buildFixture(example); + const res = await setupBrowser({ example }); + + page = res.page; + browser = res.browser; + // inline index.module.less + expect((await page.$$attr('img', 'style'))[0]).contain('height:24vw'); + // inline index.module.css + expect((await page.$$attr('span', 'style'))[0]).contain('font-weight:bold'); + // inline css from node_modules + expect((await page.$$attr('span', 'style'))[0]).contain('display:block'); + // inline index.css + expect((await page.$$attr('span', 'style'))[1]).contain('color:rgb(85,85,85)'); + }, 120000); + + afterAll(async () => { + await browser.close(); + }); +}); + +describe(`start ${example}`, () => { + let page: Page = null; + let browser = null; + + test('setup devServer', async () => { + const { devServer, port } = await startFixture(example); + const res = await setupStartBrowser({ server: devServer, port }); + page = res.page; + browser = res.browser; + await page.waitForFunction('document.getElementsByTagName(\'span\').length > 0'); + + // inline index.module.less + expect((await page.$$attr('img', 'style'))[0]).contain('height:24vw'); + // inline index.module.css + expect((await page.$$attr('span', 'style'))[0]).contain('font-weight:bold'); + // inline css from node_modules + expect((await page.$$attr('span', 'style'))[0]).contain('display:block'); + // inline index.css + expect((await page.$$attr('span', 'style'))[1]).contain('color:rgb(85,85,85)'); + }, 120000); + + afterAll(async () => { + await browser.close(); + }); +}); diff --git a/tests/integration/rax-project.test.ts b/tests/integration/rax-project.test.ts index c6f871aef..0115a751b 100644 --- a/tests/integration/rax-project.test.ts +++ b/tests/integration/rax-project.test.ts @@ -3,7 +3,7 @@ import * as fs from 'fs'; import { expect, test, describe, afterAll } from 'vitest'; import { buildFixture, setupBrowser } from '../utils/build'; import { startFixture, setupStartBrowser } from '../utils/start'; -import { Page } from '../utils/browser'; +import type { Page } from '../utils/browser'; const example = 'rax-project'; @@ -39,7 +39,7 @@ describe(`start ${example}`, () => { const res = await setupStartBrowser({ server: devServer, port }); page = res.page; browser = res.browser; - await page.waitForFunction(`document.getElementsByTagName('span').length > 0`); + await page.waitForFunction('document.getElementsByTagName(\'span\').length > 0'); expect((await page.$$text('span')).length).toEqual(3); expect((await page.$$text('span'))[0]).toStrictEqual('Welcome to Your Rax App'); expect((await page.$$text('span'))[1]).toStrictEqual('More information about Rax'); diff --git a/tests/integration/routes-generate.test.ts b/tests/integration/routes-generate.test.ts index 07880a910..762935408 100644 --- a/tests/integration/routes-generate.test.ts +++ b/tests/integration/routes-generate.test.ts @@ -1,13 +1,14 @@ import { expect, test, describe, afterAll } from 'vitest'; import { buildFixture, setupBrowser } from '../utils/build'; import { startFixture, setupStartBrowser } from '../utils/start'; -import { Page } from '../utils/browser'; +import type { Page } from '../utils/browser'; +import type Browser from '../utils/browser'; const example = 'routes-generate'; describe(`build ${example}`, () => { - let page: Page = null; - let browser = null; + let page: Page; + let browser: Browser; test('open /', async () => { await buildFixture(example); @@ -19,30 +20,22 @@ describe(`build ${example}`, () => { }, 120000); test('define extra routes', async () => { - let res = await setupBrowser({ example, defaultHtml: 'about-me.html' }); - page = res.page; - browser = res.browser; + await page.push('/about-me.html'); expect(await page.$$text('h1')).toStrictEqual([]); expect(await page.$$text('h2')).toStrictEqual(['About']); - res = await setupBrowser({ example, defaultHtml: 'product.html' }); - page = res.page; - browser = res.browser; + await page.push('/product.html'); expect(await page.$$text('h1')).toStrictEqual(['Layout']); expect(await page.$$text('h2')).toStrictEqual(['Products Page']); }); test('page layout', async () => { - let res = await setupBrowser({ example, defaultHtml: 'dashboard/a.html' }); - page = res.page; - browser = res.browser; + await page.push('/dashboard/a.html'); expect(await page.$$text('h1')).toStrictEqual(['Layout']); expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); expect(await page.$$text('h3')).toStrictEqual(['A page']); - res = await setupBrowser({ example, defaultHtml: 'dashboard/b.html' }); - page = res.page; - browser = res.browser; + await page.push('/dashboard/b.html'); expect(await page.$$text('h1')).toStrictEqual(['Layout']); expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); expect(await page.$$text('h3')).toStrictEqual(['B page']); @@ -57,10 +50,10 @@ describe(`build ${example}`, () => { }); describe(`start ${example}`, () => { - let page: Page = null; - let browser = null; + let page: Page; + let browser: Browser; - test('setup devServer', async () => { + test('open /', async () => { const { devServer, port } = await startFixture(example); const res = await setupStartBrowser({ server: devServer, port }); page = res.page; @@ -70,33 +63,33 @@ describe(`start ${example}`, () => { }, 120000); test('define extra routes', async () => { - await page.push('about-me'); + await page.push('/about-me'); expect(await page.$$text('h1')).toStrictEqual([]); expect(await page.$$text('h2')).toStrictEqual(['About']); - await page.push('product'); + await page.push('/product'); expect(await page.$$text('h1')).toStrictEqual(['Layout']); expect(await page.$$text('h2')).toStrictEqual(['Products Page']); }); test('page layout', async () => { - await page.push('dashboard/a'); + await page.push('/dashboard/a'); expect(await page.$$text('h1')).toStrictEqual(['Layout']); expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); expect(await page.$$text('h3')).toStrictEqual(['A page']); - await page.push('dashboard/b'); + await page.push('/dashboard/b'); expect(await page.$$text('h1')).toStrictEqual(['Layout']); expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); expect(await page.$$text('h3')).toStrictEqual(['B page']); }); test('dynamic routes layout', async () => { - await page.push('detail/a'); + await page.push('/detail/a'); expect(await page.$$text('h1')).toStrictEqual(['Layout']); expect(await page.$$text('h2')).toStrictEqual(['Detail id: a']); - await page.push('detail/b'); + await page.push('/detail/b'); expect(await page.$$text('h1')).toStrictEqual(['Layout']); expect(await page.$$text('h2')).toStrictEqual(['Detail id: b']); }); diff --git a/tests/integration/single-router.test.ts b/tests/integration/single-router.test.ts index b882b425a..caa3c013a 100644 --- a/tests/integration/single-router.test.ts +++ b/tests/integration/single-router.test.ts @@ -1,6 +1,6 @@ -import { expect, test, describe, afterAll } from 'vitest'; import * as path from 'path'; import * as fs from 'fs'; +import { expect, test, describe, afterAll } from 'vitest'; import { buildFixture } from '../utils/build'; const example = 'single-route'; @@ -11,22 +11,20 @@ describe(`build ${example}`, () => { test('optimize router', async () => { await buildFixture(example, { - config: 'optimization.config.mts' + config: 'optimization.config.mts', }); const dataLoaderPath = path.join(__dirname, `../../examples/${example}/build/js/framework.js`); sizeWithOptimize = fs.statSync(dataLoaderPath).size; - }, 120000); test('disable optimize router', async () => { await buildFixture(example); const dataLoaderPath = path.join(__dirname, `../../examples/${example}/build/js/framework.js`); sizeWithoutOptimize = fs.statSync(dataLoaderPath).size; - }, 120000); afterAll(async () => { expect(sizeWithOptimize).toBeLessThan(sizeWithoutOptimize); - expect(sizeWithoutOptimize - sizeWithOptimize).toBeGreaterThan(6 * 1024) // reduce more than 6kb after minify + expect(sizeWithoutOptimize - sizeWithOptimize).toBeGreaterThan(6 * 1024); // reduce more than 6kb after minify }); }); diff --git a/tests/integration/with-store.test.ts b/tests/integration/with-store.test.ts index 4e695a937..0235f86dc 100644 --- a/tests/integration/with-store.test.ts +++ b/tests/integration/with-store.test.ts @@ -14,7 +14,7 @@ describe(`build ${example}`, () => { const res = await setupBrowser({ example, disableJS: false }); page = res.page; browser = res.browser; - await page.waitForFunction(`document.getElementsByTagName('button').length > 0`); + await page.waitForFunction('document.getElementsByTagName(\'button\').length > 0'); expect(await page.$$text('#username')).toStrictEqual(['name: ICE 3']); expect(await page.$$text('#count')).toStrictEqual(['0']); }, 120000); diff --git a/tests/utils/browser.ts b/tests/utils/browser.ts index 8b64cdc74..bd978ebe6 100644 --- a/tests/utils/browser.ts +++ b/tests/utils/browser.ts @@ -1,16 +1,16 @@ import http from 'http'; import url from 'url'; -import fse from 'fs-extra'; import path from 'path'; +import fse from 'fs-extra'; import puppeteer from 'puppeteer'; export interface Page extends puppeteer.Page { - html?: () => Promise<string>; - $text?: (selector: string, trim?: boolean) => Promise<string|null>; - $$text?: (selector: string, trim?: boolean) => Promise<(string|null)[]>; - $attr?: (selector: string, attr: string) => Promise<string|null>; - $$attr?: (selector: string, attr: string) => Promise<(string|null)[]>; - push?: (url: string, options?: puppeteer.WaitForOptions & { referer?: string }) => Promise<puppeteer.HTTPResponse>; + html: () => Promise<string>; + $text: (selector: string, trim?: boolean) => Promise<string | null>; + $$text: (selector: string, trim?: boolean) => Promise<(string | null)[]>; + $attr: (selector: string, attr: string) => Promise<string | null>; + $$attr: (selector: string, attr: string) => Promise<(string | null)[]>; + push: (url: string, options?: puppeteer.WaitForOptions & { referer?: string }) => Promise<puppeteer.HTTPResponse>; } interface BrowserOptions { @@ -24,20 +24,20 @@ export default class Browser { private browser: puppeteer.Browser; private baseUrl: string; - constructor (options: BrowserOptions) { + constructor(options: BrowserOptions) { const { server } = options; if (server) { this.server = server; } else { const { cwd, port } = options; - this.server = this.createServer(cwd, port); + this.server = this.createServer(cwd!, port!); } } createServer(cwd: string, port: number) { return http.createServer((req, res) => { - const requrl: string = req.url || ''; - const pathname = `${cwd}${url.parse(requrl).pathname}`.split(path.sep).join('/'); + const reqUrl: string = req.url || ''; + const pathname = `${cwd}${url.parse(reqUrl).pathname}`.split(path.sep).join('/'); if (fse.existsSync(pathname)) { switch (path.extname(pathname)) { // set HTTP HEAD case '.html': @@ -74,12 +74,12 @@ export default class Browser { }).listen(port, '127.0.0.1'); } - async start () { + async start() { this.browser = await puppeteer.launch(); } - async close () { - if (!this.browser) { return } + async close() { + if (!this.browser) { return; } await this.browser.close(); // @ts-ignore if (this.server.stop) { @@ -90,25 +90,27 @@ export default class Browser { } } - async page (url: string, disableJS?: boolean) { - this.baseUrl = url; + async page(baseUrl: string, path = '/', disableJS?: boolean): Promise<Page> { + this.baseUrl = baseUrl; + if (!this.browser) { throw new Error('Please call start() before page(url)'); } - const page: Page = await this.browser.newPage(); + const page = (await this.browser.newPage()) as Page; if (disableJS) { page.setJavaScriptEnabled(false); } - await page.goto(url); + await page.goto(`${this.baseUrl}${path}`); + page.push = (url, options) => page.goto(`${this.baseUrl}${url}`, options); page.html = () => page.evaluate(() => window.document.documentElement.outerHTML); page.$text = (selector, trim) => page.$eval(selector, (el, trim) => { - return trim ? (el.textContent || '').replace(/^\s+|\s+$/g, '') : el.textContent + return trim ? (el.textContent || '').replace(/^\s+|\s+$/g, '') : el.textContent; }, trim); page.$$text = (selector, trim) => page.$$eval(selector, (els, trim) => els.map((el) => { - return trim ? (el.textContent || '').replace(/^\s+|\s+$/g, '') : el.textContent + return trim ? (el.textContent || '').replace(/^\s+|\s+$/g, '') : el.textContent; }), trim); page.$attr = (selector, attr) => @@ -120,6 +122,7 @@ export default class Browser { (els, attr) => els.map(el => el.getAttribute(attr as string)), attr, ); + return page; } } diff --git a/tests/utils/build.ts b/tests/utils/build.ts index d63d23966..293f53bdb 100644 --- a/tests/utils/build.ts +++ b/tests/utils/build.ts @@ -1,9 +1,10 @@ import path from 'path'; import process from 'process'; +import { fileURLToPath } from 'url'; import getPort from 'get-port'; -import Browser, { Page } from './browser'; import createService from '../../packages/ice/src/createService'; -import { fileURLToPath } from 'url'; +import type { Page } from './browser'; +import Browser from './browser'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -22,14 +23,16 @@ interface ReturnValue { } // get builtIn plugins -export const buildFixture = async function(example: string, commandArgs?: Record<string, string>) { +export const buildFixture = async function (example: string, commandArgs?: Record<string, string>) { const rootDir = path.join(__dirname, `../../examples/${example}`); process.env.DISABLE_FS_CACHE = 'true'; - const service = await createService({ rootDir, command: 'build', commandArgs: { + const service = await createService({ rootDir, +command: 'build', +commandArgs: { ...(commandArgs || {}), } }); await service.run(); -} +}; export const setupBrowser: SetupBrowser = async (options) => { const { example, outputDir = 'build', defaultHtml = 'index.html', disableJS = true } = options; @@ -37,11 +40,12 @@ export const setupBrowser: SetupBrowser = async (options) => { const port = await getPort(); const browser = new Browser({ cwd: path.join(rootDir, outputDir), port }); await browser.start(); - console.log() - // when preview html generate by build, the path will not match the router info, so hydrate will not found the route component - const page = await browser.page(`http://127.0.0.1:${port}/${defaultHtml}`, disableJS); + console.log(); + // When preview html generate by build, the path will not match the router info, + // so hydrate will not found the route component. + const page = await browser.page(`http://127.0.0.1:${port}`, `/${defaultHtml}`, disableJS); return { browser, page, - } -} + }; +}; diff --git a/tests/utils/executeCommand.ts b/tests/utils/executeCommand.ts index fe83aceaf..2dc848695 100644 --- a/tests/utils/executeCommand.ts +++ b/tests/utils/executeCommand.ts @@ -6,4 +6,4 @@ export default (order: string, cwd: string) => { stdio: 'inherit', cwd, }); -} +}; diff --git a/tests/utils/start.ts b/tests/utils/start.ts index df7b14cd0..ec53ccad2 100644 --- a/tests/utils/start.ts +++ b/tests/utils/start.ts @@ -1,14 +1,15 @@ import path from 'path'; +import type { Server } from 'http'; +import { fileURLToPath } from 'url'; import getPort from 'get-port'; -import Browser, { Page } from './browser'; -import { Server } from 'http'; import createService from '../../packages/ice/src/createService'; -import { fileURLToPath } from 'url'; +import type { Page } from './browser'; +import Browser from './browser'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); interface SetupBrowser { - (options: { port: number; defaultPath?: string; server: Server; }): Promise<ReturnValue>; + (options: { port: number; defaultPath?: string; server: Server }): Promise<ReturnValue>; } interface ReturnValue { @@ -17,36 +18,39 @@ interface ReturnValue { } // get builtIn plugins -export const startFixture = async function (example: string) { +export const startFixture = async function (example: string, commandArgs?: Record<string, any>) { const port = await getPort(); const rootDir = path.join(__dirname, `../../examples/${example}`); process.env.DISABLE_FS_CACHE = 'true'; - const service = await createService({ rootDir, command: 'start', commandArgs: { + const service = await createService({ rootDir, +command: 'start', +commandArgs: { host: '0.0.0.0', port, open: false, - }}); + ...commandArgs, + } }); // @ts-ignore const { compiler, devServer } = await service.run(); // wait generate assets manifest await new Promise((resolve) => { - compiler.hooks.done.tap('done',() => { + compiler.hooks.done.tap('done', () => { resolve(true); - }) + }); }); return { port, - devServer + devServer, }; }; export const setupStartBrowser: SetupBrowser = async (options) => { - const { port, server, defaultPath = '' } = options; + const { port, server, defaultPath = '/' } = options; const browser = new Browser({ server }); await browser.start(); - const page = await browser.page(`http://127.0.0.1:${port}/${defaultPath}`); + const page = await browser.page(`http://127.0.0.1:${port}`, defaultPath); return { browser, page, diff --git a/tests/utils/test-plugin.ts b/tests/utils/test-plugin.ts index 20fcec3d4..a7266861c 100644 --- a/tests/utils/test-plugin.ts +++ b/tests/utils/test-plugin.ts @@ -3,4 +3,4 @@ export default ({ modifyUserConfig }) => { modifyUserConfig('minify', false); // disable sourceMap to speed-up fixture start modifyUserConfig('sourceMap', false); -} \ No newline at end of file +}; \ No newline at end of file diff --git a/vitest.config.ts b/vitest.config.ts index e230074fd..d644e882c 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -18,12 +18,15 @@ export default defineConfig({ '**/node_modules/**', '**/esm/**', '**/tests/fixtures/**', + 'examples/**', ], coverage: { reporter: ['cobertura', 'text'], include: ['**/packages/**'], exclude: [ '**/bundles/compiled/**', + // App runtime has been tested by unit test case + '**/packages/runtime/esm/**', '**/tests/**', ], }, diff --git a/website/docs/guide/basic/config.md b/website/docs/guide/basic/config.md index 799592098..50e265f17 100644 --- a/website/docs/guide/basic/config.md +++ b/website/docs/guide/basic/config.md @@ -259,8 +259,8 @@ export default defineConfig({ ### server -- 类型:`{ format: 'esm' | 'cjs'; bundle: boolean }` -- 默认值:`{ format: 'esm', bundle: false }` +- 类型:`{ format: 'esm' | 'cjs'; bundle: boolean; ignores: IgnorePattern[] }` +- 默认值:`{ format: 'esm', bundle: false, ignores: [] }` SSR / SSG 产物标准,推荐以 ESM 标准进行执行,如果希望打包成一个 cjs 模块,可以进行如下设置: @@ -275,6 +275,25 @@ export default defineConfig({ }); ``` +可以通过 `ignores` 参数,为 SSR / SSG 产物过滤指定文件: + +```js +import { defineConfig } from '@ice/app'; + +export default defineConfig({ + server: { + ignores: [{ + resourceRegExp: /^\.\/locale$/, + contextRegExp: /moment$/, + }] + }, +}); +``` + +其中: +* resourceRegExp 对应文件的匹配路径 +* contextRegExp (可选)对应文件内容的匹配规则 + ### routes - 类型:`{ignoreFiles: string[]; defineRoutes: (route) => void}` diff --git a/website/docs/guide/basic/page.md b/website/docs/guide/basic/page.md index 0f3f54fff..55664ed44 100644 --- a/website/docs/guide/basic/page.md +++ b/website/docs/guide/basic/page.md @@ -27,17 +27,17 @@ export default function Home() { } ``` -## getData() +## 获取页面初始数据 -获取页面初始数据的方法,详见[数据请求](./request.md)。 +详见[数据请求](./request.md)。 -## getConfig() +## 配置页面运行时属性 -获取页面运行时配置的方法,页面主体内容之外的,其他需要通用 HTML 模板上差异化显示的内容,可以通过导出 `getConfig` 方法来声明。 +页面主体内容之外的、其他需要通用 HTML 模板上差异化显示的内容,可以通过导出 `getConfig` 方法来声明。 -支持的页面级配置包含: +支持的页面级配置包含: -#### title +### title 标题会显示在文档上,可以通过 `title` 属性来设置。 示例: @@ -49,9 +49,9 @@ export function getConfig() { } ``` -#### metas +### metas -Meta 信息会显示在文档上,可以通过 `meta` 属性来设置。 示例: +Meta 信息会显示在文档上,可以通过 `metas` 属性来设置。 示例: ```tsx export function getConfig() { @@ -67,7 +67,7 @@ export function getConfig() { } ``` -#### links +### links 页面级需要额外插入的 `<link />` 标签,会被插入 `<head>` 标签内,先于页面自身的 Bundle 加载,是阻塞型的。 diff --git a/website/docs/guide/best-practices/unit-test.md b/website/docs/guide/best-practices/unit-test.md index d9918165c..04515d4bc 100644 --- a/website/docs/guide/best-practices/unit-test.md +++ b/website/docs/guide/best-practices/unit-test.md @@ -1,7 +1,270 @@ --- title: 单元测试 order: 8 -hide: true --- -@TODO +icejs 不耦合任何一个测试框架,开发者可自由选择。目前提供开箱即用的 [jest](https://jestjs.io/) 和 [vitest](https://vitest.dev/) 配置,以便快速开始单元测试。 + +<details> + <summary>示例</summary> + <ul> + <li> + <a href="https://github.com/ice-lab/ice-next/tree/master/examples/with-jest" target="_blank" rel="noopener noreferrer"> + icejs with jest + </a> + </li> + <li> + <a href="https://github.com/ice-lab/ice-next/tree/master/examples/with-vitest" target="_blank" rel="noopener noreferrer"> + icejs with vitest + </a> + </li> + </ul> +</details> + +## Jest + +### 依赖安装 + +```bash +$ npm i jest -D +``` + +> 如果使用 TypeScript 编写单元测试,推荐接入使用 [@swc/jest](https://swc.rs/docs/usage/jest) 或 [ts-jest](https://kulshekhar.github.io/ts-jest/docs/getting-started/installation) + +### 配置 + +首先需要在项目的根目录下新建 `jest.config.mjs` 文件,并加入以下内容: + +```js title="jest.config.mjs" +import { defineJestConfig } from '@ice/app'; + +export default defineJestConfig({}); +``` + +`defineJestConfig` 方法返回的是 icejs 默认配置好的 Jest 配置,支持传入自定义的 [Jest 配置](https://jestjs.io/docs/configuration)。 + +`defineJestConfig` 入参支持两种写法: + +- `jest.Config` +- `() => Promise<jest.Config>` + +以添加 `@swc/jest` 为例: +```diff title="jest.config.mjs" +import { defineJestConfig } from '@ice/app'; + +export default defineJestConfig({ ++ transform: { ++ '^.+\\.(t|j)sx?$': [ ++ '@swc/jest', ++ { ++ // swc 配置 ++ jsc: { ++ transform: { ++ react: { ++ runtime: 'automatic', ++ }, ++ }, ++ }, ++ }, ++ ], ++ }, +}); +``` + +然后在 `package.json` 中加入 `test` 脚本: + +```diff title="package.json" +{ + "scripts": { ++ "test": "jest" + } +} +``` + +配置完成后,就可以开始编写单元测试了。 + +### 非 UI 测试 + +假设现在要测试 `add` 函数如下: + +```ts title="src/utils/add.ts" +export default function add(a, b) { + return a + b; +} +``` + +新建一个测试用例: + +```ts title="tests/add.spec.ts" +import add from '../src/add'; + +test('add function', () => { + expect(add(1, 2)).toBe(3); +}); +``` + +这时,运行 `npm run test` 查看测试结果了。 + +### UI 测试 + +组件 UI 测试推荐使用 [@testing-library/react](https://www.npmjs.com/package/@testing-library/react) 和 [@testing-library/jest-dom](https://www.npmjs.com/package/@testing-library/jest-dom)。 + +首先安装依赖: + +```bash +$ npm i @testing-library/react jest-environment-jsdom @testing-library/jest-dom -D +``` + +然后在项目根目录下新建 `jest-setup.ts` 并写入以下内容,以扩展匹配器(matchers): +```ts title="jest-setup.ts" +import '@testing-library/jest-dom'; +``` + +最后在 `jest.config.mjs` 中加入以下内容: +```diff title="jest.config.mjs" +import { defineJestConfig } from '@ice/app'; + +export default defineJestConfig({ ++ setupFilesAfterEnv: ['<rootDir>/jest-setup.ts'], ++ testEnvironment: 'jest-environment-jsdom', +}); +``` + +假设现在要测试一个 Header 组件: +```tsx title="src/components/Header.tsx" +export default function Header() { + return ( + <h2 data-testid="title">Jest Test</h2> + ); +} +``` + +编写组件的测试用例: +```tsx title="tests/Header.spec.tsx" +import { render, screen } from '@testing-library/react'; +import Header from '../src/components/Header'; + +test('test Header component', () => { + render(<Header />); + expect(screen.getByTestId('title')).toHaveTextContent('Jest Test'); +}); +``` + +最后,运行 `npm run test` 就可以查看测试结果了。 + +## Vitest + +### 依赖安装 + +```bash +$ npm i vitest -D +``` + +### 配置 + +首先需要在项目的根目录下新建 vitest.config.mjs 文件,并加入以下内容: + +```js title="vitest.config.mjs" +import { defineVitestConfig } from '@ice/app'; + +export default defineVitestConfig({}); +``` +`defineVitestConfig` 方法返回的是 icejs 默认配置好的 vitest 配置,支持传入自定义的 [vitest 配置](https://vitest.dev/config/)。 + +defineVitestConfig 入参支持三种写法: + +- `vitest.UserConfig` +- `Promise<vitest.UserConfig>` +- `(env) => Promise<vitest.UserConfig>` + +以修改 `include` 参数为例: + +```diff title="vitest.config.mjs" +import { defineVitestConfig } from '@ice/app'; + +export default defineVitestConfig({ ++ test: { ++ include: ['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'] ++ } +}); +``` +然后在 `package.json` 中加入 `test` 脚本: + +```diff title="package.json" +{ + "scripts": { ++ "test": "vitest" + } +} +``` +### 非 UI 测试 + +同样测试 [Jest 非 UI 测试章节](#非-ui-测试) 中的 `Header` 组件,编写以下的测试用例: + +```ts title="tests/add.spec.ts" +import { test, expect } from 'vitest'; +import add from '../src/add'; + +test('add', () => { + expect(add(1, 2)).toBe(3); +}); +``` + +现在可以运行 `npm run test` 查看测试结果。 + +### UI 测试 + +首先安装依赖: + +```bash +$ npm i @testing-library/react jsdom @testing-library/jest-dom @vitejs/plugin-react@1.3.2 -D +``` + +然后在项目根目录下新建 `vitest-setup.js` 并写入以下内容,以扩展匹配器(matchers): + +```ts title="vitest-setup.js" +import matchers from '@testing-library/jest-dom/matchers'; +import { expect } from 'vitest'; + +expect.extend(matchers); +``` + +最后在 `vitest.config.mjs` 中加入以下内容: + +```diff title="vitest.config.mjs" +import { defineVitestConfig } from '@ice/app'; ++ import react from '@vitejs/plugin-react'; + +export default defineVitestConfig({ ++ test: { ++ environment: 'jsdom', ++ setupFiles: ['./vitest-setup.js'], ++ plugins: [react()], // 支持解析 JSX 语法 ++ }, +}); +``` + +假设现在测试一个 Header 组件: + +```tsx title="src/components/Header.tsx" +export default function Header() { + return ( + <h2 data-testid="title">Vitest Test</h2> + ); +} +``` + +编写组件的测试用例: + +```tsx title="tests/Header.spec.tsx" +import { test, expect } from 'vitest'; +import { render, screen } from '@testing-library/react'; +import Header from '../src/components/Header'; + +test('test Header component', () => { + render(<Header />); + expect(screen.getByTestId('title')).toHaveTextContent('Vitest Test'); +}); +``` + +最后,运行 `npm run test` 就可以查看测试结果了。 \ No newline at end of file diff --git a/website/docs/guide/plugins/css-assets-local.md b/website/docs/guide/plugins/css-assets-local.md new file mode 100644 index 000000000..9d0f45052 --- /dev/null +++ b/website/docs/guide/plugins/css-assets-local.md @@ -0,0 +1,50 @@ +--- +title: CSS 资源本地化 +order: 2 +--- + +组件代码里有可能会依赖一些远程 CDN 的字体文件等,某些情况下网站运行时可能访问不了。该插件提供在构建部署时将 CSS 中的网络资源本地化能力,例如字体文件等。 + +## 开启插件 + +安装插件: + +```bash +$ npm i -D @ice/plugin-css-assets-local +``` + +在 `ice.config.mts` 中添加插件: + +```ts title="ice.config.mts" +import { defineConfig } from '@ice/app'; +import cssAssetsLocal from '@ice/plugin-css-assets-local'; + +export default defineConfig({ + plugins: [ + cssAssetsLocal(), + ], +}); +``` + +## 配置 + +### `outputPath` + +提取后的静态文件目录前缀 + +- 类型: `string` +- 默认值: `assets` + +### `relativeCssPath` + +提取的文件后相对于 CSS 的路径 + +- 类型: `string` +- 默认值: `../` + +### `enableInDev` + +本地调试时是否启用插件 + +- 类型: `boolean` +- 默认值: `false` diff --git a/website/plugins/redirect.js b/website/plugins/redirect.js index 02aa74625..2c0bf26c2 100644 --- a/website/plugins/redirect.js +++ b/website/plugins/redirect.js @@ -1,7 +1,9 @@ -module.exports = function (context, options) { +const path = require('path'); + +module.exports = function (config) { return { name: 'docusaurus-redirect-plugin', - async contentLoaded({ content, actions }) { + async contentLoaded({ actions }) { const { createData, addRoute } = actions; const routes = [ @@ -53,7 +55,7 @@ module.exports = function (context, options) { }); addRoute({ - path: '/component', + path: path.join(config.baseUrl, '/component'), component: '@site/src/components/Redirect', modules: { // propName -> JSON file path @@ -62,7 +64,7 @@ module.exports = function (context, options) { }); addRoute({ - path: '/docs/guide/advance', + path: path.join(config.baseUrl, '/docs/guide/advance'), component: '@site/src/components/Redirect', modules: { // propName -> JSON file path @@ -71,7 +73,7 @@ module.exports = function (context, options) { }); addRoute({ - path: '/docs/materials', + path: path.join(config.baseUrl, '/docs/materials'), component: '@site/src/components/Redirect', modules: { // propName -> JSON file path @@ -80,7 +82,7 @@ module.exports = function (context, options) { }); addRoute({ - path: '/docs/icestark', + path: path.join(config.baseUrl, '/docs/icestark'), component: '@site/src/components/Redirect', modules: { // propName -> JSON file path @@ -89,4 +91,4 @@ module.exports = function (context, options) { }); }, }; -}; \ No newline at end of file +}; diff --git a/website/src/components/Button/index.jsx b/website/src/components/Button/index.jsx index aa55bea8e..05d1560bc 100644 --- a/website/src/components/Button/index.jsx +++ b/website/src/components/Button/index.jsx @@ -1,10 +1,14 @@ import React from 'react'; import clsx from 'clsx'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import { join } from '../../utils/path'; import styles from './button.module.css'; function Button({ primary = true, url, children }) { + const context = useDocusaurusContext(); + const source = join(context.siteConfig.baseUrl, url); return ( - <a href={url} className={clsx(styles.button, primary && styles.primary)}> + <a href={source} className={clsx(styles.button, primary && styles.primary)}> {children} </a> ); diff --git a/website/src/components/Redirect/index.jsx b/website/src/components/Redirect/index.jsx index 29873f6ca..6df55768d 100644 --- a/website/src/components/Redirect/index.jsx +++ b/website/src/components/Redirect/index.jsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import { useEffect } from 'react'; export default function Redirect(props) { const { location, history, redirectConfig = [] } = props; @@ -28,7 +28,7 @@ export default function Redirect(props) { console.log('未知路由', pathname); } } - }, []); + }, [location, history, pathname, redirectConfig]); return null; } diff --git a/website/src/components/Support/index.jsx b/website/src/components/Support/index.jsx index 1a33e631b..b5fdf588e 100644 --- a/website/src/components/Support/index.jsx +++ b/website/src/components/Support/index.jsx @@ -1,8 +1,11 @@ import React from 'react'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import { join } from '../../utils/path'; import styles from './support.module.css'; -function Support({ list }) { +export default function Support({ list }) { const availablePlatforms = ['webpack', 'vite']; + const context = useDocusaurusContext(); return ( <span className={styles.container}> {availablePlatforms.map((supportPlatform) => { @@ -11,12 +14,10 @@ function Support({ list }) { title={supportPlatform} className={styles[supportPlatform]} key={supportPlatform} - src={`/img/svg/${list.includes(supportPlatform) ? supportPlatform : `${supportPlatform}-gray`}.svg`} + src={join(context.siteConfig.baseUrl, `/img/svg/${list.includes(supportPlatform) ? supportPlatform : `${supportPlatform}-gray`}.svg`)} /> ); })} </span> ); } - -export default Support; diff --git a/website/src/theme/Root.js b/website/src/theme/Root.js index d6fef1a6c..7e8984b44 100644 --- a/website/src/theme/Root.js +++ b/website/src/theme/Root.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; import clsx from 'clsx'; import storage from '../utils/storage'; import { isIntranet } from '../utils/internal'; diff --git a/website/src/utils/path.js b/website/src/utils/path.js new file mode 100644 index 000000000..d16b15ec4 --- /dev/null +++ b/website/src/utils/path.js @@ -0,0 +1,7 @@ +// Similar with nodejs's path.join, not a full version support. +const separator = '/'; + +export function join(...args) { + const replace = new RegExp(`${separator}{1,}`, 'g'); + return args.join(separator).replace(replace, separator); +}