diff --git a/package.json b/package.json
index 33e106f63..b532bfedf 100644
--- a/package.json
+++ b/package.json
@@ -65,7 +65,9 @@
"auto-changelog": "^2.4.0",
"axios": "^1.6.8",
"commander": "^9.5.0",
+ "eslint": "^9.10.0",
"eslint-plugin-jest-dom": "^5.4.0",
+ "eslint-plugin-react": "^7.33.0",
"eslint-plugin-testing-library": "^5.11.1",
"globals": "^15.9.0",
"husky": "^9.0.11",
@@ -79,6 +81,7 @@
"react-dom": "^18.3.1",
"tsx": "^4.15.2",
"typescript": "5.4.5",
+ "typescript-eslint": "^8.4.0",
"umi": "^4.3.3",
"vitest": "^1.6.0"
},
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/.npmignore b/packages/plugins/@tachybase/plugin-wechat-auth/.npmignore
new file mode 100644
index 000000000..65f5e8779
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/.npmignore
@@ -0,0 +1,2 @@
+/node_modules
+/src
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/README.md b/packages/plugins/@tachybase/plugin-wechat-auth/README.md
new file mode 100644
index 000000000..d9fde6675
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/README.md
@@ -0,0 +1,14 @@
+# wechat-auth
+
+English | [中文](./README.zh-CN.md)
+
+## Install
+
+```
+pnpm pm add @tachybase/plugin-wechat-auth
+pnpm pm enable @tachybase/plugin-wechat-auth
+```
+
+## Usage
+
+TODO
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/client.d.ts b/packages/plugins/@tachybase/plugin-wechat-auth/client.d.ts
new file mode 100644
index 000000000..6c459cbac
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/client.d.ts
@@ -0,0 +1,2 @@
+export * from './dist/client';
+export { default } from './dist/client';
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/client.js b/packages/plugins/@tachybase/plugin-wechat-auth/client.js
new file mode 100644
index 000000000..b6e3be70e
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/client.js
@@ -0,0 +1 @@
+module.exports = require('./dist/client/index.js');
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/package.json b/packages/plugins/@tachybase/plugin-wechat-auth/package.json
new file mode 100644
index 000000000..84bb36a99
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "@tachybase/plugin-wechat-auth",
+ "displayName": "Auth: WeChat",
+ "version": "0.21.88",
+ "description": "WeChat authentication.",
+ "keywords": [
+ "Authentication"
+ ],
+ "license": "Apache-2.0",
+ "main": "dist/server/index.js",
+ "devDependencies": {
+ "@ant-design/icons": "~5.3.7",
+ "antd": "5.19.4",
+ "react-i18next": "^15.0.1",
+ "react-router-dom": "^6.25.1"
+ },
+ "peerDependencies": {
+ "@tachybase/actions": "workspace:*",
+ "@tachybase/auth": "workspace:*",
+ "@tachybase/client": "workspace:*",
+ "@tachybase/database": "workspace:*",
+ "@tachybase/plugin-auth": "workspace:*",
+ "@tachybase/schema": "workspace:*",
+ "@tachybase/server": "workspace:*"
+ },
+ "description.zh-CN": "通过微信扫码认证身份。",
+ "displayName.zh-CN": "认证:微信"
+}
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/server.d.ts b/packages/plugins/@tachybase/plugin-wechat-auth/server.d.ts
new file mode 100644
index 000000000..c41081ddc
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/server.d.ts
@@ -0,0 +1,2 @@
+export * from './dist/server';
+export { default } from './dist/server';
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/server.js b/packages/plugins/@tachybase/plugin-wechat-auth/server.js
new file mode 100644
index 000000000..972842039
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/server.js
@@ -0,0 +1 @@
+module.exports = require('./dist/server/index.js');
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/client/admin-settings-form.tsx b/packages/plugins/@tachybase/plugin-wechat-auth/src/client/admin-settings-form.tsx
new file mode 100644
index 000000000..efa8461fb
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/client/admin-settings-form.tsx
@@ -0,0 +1,73 @@
+import React from 'react';
+import { SchemaComponent, useApp } from '@tachybase/client';
+
+import { CopyOutlined } from '@ant-design/icons';
+import { Input, message, Typography } from 'antd';
+
+import { useTranslation } from '../locale';
+
+export const AdminSettingsForm = () => {
+ const { t } = useTranslation();
+ const app = useApp();
+ const redirectUrl = React.useMemo(() => app.getApiUrl('wechatAuth:redirect'), [app]);
+ const onCopy = (text) => {
+ navigator.clipboard
+ .writeText(text)
+ .then(() => {
+ message.success(t('Copied'));
+ })
+ .catch(() => {
+ message.error(t('Failed to copy'));
+ });
+ };
+ return (
+
+
+
+
+ {t('Redirect URL')}
+ :
+
+ onCopy(redirectUrl)} />} />
+
+
+ );
+};
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/client/index.tsx b/packages/plugins/@tachybase/plugin-wechat-auth/src/client/index.tsx
new file mode 100644
index 000000000..6497621b8
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/client/index.tsx
@@ -0,0 +1,20 @@
+import { Plugin } from '@tachybase/client';
+import AuthPlugin from '@tachybase/plugin-auth/client';
+
+import { authType } from '../constants';
+import { AdminSettingsForm } from './admin-settings-form';
+import { SignInForm } from './sign-in-form';
+
+export class WeChatAuthPlugin extends Plugin {
+ async load() {
+ const auth = this.app.pm.get(AuthPlugin);
+ auth.registerType(authType, {
+ components: {
+ SignInForm,
+ AdminSettingsForm,
+ },
+ });
+ }
+}
+
+export default WeChatAuthPlugin;
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/client/sign-in-form.tsx b/packages/plugins/@tachybase/plugin-wechat-auth/src/client/sign-in-form.tsx
new file mode 100644
index 000000000..ced73e9bf
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/client/sign-in-form.tsx
@@ -0,0 +1,106 @@
+import React, { useEffect, useState } from 'react';
+import { SchemaComponent, useAPIClient, useGlobalTheme } from '@tachybase/client';
+import { Authenticator } from '@tachybase/plugin-auth/client';
+import { ISchema } from '@tachybase/schema';
+
+import { useLocation } from 'react-router-dom';
+
+import { useTranslation } from '../locale';
+import WeChatQrComponent from './wechat-qr-component';
+
+const qrForm: ISchema = {
+ type: 'object',
+ name: 'qrForm',
+ 'x-component': 'Form',
+ properties: {
+ qrCode: {
+ type: 'string',
+ 'x-component': 'WeChatQrComponent',
+ 'x-component-props': {
+ style: { width: '100%' },
+ value: { config: '{{ wcQrCfg }}' },
+ },
+ 'x-decorator': 'FormItem',
+ },
+ tip: {
+ type: 'void',
+ 'x-component': 'div',
+ 'x-content': '{{t("User will be registered automatically if not exists.")}}',
+ 'x-component-props': { style: { color: '#ccc' } },
+ 'x-visible': '{{ autoSignUp }}',
+ },
+ },
+};
+
+export const SignInForm = (props: { authenticator: Authenticator }) => {
+ const authenticator = props.authenticator;
+ const { name, options } = authenticator;
+ const autoSignUp = !!options?.autoSignUp;
+ const { t } = useTranslation();
+ const api = useAPIClient();
+ const location = useLocation();
+ const urlSearchParams = new URLSearchParams(location.search);
+ const redirect = urlSearchParams.get('redirect');
+ const { theme } = useGlobalTheme();
+ const isDark = theme.name.toLowerCase().includes('dark');
+ const wcQrStyle = isDark ? 'white' : 'black';
+
+ const [wcQrCfg, setWcQrCfg] = useState(null);
+
+ useEffect(() => {
+ const fetchAuthConfig = async () => {
+ try {
+ const result = await api.request({
+ method: 'post',
+ url: 'wechatAuth:getAuthCfg',
+ headers: { 'X-Authenticator': authenticator.name },
+ data: { redirect },
+ });
+ const cfg = result?.data?.data;
+
+ const wcQrCfg = {
+ self_redirect: false,
+ id: 'wechat_qr_container',
+ appid: cfg.appId,
+ scope: cfg.scope,
+ redirect_uri: cfg.redirectUrl,
+ state: cfg.state,
+ style: wcQrStyle,
+ stylelite: 1,
+ fast_login: 1,
+ href: '',
+ };
+
+ setWcQrCfg(wcQrCfg);
+
+ const script = document.createElement('script');
+ script.async = true;
+ script.innerHTML = `
+ (function() {
+ var wxScript = document.createElement('script');
+ wxScript.src = '//res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js';
+ wxScript.async = true;
+ wxScript.onload = function() {
+ new WxLogin(${JSON.stringify(wcQrCfg)});
+ };
+ document.body.appendChild(wxScript);
+ })();
+ `;
+ document.body.appendChild(script);
+
+ return () => {
+ document.body.removeChild(script);
+ };
+ } catch (error) {
+ console.error('Error fetching auth config:', error);
+ }
+ };
+
+ fetchAuthConfig();
+ }, [api, authenticator.name, redirect, wcQrStyle]);
+
+ if (!wcQrCfg) {
+ return Loading...
;
+ }
+ return ;
+};
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/client/wechat-qr-component.tsx b/packages/plugins/@tachybase/plugin-wechat-auth/src/client/wechat-qr-component.tsx
new file mode 100644
index 000000000..f89f01282
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/client/wechat-qr-component.tsx
@@ -0,0 +1,16 @@
+import React from 'react';
+import { css } from '@tachybase/client';
+
+export default function WeChatQrComponent() {
+ return (
+
+ );
+}
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/constants.ts b/packages/plugins/@tachybase/plugin-wechat-auth/src/constants.ts
new file mode 100644
index 000000000..b9b89c225
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/constants.ts
@@ -0,0 +1,7 @@
+// @ts-ignore
+import { name } from '../package.json';
+
+export const authType = 'WeChat';
+export const namespace = name;
+export const weChatApiOauthBaseUrl = 'https://api.weixin.qq.com/sns/oauth2/';
+export const weChatApiOauthScope = 'snsapi_login';
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/index.ts b/packages/plugins/@tachybase/plugin-wechat-auth/src/index.ts
new file mode 100644
index 000000000..7e74612df
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/index.ts
@@ -0,0 +1,2 @@
+export * from './server';
+export { default } from './server';
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/locale/en-US.ts b/packages/plugins/@tachybase/plugin-wechat-auth/src/locale/en-US.ts
new file mode 100644
index 000000000..454450330
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/locale/en-US.ts
@@ -0,0 +1,9 @@
+export default {
+ "Sign in via WeChat": "Sign in via WeChat",
+ "Redirect URL": "Redirect URL",
+ "Sign up automatically when the user does not exist": "Sign up automatically when the user does not exist",
+ "User not found": "User not found",
+ "Failed to get accessToken": "Failed to get accessToken",
+ "Copied": "Copied",
+ "Failed to copy": "Failed to copy"
+}
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/locale/index.ts b/packages/plugins/@tachybase/plugin-wechat-auth/src/locale/index.ts
new file mode 100644
index 000000000..5d46f3d45
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/locale/index.ts
@@ -0,0 +1,7 @@
+import { useTranslation as t } from 'react-i18next';
+import { namespace } from '../constants';
+
+export function useTranslation() {
+ return t(namespace);
+}
+
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/locale/zh-CN.ts b/packages/plugins/@tachybase/plugin-wechat-auth/src/locale/zh-CN.ts
new file mode 100644
index 000000000..9ac5273d3
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/locale/zh-CN.ts
@@ -0,0 +1,9 @@
+export default {
+ "Sign in via WeChat": "微信登录",
+ "Redirect URL": "回调地址",
+ "Sign up automatically when the user does not exist": "用户不存在时自动注册",
+ "User not found": "用户不存在",
+ "Failed to get accessToken": "未获取到accessToken",
+ "Copied": "已复制",
+ "Failed to copy": "复制失败"
+}
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/server/actions/get-auth-cfg.ts b/packages/plugins/@tachybase/plugin-wechat-auth/src/server/actions/get-auth-cfg.ts
new file mode 100644
index 000000000..3bf8ed80e
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/server/actions/get-auth-cfg.ts
@@ -0,0 +1,7 @@
+import { Context, Next } from '@tachybase/actions';
+
+export const getAuthCfg = async (ctx: Context, next: Next) => {
+ const { redirect } = ctx.action.params.values;
+ ctx.body = await ctx.auth.getAuthCfg(redirect);
+ await next();
+};
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/server/actions/index.ts b/packages/plugins/@tachybase/plugin-wechat-auth/src/server/actions/index.ts
new file mode 100644
index 000000000..4fe577afd
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/server/actions/index.ts
@@ -0,0 +1,2 @@
+export { getAuthCfg } from './get-auth-cfg';
+export { redirect } from './redirect';
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/server/actions/redirect.ts b/packages/plugins/@tachybase/plugin-wechat-auth/src/server/actions/redirect.ts
new file mode 100644
index 000000000..9f49bda46
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/server/actions/redirect.ts
@@ -0,0 +1,32 @@
+import { Context, Next } from '@tachybase/actions';
+import { AppSupervisor } from '@tachybase/server';
+
+export const redirect = async (ctx: Context, next: Next) => {
+ let { state } = ctx.request.query;
+
+ state = Array.isArray(state) ? state[0] : state;
+ const search = new URLSearchParams(state);
+
+ const authenticator = search.get('name');
+ const appName = search.get('app');
+ const redirect = search.get('redirect') || '/admin';
+ let prefix = process.env.APP_PUBLIC_PATH || '';
+ if (appName && appName !== 'main') {
+ const appSupervisor = AppSupervisor.getInstance();
+ if (appSupervisor?.runningMode !== 'single') {
+ prefix += `apps/${appName}`;
+ }
+ }
+ const auth = await ctx.app.authManager.get(authenticator, ctx);
+ if (prefix.endsWith('/')) {
+ prefix = prefix.slice(0, -1);
+ }
+ try {
+ const { token } = await auth.signIn();
+ ctx.redirect(`${prefix}${redirect}?authenticator=${authenticator}&token=${token}`);
+ } catch (error) {
+ ctx.logger.error('WeChat auth error', { error });
+ ctx.redirect(`${prefix}/signin?redirect=${redirect}&authenticator=${authenticator}&error=${error.message}`);
+ }
+ await next();
+};
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/server/index.ts b/packages/plugins/@tachybase/plugin-wechat-auth/src/server/index.ts
new file mode 100644
index 000000000..b68aea57f
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/server/index.ts
@@ -0,0 +1 @@
+export { default } from './plugin';
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/server/plugin.ts b/packages/plugins/@tachybase/plugin-wechat-auth/src/server/plugin.ts
new file mode 100644
index 000000000..cf16c7119
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/server/plugin.ts
@@ -0,0 +1,53 @@
+import { Gateway, InstallOptions, Plugin } from '@tachybase/server';
+
+import { authType } from '../constants';
+import { getAuthCfg, redirect } from './actions';
+import { WeChatAuth } from './wechat-auth';
+
+export class WeChatAuthPlugin extends Plugin {
+ afterAdd() {}
+
+ beforeLoad() {}
+
+ async load() {
+ this.app.authManager.registerTypes(authType, {
+ auth: WeChatAuth,
+ });
+
+ this.app.resourcer.define({
+ name: 'wechatAuth',
+ actions: {
+ getAuthCfg,
+ redirect,
+ },
+ });
+
+ this.app.acl.allow('wechatAuth', '*', 'public');
+
+ Gateway.getInstance().addAppSelectorMiddleware(async (ctx, next) => {
+ const { req } = ctx;
+ const url = new URL(req.url, `http://${req.headers.host}`);
+ const params = url.searchParams;
+ const state = params.get('state');
+ if (!state) {
+ return next();
+ }
+ const search = new URLSearchParams(state);
+ const appName = search.get('app');
+ if (appName) {
+ ctx.resolvedAppName = appName;
+ }
+ await next();
+ });
+ }
+
+ async install(options?: InstallOptions) {}
+
+ async afterEnable() {}
+
+ async afterDisable() {}
+
+ async remove() {}
+}
+
+export default WeChatAuthPlugin;
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/server/wechat-auth.ts b/packages/plugins/@tachybase/plugin-wechat-auth/src/server/wechat-auth.ts
new file mode 100644
index 000000000..6b78e578f
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/server/wechat-auth.ts
@@ -0,0 +1,71 @@
+import { AuthConfig, BaseAuth } from '@tachybase/auth';
+
+import { namespace, weChatApiOauthBaseUrl, weChatApiOauthScope } from '../constants';
+
+export { Model } from '@tachybase/database';
+
+export class WeChatAuth extends BaseAuth {
+ constructor(config: AuthConfig) {
+ const { ctx } = config;
+ super({
+ ...config,
+ userCollection: ctx.db.getCollection('users'),
+ });
+ }
+
+ async validate() {
+ const ctx = this.ctx;
+ let { code } = ctx.request.query || {};
+ code = Array.isArray(code) ? code[0] : code;
+
+ if (!code) {
+ ctx.logger.error('Failed to get code');
+ ctx.throw(401, ctx.t('Unauthorized', { ns: namespace }));
+ }
+
+ try {
+ const getAccessTokenRsp = await fetch(
+ `${weChatApiOauthBaseUrl}access_token?appid=${this.options?.wechatAuth?.AppID}&secret=${this.options?.wechatAuth?.AppSecret}&code=${code}&grant_type=authorization_code`,
+ );
+ const getAccessTokenRspJson = await getAccessTokenRsp.json();
+ if (getAccessTokenRspJson.errcode) {
+ ctx.logger.error(`Failed to get user accessToken: ${getAccessTokenRspJson.errmsg}`);
+ ctx.throw(401, ctx.t('Failed to get accessToken', { ns: namespace }));
+ }
+ const { access_token, unionid } = getAccessTokenRspJson;
+ const authenticator = this.authenticator;
+ const user = await authenticator.findUser(unionid);
+ if (user) {
+ return user;
+ }
+ // Create new user
+ const { autoSignUp } = this.options?.public || {};
+ if (!autoSignUp) {
+ ctx.logger.error(`User not found: ${unionid}`);
+ ctx.throw(401, ctx.t('User not found', { ns: namespace }));
+ }
+ return await authenticator.newUser(unionid, {
+ unionid,
+ });
+ } catch (err) {
+ ctx.logger.error(`Failed in validate: ${err}`);
+ ctx.throw(401, ctx.t('Unauthorized', { ns: namespace }));
+ }
+ }
+
+ async getAuthCfg(redirect) {
+ const appID = this.options?.wechatAuth?.AppID;
+ const app = this.ctx.app.name;
+ const redirectUrl = encodeURIComponent(`${this.ctx.host}${process.env.API_BASE_PATH}wechatAuth:redirect`);
+ // TODO: 如果后续有登录后绑定的场景,服务端需要校验 state
+ const state = encodeURIComponent(
+ encodeURIComponent(`redirect=${redirect}&app=${app}&name=${this.ctx.headers['x-authenticator']}`),
+ );
+ return {
+ appId: appID,
+ scope: weChatApiOauthScope,
+ redirectUrl,
+ state,
+ };
+ }
+}
diff --git a/packages/plugins/@tachybase/plugin-wechat-auth/src/swagger/index.ts b/packages/plugins/@tachybase/plugin-wechat-auth/src/swagger/index.ts
new file mode 100644
index 000000000..40b6c3d80
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-wechat-auth/src/swagger/index.ts
@@ -0,0 +1,157 @@
+const user = {
+ type: 'object',
+ description: '用户',
+ properties: {
+ id: {
+ type: 'integer',
+ description: 'ID',
+ },
+ nickname: {
+ type: 'string',
+ description: '昵称',
+ },
+ email: {
+ type: 'string',
+ description: '邮箱',
+ },
+ phone: {
+ type: 'string',
+ description: '手机号',
+ },
+ appLang: {
+ type: 'string',
+ description: '用户使用语言',
+ },
+ systemSettings: {
+ type: 'object',
+ description: '系统设置',
+ properties: {
+ theme: {
+ type: 'string',
+ description: '用户使用主题',
+ },
+ },
+ },
+ createdAt: {
+ type: 'string',
+ format: 'date-time',
+ description: '创建时间',
+ },
+ updatedAt: {
+ type: 'string',
+ format: 'date-time',
+ description: '更新时间',
+ },
+ createdById: {
+ type: 'integer',
+ description: '创建人',
+ },
+ updatedById: {
+ type: 'integer',
+ description: '更新人',
+ },
+ },
+};
+
+export default {
+ info: {
+ title: 'TachyBase API - WeChat Auth plugin',
+ },
+ paths: {
+ '/wechatAuth:getAuthCfg': {
+ security: [],
+ get: {
+ description: 'Get WeChat authorization configuration',
+ tags: ['WeChat'],
+ parameters: [
+ {
+ name: 'X-Authenticator',
+ description: '登录方式标识',
+ in: 'header',
+ schema: {
+ type: 'string',
+ },
+ required: true,
+ },
+ ],
+ responses: {
+ 200: {
+ description: 'ok',
+ content: {
+ 'application/json': {
+ schema: {
+ type: 'string',
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ '/wechatAuth:signIn': {
+ security: [],
+ post: {
+ description: 'WeChat sign in',
+ tags: ['WeChat'],
+ parameters: [
+ {
+ name: 'X-Authenticator',
+ description: '登录方式标识',
+ in: 'header',
+ schema: {
+ type: 'string',
+ },
+ required: true,
+ },
+ {
+ name: 'tachybase_wechat_auth',
+ description: 'state校验值',
+ in: 'cookie',
+ schema: {
+ type: 'string',
+ },
+ required: true,
+ },
+ ],
+ requestBody: {
+ content: {
+ 'application/json': {
+ schema: {
+ type: 'object',
+ properties: {
+ code: {
+ type: 'string',
+ },
+ state: {
+ type: 'string',
+ },
+ iss: {
+ type: 'string',
+ },
+ },
+ },
+ },
+ },
+ },
+ responses: {
+ 200: {
+ description: 'ok',
+ content: {
+ 'application/json': {
+ schema: {
+ type: 'object',
+ properties: {
+ token: {
+ type: 'string',
+ },
+ user,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+};
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 069550827..06acf596f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -80,12 +80,18 @@ importers:
commander:
specifier: ^9.5.0
version: 9.5.0
+ eslint:
+ specifier: ^9.10.0
+ version: 9.10.0
eslint-plugin-jest-dom:
specifier: ^5.4.0
- version: 5.4.0(@testing-library/dom@10.4.0)(eslint@9.9.0)
+ version: 5.4.0(@testing-library/dom@10.4.0)(eslint@9.10.0)
+ eslint-plugin-react:
+ specifier: ^7.33.0
+ version: 7.33.2(eslint@9.10.0)
eslint-plugin-testing-library:
specifier: ^5.11.1
- version: 5.11.1(eslint@9.9.0)(typescript@5.4.5)
+ version: 5.11.1(eslint@9.10.0)(typescript@5.4.5)
globals:
specifier: ^15.9.0
version: 15.9.0
@@ -122,9 +128,12 @@ importers:
typescript:
specifier: 5.4.5
version: 5.4.5
+ typescript-eslint:
+ specifier: ^8.4.0
+ version: 8.4.0(eslint@9.10.0)(typescript@5.4.5)
umi:
specifier: ^4.3.3
- version: 4.3.3(@babel/core@7.22.10)(@types/node@20.14.2)(@types/react@18.3.3)(eslint@9.9.0)(lightningcss@1.26.0)(prettier@3.2.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.4)(sass@1.77.8)(stylelint@16.8.2(typescript@5.4.5))(terser@5.31.6)(type-fest@4.25.0)(typescript@5.4.5)(webpack@5.93.0)
+ version: 4.3.3(@babel/core@7.22.10)(@types/node@20.14.2)(@types/react@18.3.3)(eslint@9.10.0)(lightningcss@1.26.0)(prettier@3.2.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.4)(sass@1.77.8)(stylelint@16.8.2(typescript@5.4.5))(terser@5.31.6)(type-fest@4.25.0)(typescript@5.4.5)(webpack@5.93.0)
vitest:
specifier: ^1.6.0
version: 1.6.0(@types/node@20.14.2)(jsdom@24.1.1(canvas@2.11.2(encoding@0.1.13)))(less@4.1.3)(lightningcss@1.26.0)(sass@1.77.8)(terser@5.31.6)
@@ -4081,6 +4090,43 @@ importers:
specifier: ^4.0.525
version: 4.0.759(encoding@0.1.13)
+ packages/plugins/@tachybase/plugin-wechat-auth:
+ dependencies:
+ '@tachybase/actions':
+ specifier: workspace:*
+ version: link:../../../core/actions
+ '@tachybase/auth':
+ specifier: workspace:*
+ version: link:../../../core/auth
+ '@tachybase/client':
+ specifier: workspace:*
+ version: link:../../../core/client
+ '@tachybase/database':
+ specifier: workspace:*
+ version: link:../../../core/database
+ '@tachybase/plugin-auth':
+ specifier: workspace:*
+ version: link:../plugin-auth
+ '@tachybase/schema':
+ specifier: workspace:*
+ version: link:../../../core/schema
+ '@tachybase/server':
+ specifier: workspace:*
+ version: link:../../../core/server
+ devDependencies:
+ '@ant-design/icons':
+ specifier: ~5.3.7
+ version: 5.3.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ antd:
+ specifier: 5.19.4
+ version: 5.19.4(date-fns@3.6.0)(luxon@3.5.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react-i18next:
+ specifier: ^15.0.1
+ version: 15.0.1(i18next@23.13.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react-router-dom:
+ specifier: ^6.25.1
+ version: 6.25.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+
packages/plugins/@tachybase/plugin-wechat-official-account:
dependencies:
'@ant-design/icons':
@@ -7220,8 +7266,8 @@ packages:
resolution: {integrity: sha512-lpHyRyplhGPL5mGEh6M9O5nnKk0Gz4bFI+Zu6tKlPpDUN7XshWvH9C/px4UVm87IAANE0W81CEsNGbS1KlzXpA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/config-array@0.17.1':
- resolution: {integrity: sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==}
+ '@eslint/config-array@0.18.0':
+ resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/eslintrc@2.1.4':
@@ -7240,14 +7286,14 @@ packages:
resolution: {integrity: sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/js@9.9.0':
- resolution: {integrity: sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==}
- engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
-
'@eslint/object-schema@2.1.4':
resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@eslint/plugin-kit@0.1.0':
+ resolution: {integrity: sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
'@ethereumjs/rlp@4.0.1':
resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==}
engines: {node: '>=14'}
@@ -9671,6 +9717,17 @@ packages:
typescript:
optional: true
+ '@typescript-eslint/eslint-plugin@8.4.0':
+ resolution: {integrity: sha512-rg8LGdv7ri3oAlenMACk9e+AR4wUV0yrrG+XKsGKOK0EVgeEDqurkXMPILG2836fW4ibokTB5v4b6Z9+GYQDEw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
'@typescript-eslint/parser@5.62.0':
resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -9691,6 +9748,16 @@ packages:
typescript:
optional: true
+ '@typescript-eslint/parser@8.4.0':
+ resolution: {integrity: sha512-NHgWmKSgJk5K9N16GIhQ4jSobBoJwrmURaLErad0qlLjrpP5bECYg+wxVTGlGZmJbU03jj/dfnb6V9bw+5icsA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
'@typescript-eslint/scope-manager@5.62.0':
resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -9699,6 +9766,10 @@ packages:
resolution: {integrity: sha512-VT7CFWHbZipPncAZtuALr9y3EuzY1b1t1AEkIq2bTXUPKw+pHoXflGNG5L+Gv6nKul1cz1VH8fz16IThIU0tdg==}
engines: {node: ^16.0.0 || >=18.0.0}
+ '@typescript-eslint/scope-manager@8.4.0':
+ resolution: {integrity: sha512-n2jFxLeY0JmKfUqy3P70rs6vdoPjHK8P/w+zJcV3fk0b0BwRXC/zxRTEnAsgYT7MwdQDt/ZEbtdzdVC+hcpF0A==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
'@typescript-eslint/type-utils@5.62.0':
resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -9719,6 +9790,15 @@ packages:
typescript:
optional: true
+ '@typescript-eslint/type-utils@8.4.0':
+ resolution: {integrity: sha512-pu2PAmNrl9KX6TtirVOrbLPLwDmASpZhK/XU7WvoKoCUkdtq9zF7qQ7gna0GBZFN0hci0vHaSusiL2WpsQk37A==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
'@typescript-eslint/types@5.62.0':
resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -9727,6 +9807,10 @@ packages:
resolution: {integrity: sha512-uty9H2K4Xs8E47z3SnXEPRNDfsis8JO27amp2GNCnzGETEW3yTqEIVg5+AI7U276oGF/tw6ZA+UesxeQ104ceA==}
engines: {node: ^16.0.0 || >=18.0.0}
+ '@typescript-eslint/types@8.4.0':
+ resolution: {integrity: sha512-T1RB3KQdskh9t3v/qv7niK6P8yvn7ja1mS7QK7XfRVL6wtZ8/mFs/FHf4fKvTA0rKnqnYxl/uHFNbnEt0phgbw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
'@typescript-eslint/typescript-estree@5.62.0':
resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -9745,6 +9829,15 @@ packages:
typescript:
optional: true
+ '@typescript-eslint/typescript-estree@8.4.0':
+ resolution: {integrity: sha512-kJ2OIP4dQw5gdI4uXsaxUZHRwWAGpREJ9Zq6D5L0BweyOrWsL6Sz0YcAZGWhvKnH7fm1J5YFE1JrQL0c9dd53A==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
'@typescript-eslint/utils@5.62.0':
resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -9757,6 +9850,12 @@ packages:
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
+ '@typescript-eslint/utils@8.4.0':
+ resolution: {integrity: sha512-swULW8n1IKLjRAgciCkTCafyTHHfwVQFt8DovmaF69sKbOxTSFMmIZaSHjqO9i/RV0wIblaawhzvtva8Nmm7lQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+
'@typescript-eslint/visitor-keys@5.62.0':
resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -9765,6 +9864,10 @@ packages:
resolution: {integrity: sha512-fB5cw6GRhJUz03MrROVuj5Zm/Q+XWlVdIsFj+Zb1Hvqouc8t+XP2H5y53QYU/MGtd2dPg6/vJJlhoX3xc2ehfw==}
engines: {node: ^16.0.0 || >=18.0.0}
+ '@typescript-eslint/visitor-keys@8.4.0':
+ resolution: {integrity: sha512-zTQD6WLNTre1hj5wp09nBIDiOc2U5r/qmzo7wxPn4ZgAjHql09EofqhF9WF+fZHzL5aCyaIpPcT2hyxl73kr9A==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
'@umijs/ast@4.3.3':
resolution: {integrity: sha512-5aw402aLXxGkCZjPJ5vkQpBdfKkcAe+19A5nqCj6AvV+hpUtDsywu9Vy5CCiD1MWpTUEvyWGA4f+hfvoZLTPUQ==}
@@ -12824,8 +12927,8 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
- eslint@9.9.0:
- resolution: {integrity: sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==}
+ eslint@9.10.0:
+ resolution: {integrity: sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
hasBin: true
peerDependencies:
@@ -12856,10 +12959,6 @@ packages:
resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==}
engines: {node: '>=0.10'}
- esquery@1.6.0:
- resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
- engines: {node: '>=0.10'}
-
esrecurse@4.3.0:
resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
engines: {node: '>=4.0'}
@@ -15895,10 +15994,6 @@ packages:
resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
engines: {node: '>= 0.8.0'}
- optionator@0.9.4:
- resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
- engines: {node: '>= 0.8.0'}
-
ora@5.4.1:
resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
engines: {node: '>=10'}
@@ -17323,6 +17418,19 @@ packages:
react-native:
optional: true
+ react-i18next@15.0.1:
+ resolution: {integrity: sha512-NwxLqNM6CLbeGA9xPsjits0EnXdKgCRSS6cgkgOdNcPXqL+1fYNl8fBg1wmnnHvFy812Bt4IWTPE9zjoPmFj3w==}
+ peerDependencies:
+ i18next: '>= 23.2.3'
+ react: '>= 16.8.0'
+ react-dom: '*'
+ react-native: '*'
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+
react-iframe@1.8.5:
resolution: {integrity: sha512-F4cQJGs3ydaG6fJWfuz9yLwOU0Trzl6kttXuUG+vYwosH8enOOFxZWEDQCSbNVO8ayjfYZeqLxEvdvcsSy4GvA==}
peerDependencies:
@@ -18876,6 +18984,12 @@ packages:
peerDependencies:
typescript: '>=4.2.0'
+ ts-api-utils@1.3.0:
+ resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ typescript: '>=4.2.0'
+
ts-command-line-args@2.5.1:
resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==}
hasBin: true
@@ -19109,6 +19223,15 @@ packages:
typedarray@0.0.6:
resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
+ typescript-eslint@8.4.0:
+ resolution: {integrity: sha512-67qoc3zQZe3CAkO0ua17+7aCLI0dU+sSQd1eKPGq06QE4rfQjstVXR6woHO5qQvGUa550NfGckT4tzh3b3c8Pw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
typescript@4.9.5:
resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
engines: {node: '>=4.2.0'}
@@ -21299,11 +21422,11 @@ snapshots:
eslint-visitor-keys: 2.1.0
semver: 6.3.1
- '@babel/eslint-parser@7.23.3(@babel/core@7.23.6)(eslint@9.9.0)':
+ '@babel/eslint-parser@7.23.3(@babel/core@7.23.6)(eslint@9.10.0)':
dependencies:
'@babel/core': 7.23.6
'@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1
- eslint: 9.9.0
+ eslint: 9.10.0
eslint-visitor-keys: 2.1.0
semver: 6.3.1
@@ -23159,16 +23282,16 @@ snapshots:
eslint: 8.55.0
eslint-visitor-keys: 3.4.3
- '@eslint-community/eslint-utils@4.4.0(eslint@9.9.0)':
+ '@eslint-community/eslint-utils@4.4.0(eslint@9.10.0)':
dependencies:
- eslint: 9.9.0
+ eslint: 9.10.0
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.11.0': {}
'@eslint/compat@1.1.1': {}
- '@eslint/config-array@0.17.1':
+ '@eslint/config-array@0.18.0':
dependencies:
'@eslint/object-schema': 2.1.4
debug: 4.3.6(supports-color@8.1.1)
@@ -23208,10 +23331,12 @@ snapshots:
'@eslint/js@9.10.0': {}
- '@eslint/js@9.9.0': {}
-
'@eslint/object-schema@2.1.4': {}
+ '@eslint/plugin-kit@0.1.0':
+ dependencies:
+ levn: 0.4.1
+
'@ethereumjs/rlp@4.0.1': {}
'@ethereumjs/rlp@5.0.2': {}
@@ -24592,7 +24717,7 @@ snapshots:
async: 3.2.5
chalk: 3.0.0
dayjs: 1.11.10
- debug: 4.3.5(supports-color@5.5.0)
+ debug: 4.3.6(supports-color@8.1.1)
eventemitter2: 5.0.1
fast-json-patch: 3.1.1
fclone: 1.0.11
@@ -24612,7 +24737,7 @@ snapshots:
'@opencensus/core': 0.0.9
'@opencensus/propagation-b3': 0.0.8
async: 2.6.4
- debug: 4.3.5(supports-color@5.5.0)
+ debug: 4.3.6(supports-color@8.1.1)
eventemitter2: 6.4.9
require-in-the-middle: 5.2.0
semver: 7.5.4
@@ -24625,9 +24750,9 @@ snapshots:
'@pm2/js-api@0.8.0':
dependencies:
async: 2.6.4
- debug: 4.3.5(supports-color@5.5.0)
+ debug: 4.3.6(supports-color@8.1.1)
eventemitter2: 6.4.9
- extrareqp2: 1.0.0(debug@4.3.5)
+ extrareqp2: 1.0.0(debug@4.3.6)
ws: 7.5.9
transitivePeerDependencies:
- bufferutil
@@ -26443,15 +26568,15 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.9.0)(typescript@5.4.5))(eslint@9.9.0)(typescript@5.4.5)':
+ '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.10.0)(typescript@5.4.5))(eslint@9.10.0)(typescript@5.4.5)':
dependencies:
'@eslint-community/regexpp': 4.11.0
- '@typescript-eslint/parser': 5.62.0(eslint@9.9.0)(typescript@5.4.5)
+ '@typescript-eslint/parser': 5.62.0(eslint@9.10.0)(typescript@5.4.5)
'@typescript-eslint/scope-manager': 5.62.0
- '@typescript-eslint/type-utils': 5.62.0(eslint@9.9.0)(typescript@5.4.5)
- '@typescript-eslint/utils': 5.62.0(eslint@9.9.0)(typescript@5.4.5)
+ '@typescript-eslint/type-utils': 5.62.0(eslint@9.10.0)(typescript@5.4.5)
+ '@typescript-eslint/utils': 5.62.0(eslint@9.10.0)(typescript@5.4.5)
debug: 4.3.6(supports-color@8.1.1)
- eslint: 9.9.0
+ eslint: 9.10.0
graphemer: 1.4.0
ignore: 5.3.2
natural-compare-lite: 1.4.0
@@ -26482,6 +26607,24 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@typescript-eslint/eslint-plugin@8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.10.0)(typescript@5.4.5))(eslint@9.10.0)(typescript@5.4.5)':
+ dependencies:
+ '@eslint-community/regexpp': 4.11.0
+ '@typescript-eslint/parser': 8.4.0(eslint@9.10.0)(typescript@5.4.5)
+ '@typescript-eslint/scope-manager': 8.4.0
+ '@typescript-eslint/type-utils': 8.4.0(eslint@9.10.0)(typescript@5.4.5)
+ '@typescript-eslint/utils': 8.4.0(eslint@9.10.0)(typescript@5.4.5)
+ '@typescript-eslint/visitor-keys': 8.4.0
+ eslint: 9.10.0
+ graphemer: 1.4.0
+ ignore: 5.3.2
+ natural-compare: 1.4.0
+ ts-api-utils: 1.3.0(typescript@5.4.5)
+ optionalDependencies:
+ typescript: 5.4.5
+ transitivePeerDependencies:
+ - supports-color
+
'@typescript-eslint/parser@5.62.0(eslint@8.55.0)(typescript@5.4.4)':
dependencies:
'@typescript-eslint/scope-manager': 5.62.0
@@ -26494,13 +26637,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@5.62.0(eslint@9.9.0)(typescript@5.4.5)':
+ '@typescript-eslint/parser@5.62.0(eslint@9.10.0)(typescript@5.4.5)':
dependencies:
'@typescript-eslint/scope-manager': 5.62.0
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.5)
debug: 4.3.6(supports-color@8.1.1)
- eslint: 9.9.0
+ eslint: 9.10.0
optionalDependencies:
typescript: 5.4.5
transitivePeerDependencies:
@@ -26519,6 +26662,19 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@typescript-eslint/parser@8.4.0(eslint@9.10.0)(typescript@5.4.5)':
+ dependencies:
+ '@typescript-eslint/scope-manager': 8.4.0
+ '@typescript-eslint/types': 8.4.0
+ '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.4.5)
+ '@typescript-eslint/visitor-keys': 8.4.0
+ debug: 4.3.6(supports-color@8.1.1)
+ eslint: 9.10.0
+ optionalDependencies:
+ typescript: 5.4.5
+ transitivePeerDependencies:
+ - supports-color
+
'@typescript-eslint/scope-manager@5.62.0':
dependencies:
'@typescript-eslint/types': 5.62.0
@@ -26529,6 +26685,11 @@ snapshots:
'@typescript-eslint/types': 6.14.0
'@typescript-eslint/visitor-keys': 6.14.0
+ '@typescript-eslint/scope-manager@8.4.0':
+ dependencies:
+ '@typescript-eslint/types': 8.4.0
+ '@typescript-eslint/visitor-keys': 8.4.0
+
'@typescript-eslint/type-utils@5.62.0(eslint@8.55.0)(typescript@5.4.4)':
dependencies:
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.4)
@@ -26541,12 +26702,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/type-utils@5.62.0(eslint@9.9.0)(typescript@5.4.5)':
+ '@typescript-eslint/type-utils@5.62.0(eslint@9.10.0)(typescript@5.4.5)':
dependencies:
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.5)
- '@typescript-eslint/utils': 5.62.0(eslint@9.9.0)(typescript@5.4.5)
+ '@typescript-eslint/utils': 5.62.0(eslint@9.10.0)(typescript@5.4.5)
debug: 4.3.6(supports-color@8.1.1)
- eslint: 9.9.0
+ eslint: 9.10.0
tsutils: 3.21.0(typescript@5.4.5)
optionalDependencies:
typescript: 5.4.5
@@ -26565,10 +26726,24 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@typescript-eslint/type-utils@8.4.0(eslint@9.10.0)(typescript@5.4.5)':
+ dependencies:
+ '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.4.5)
+ '@typescript-eslint/utils': 8.4.0(eslint@9.10.0)(typescript@5.4.5)
+ debug: 4.3.6(supports-color@8.1.1)
+ ts-api-utils: 1.3.0(typescript@5.4.5)
+ optionalDependencies:
+ typescript: 5.4.5
+ transitivePeerDependencies:
+ - eslint
+ - supports-color
+
'@typescript-eslint/types@5.62.0': {}
'@typescript-eslint/types@6.14.0': {}
+ '@typescript-eslint/types@8.4.0': {}
+
'@typescript-eslint/typescript-estree@5.62.0(typescript@5.4.4)':
dependencies:
'@typescript-eslint/types': 5.62.0
@@ -26604,13 +26779,28 @@ snapshots:
debug: 4.3.6(supports-color@8.1.1)
globby: 11.1.0
is-glob: 4.0.3
- semver: 7.6.2
+ semver: 7.6.3
ts-api-utils: 1.0.3(typescript@5.4.4)
optionalDependencies:
typescript: 5.4.4
transitivePeerDependencies:
- supports-color
+ '@typescript-eslint/typescript-estree@8.4.0(typescript@5.4.5)':
+ dependencies:
+ '@typescript-eslint/types': 8.4.0
+ '@typescript-eslint/visitor-keys': 8.4.0
+ debug: 4.3.6(supports-color@8.1.1)
+ fast-glob: 3.3.2
+ is-glob: 4.0.3
+ minimatch: 9.0.5
+ semver: 7.6.3
+ ts-api-utils: 1.3.0(typescript@5.4.5)
+ optionalDependencies:
+ typescript: 5.4.5
+ transitivePeerDependencies:
+ - supports-color
+
'@typescript-eslint/utils@5.62.0(eslint@8.55.0)(typescript@5.4.4)':
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0)
@@ -26626,15 +26816,15 @@ snapshots:
- supports-color
- typescript
- '@typescript-eslint/utils@5.62.0(eslint@9.9.0)(typescript@5.4.5)':
+ '@typescript-eslint/utils@5.62.0(eslint@9.10.0)(typescript@5.4.5)':
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.0)
+ '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0)
'@types/json-schema': 7.0.15
'@types/semver': 7.5.8
'@typescript-eslint/scope-manager': 5.62.0
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.5)
- eslint: 9.9.0
+ eslint: 9.10.0
eslint-scope: 5.1.1
semver: 7.6.3
transitivePeerDependencies:
@@ -26650,7 +26840,18 @@ snapshots:
'@typescript-eslint/types': 6.14.0
'@typescript-eslint/typescript-estree': 6.14.0(typescript@5.4.4)
eslint: 8.55.0
- semver: 7.6.2
+ semver: 7.6.3
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
+ '@typescript-eslint/utils@8.4.0(eslint@9.10.0)(typescript@5.4.5)':
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0)
+ '@typescript-eslint/scope-manager': 8.4.0
+ '@typescript-eslint/types': 8.4.0
+ '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.4.5)
+ eslint: 9.10.0
transitivePeerDependencies:
- supports-color
- typescript
@@ -26665,6 +26866,11 @@ snapshots:
'@typescript-eslint/types': 6.14.0
eslint-visitor-keys: 3.4.3
+ '@typescript-eslint/visitor-keys@8.4.0':
+ dependencies:
+ '@typescript-eslint/types': 8.4.0
+ eslint-visitor-keys: 3.4.3
+
'@umijs/ast@4.3.3':
dependencies:
'@umijs/bundler-utils': 4.3.3
@@ -26899,17 +27105,17 @@ snapshots:
- supports-color
- typescript
- '@umijs/lint@4.3.3(eslint@9.9.0)(stylelint@16.8.2(typescript@5.4.5))(typescript@5.4.5)':
+ '@umijs/lint@4.3.3(eslint@9.10.0)(stylelint@16.8.2(typescript@5.4.5))(typescript@5.4.5)':
dependencies:
'@babel/core': 7.23.6
- '@babel/eslint-parser': 7.23.3(@babel/core@7.23.6)(eslint@9.9.0)
+ '@babel/eslint-parser': 7.23.3(@babel/core@7.23.6)(eslint@9.10.0)
'@stylelint/postcss-css-in-js': 0.38.0(postcss-syntax@0.36.2(postcss@8.4.39))(postcss@8.4.39)
- '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.9.0)(typescript@5.4.5))(eslint@9.9.0)(typescript@5.4.5)
- '@typescript-eslint/parser': 5.62.0(eslint@9.9.0)(typescript@5.4.5)
+ '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.10.0)(typescript@5.4.5))(eslint@9.10.0)(typescript@5.4.5)
+ '@typescript-eslint/parser': 5.62.0(eslint@9.10.0)(typescript@5.4.5)
'@umijs/babel-preset-umi': 4.3.3
- eslint-plugin-jest: 27.2.3(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.9.0)(typescript@5.4.5))(eslint@9.9.0)(typescript@5.4.5))(eslint@9.9.0)(typescript@5.4.5)
- eslint-plugin-react: 7.33.2(eslint@9.9.0)
- eslint-plugin-react-hooks: 4.6.0(eslint@9.9.0)
+ eslint-plugin-jest: 27.2.3(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.10.0)(typescript@5.4.5))(eslint@9.10.0)(typescript@5.4.5))(eslint@9.10.0)(typescript@5.4.5)
+ eslint-plugin-react: 7.33.2(eslint@9.10.0)
+ eslint-plugin-react-hooks: 4.6.0(eslint@9.10.0)
postcss: 8.4.39
postcss-syntax: 0.36.2(postcss@8.4.39)
stylelint-config-standard: 25.0.0(stylelint@16.8.2(typescript@5.4.5))
@@ -30419,10 +30625,10 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
- eslint-plugin-jest-dom@5.4.0(@testing-library/dom@10.4.0)(eslint@9.9.0):
+ eslint-plugin-jest-dom@5.4.0(@testing-library/dom@10.4.0)(eslint@9.10.0):
dependencies:
'@babel/runtime': 7.25.0
- eslint: 9.9.0
+ eslint: 9.10.0
requireindex: 1.2.0
optionalDependencies:
'@testing-library/dom': 10.4.0
@@ -30437,12 +30643,12 @@ snapshots:
- supports-color
- typescript
- eslint-plugin-jest@27.2.3(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.9.0)(typescript@5.4.5))(eslint@9.9.0)(typescript@5.4.5))(eslint@9.9.0)(typescript@5.4.5):
+ eslint-plugin-jest@27.2.3(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.10.0)(typescript@5.4.5))(eslint@9.10.0)(typescript@5.4.5))(eslint@9.10.0)(typescript@5.4.5):
dependencies:
- '@typescript-eslint/utils': 5.62.0(eslint@9.9.0)(typescript@5.4.5)
- eslint: 9.9.0
+ '@typescript-eslint/utils': 5.62.0(eslint@9.10.0)(typescript@5.4.5)
+ eslint: 9.10.0
optionalDependencies:
- '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.9.0)(typescript@5.4.5))(eslint@9.9.0)(typescript@5.4.5)
+ '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.10.0)(typescript@5.4.5))(eslint@9.10.0)(typescript@5.4.5)
transitivePeerDependencies:
- supports-color
- typescript
@@ -30482,9 +30688,9 @@ snapshots:
dependencies:
eslint: 8.55.0
- eslint-plugin-react-hooks@4.6.0(eslint@9.9.0):
+ eslint-plugin-react-hooks@4.6.0(eslint@9.10.0):
dependencies:
- eslint: 9.9.0
+ eslint: 9.10.0
eslint-plugin-react@7.33.2(eslint@8.55.0):
dependencies:
@@ -30506,14 +30712,14 @@ snapshots:
semver: 6.3.1
string.prototype.matchall: 4.0.11
- eslint-plugin-react@7.33.2(eslint@9.9.0):
+ eslint-plugin-react@7.33.2(eslint@9.10.0):
dependencies:
array-includes: 3.1.8
array.prototype.flatmap: 1.3.2
array.prototype.tosorted: 1.1.4
doctrine: 2.1.0
es-iterator-helpers: 1.0.19
- eslint: 9.9.0
+ eslint: 9.10.0
estraverse: 5.3.0
jsx-ast-utils: 3.3.5
minimatch: 3.1.2
@@ -30526,10 +30732,10 @@ snapshots:
semver: 6.3.1
string.prototype.matchall: 4.0.11
- eslint-plugin-testing-library@5.11.1(eslint@9.9.0)(typescript@5.4.5):
+ eslint-plugin-testing-library@5.11.1(eslint@9.10.0)(typescript@5.4.5):
dependencies:
- '@typescript-eslint/utils': 5.62.0(eslint@9.9.0)(typescript@5.4.5)
- eslint: 9.9.0
+ '@typescript-eslint/utils': 5.62.0(eslint@9.10.0)(typescript@5.4.5)
+ eslint: 9.10.0
transitivePeerDependencies:
- supports-color
- typescript
@@ -30604,13 +30810,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint@9.9.0:
+ eslint@9.10.0:
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.0)
+ '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0)
'@eslint-community/regexpp': 4.11.0
- '@eslint/config-array': 0.17.1
+ '@eslint/config-array': 0.18.0
'@eslint/eslintrc': 3.1.0
- '@eslint/js': 9.9.0
+ '@eslint/js': 9.10.0
+ '@eslint/plugin-kit': 0.1.0
'@humanwhocodes/module-importer': 1.0.1
'@humanwhocodes/retry': 0.3.0
'@nodelib/fs.walk': 1.2.8
@@ -30622,7 +30829,7 @@ snapshots:
eslint-scope: 8.0.2
eslint-visitor-keys: 4.0.0
espree: 10.1.0
- esquery: 1.6.0
+ esquery: 1.5.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
file-entry-cache: 8.0.0
@@ -30633,11 +30840,10 @@ snapshots:
is-glob: 4.0.3
is-path-inside: 3.0.3
json-stable-stringify-without-jsonify: 1.0.1
- levn: 0.4.1
lodash.merge: 4.6.2
minimatch: 3.1.2
natural-compare: 1.4.0
- optionator: 0.9.4
+ optionator: 0.9.3
strip-ansi: 6.0.1
text-table: 0.2.0
transitivePeerDependencies:
@@ -30663,10 +30869,6 @@ snapshots:
dependencies:
estraverse: 5.3.0
- esquery@1.6.0:
- dependencies:
- estraverse: 5.3.0
-
esrecurse@4.3.0:
dependencies:
estraverse: 5.3.0
@@ -30928,9 +31130,9 @@ snapshots:
iconv-lite: 0.4.24
tmp: 0.0.33
- extrareqp2@1.0.0(debug@4.3.5):
+ extrareqp2@1.0.0(debug@4.3.6):
dependencies:
- follow-redirects: 1.15.6(debug@4.3.5)
+ follow-redirects: 1.15.6(debug@4.3.6)
transitivePeerDependencies:
- debug
@@ -31145,6 +31347,10 @@ snapshots:
optionalDependencies:
debug: 4.3.5(supports-color@5.5.0)
+ follow-redirects@1.15.6(debug@4.3.6):
+ optionalDependencies:
+ debug: 4.3.6(supports-color@8.1.1)
+
fontkit@2.0.2:
dependencies:
'@swc/helpers': 0.4.36
@@ -34302,15 +34508,6 @@ snapshots:
prelude-ls: 1.2.1
type-check: 0.4.0
- optionator@0.9.4:
- dependencies:
- deep-is: 0.1.4
- fast-levenshtein: 2.0.6
- levn: 0.4.1
- prelude-ls: 1.2.1
- type-check: 0.4.0
- word-wrap: 1.2.5
-
ora@5.4.1:
dependencies:
bl: 4.1.0
@@ -34707,7 +34904,7 @@ snapshots:
pm2-axon-rpc@0.7.1:
dependencies:
- debug: 4.3.5(supports-color@5.5.0)
+ debug: 4.3.6(supports-color@8.1.1)
transitivePeerDependencies:
- supports-color
@@ -34715,7 +34912,7 @@ snapshots:
dependencies:
amp: 0.3.1
amp-message: 0.1.2
- debug: 4.3.5(supports-color@5.5.0)
+ debug: 4.3.6(supports-color@8.1.1)
escape-string-regexp: 4.0.0
transitivePeerDependencies:
- supports-color
@@ -34732,7 +34929,7 @@ snapshots:
pm2-sysmonit@1.2.8:
dependencies:
async: 3.2.5
- debug: 4.3.5(supports-color@5.5.0)
+ debug: 4.3.6(supports-color@8.1.1)
pidusage: 2.0.21
systeminformation: 5.22.8
tx2: 1.0.5
@@ -35936,6 +36133,15 @@ snapshots:
optionalDependencies:
react-dom: 18.3.1(react@18.3.1)
+ react-i18next@15.0.1(i18next@23.13.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+ dependencies:
+ '@babel/runtime': 7.25.0
+ html-parse-stringify: 3.0.1
+ i18next: 23.13.0
+ react: 18.3.1
+ optionalDependencies:
+ react-dom: 18.3.1(react@18.3.1)
+
react-iframe@1.8.5(react@18.3.1):
dependencies:
object-assign: 4.1.1
@@ -37840,6 +38046,10 @@ snapshots:
dependencies:
typescript: 5.4.4
+ ts-api-utils@1.3.0(typescript@5.4.5):
+ dependencies:
+ typescript: 5.4.5
+
ts-command-line-args@2.5.1:
dependencies:
chalk: 4.1.2
@@ -38150,6 +38360,17 @@ snapshots:
typedarray@0.0.6: {}
+ typescript-eslint@8.4.0(eslint@9.10.0)(typescript@5.4.5):
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.10.0)(typescript@5.4.5))(eslint@9.10.0)(typescript@5.4.5)
+ '@typescript-eslint/parser': 8.4.0(eslint@9.10.0)(typescript@5.4.5)
+ '@typescript-eslint/utils': 8.4.0(eslint@9.10.0)(typescript@5.4.5)
+ optionalDependencies:
+ typescript: 5.4.5
+ transitivePeerDependencies:
+ - eslint
+ - supports-color
+
typescript@4.9.5: {}
typescript@5.4.4: {}
@@ -38179,13 +38400,13 @@ snapshots:
uglify-to-browserify@1.0.2:
optional: true
- umi@4.3.3(@babel/core@7.22.10)(@types/node@20.14.2)(@types/react@18.3.3)(eslint@9.9.0)(lightningcss@1.26.0)(prettier@3.2.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.4)(sass@1.77.8)(stylelint@16.8.2(typescript@5.4.5))(terser@5.31.6)(type-fest@4.25.0)(typescript@5.4.5)(webpack@5.93.0):
+ umi@4.3.3(@babel/core@7.22.10)(@types/node@20.14.2)(@types/react@18.3.3)(eslint@9.10.0)(lightningcss@1.26.0)(prettier@3.2.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.4)(sass@1.77.8)(stylelint@16.8.2(typescript@5.4.5))(terser@5.31.6)(type-fest@4.25.0)(typescript@5.4.5)(webpack@5.93.0):
dependencies:
'@babel/runtime': 7.23.6
'@umijs/bundler-utils': 4.3.3
'@umijs/bundler-webpack': 4.3.3(type-fest@4.25.0)(typescript@5.4.5)(webpack@5.93.0)
'@umijs/core': 4.3.3
- '@umijs/lint': 4.3.3(eslint@9.9.0)(stylelint@16.8.2(typescript@5.4.5))(typescript@5.4.5)
+ '@umijs/lint': 4.3.3(eslint@9.10.0)(stylelint@16.8.2(typescript@5.4.5))(typescript@5.4.5)
'@umijs/preset-umi': 4.3.3(@types/node@20.14.2)(@types/react@18.3.3)(lightningcss@1.26.0)(rollup@3.29.4)(sass@1.77.8)(terser@5.31.6)(type-fest@4.25.0)(typescript@5.4.5)(webpack@5.93.0)
'@umijs/renderer-react': 4.3.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@umijs/server': 4.3.3