@liujitcn/kratos-admin-core 0.0.38 → 0.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/build/codegen-hmr.ts +37 -0
- package/build/plugins.ts +2 -0
- package/build/source-patterns.ts +7 -0
- package/dist/package/declarations/build/codegen-hmr.d.ts +3 -0
- package/dist/package/declarations/build/source-patterns.d.ts +2 -0
- package/dist/package/declarations/src/components/ProForm/components/ProFormItem.vue.d.ts +9 -4
- package/dist/package/declarations/src/components/ProForm/interface/index.d.ts +2 -0
- package/dist/package/declarations/src/index.d.ts +5 -0
- package/dist/package/declarations/src/locales/generated.d.ts +12 -0
- package/dist/package/declarations/src/rpc/base/v1/language.d.ts +1 -1
- package/dist/package/declarations/src/rpc/base/v1/login.d.ts +2 -0
- package/dist/package/declarations/src/rpc/base/v1/mfa.d.ts +2 -0
- package/dist/package/declarations/src/rpc/base/v1/oauth.d.ts +4 -0
- package/dist/package/declarations/src/rpc/base/v1/oauth_client.d.ts +1 -1
- package/dist/package/declarations/src/rpc/system/admin/v1/base_i18n.d.ts +1 -1
- package/dist/package/declarations/src/views/login/components/LoginForm.vue.d.ts +5 -1
- package/dist/package/src/components/ProForm/components/ProFormItem.vue +5 -1
- package/dist/package/src/components/ProForm/index.vue +27 -5
- package/dist/package/src/components/ProForm/interface/index.ts +2 -0
- package/dist/package/src/index.ts +5 -5
- package/dist/package/src/layouts/index.vue +0 -6
- package/dist/package/src/layouts/indexAsync.vue +0 -6
- package/dist/package/src/locales/en-US.json +4 -1
- package/dist/package/src/locales/ja-JP.json +4 -1
- package/dist/package/src/locales/zh-CN.json +4 -1
- package/dist/package/src/locales/zh-TW.json +4 -1
- package/dist/package/src/rpc/base/v1/config.ts +1 -1
- package/dist/package/src/rpc/base/v1/file.ts +1 -1
- package/dist/package/src/rpc/base/v1/language.ts +2 -2
- package/dist/package/src/rpc/base/v1/login.ts +3 -1
- package/dist/package/src/rpc/base/v1/mfa.ts +3 -1
- package/dist/package/src/rpc/base/v1/oauth.ts +5 -1
- package/dist/package/src/rpc/base/v1/oauth_client.ts +2 -2
- package/dist/package/src/rpc/common/v1/common.ts +1 -1
- package/dist/package/src/rpc/common/v1/enum.ts +1 -1
- package/dist/package/src/rpc/common/v1/types.ts +1 -1
- package/dist/package/src/rpc/google/protobuf/empty.ts +1 -1
- package/dist/package/src/rpc/google/protobuf/wrappers.ts +1 -1
- package/dist/package/src/rpc/system/admin/v1/auth.ts +1 -1
- package/dist/package/src/rpc/system/admin/v1/base_dict.ts +1 -1
- package/dist/package/src/rpc/system/admin/v1/base_i18n.ts +2 -2
- package/dist/package/src/rpc/system/admin/v1/base_tenant.ts +1 -1
- package/dist/package/src/rpc/system/admin/v1/common.ts +1 -1
- package/dist/package/src/rpc/system/common/v1/common.ts +1 -1
- package/dist/package/src/views/login/components/LoginForm.vue +66 -12
- package/dist/package/src/views/login/index.scss +24 -2
- package/dist/package/src/views/login/index.vue +3 -2
- package/package.json +2 -2
- package/vite.config.ts +2 -3
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @liujitcn/kratos-admin-core
|
|
2
2
|
|
|
3
|
+
账号密码、OAuth 票据兑换和微信登录统一返回 `mfa_remember_days`,表示当前登录策略允许的 MFA 设备免验证天数;为 `0` 时不提供记住设备选项。
|
|
4
|
+
|
|
3
5
|
kratos-admin 前端底座包。它不包含具体业务模块,提供登录、MFA 校验、菜单、用户信息、应用启动、动态路由、布局、运行状态、公共组件和静态状态页;MFA 绑定面板与恢复码弹窗由登录页和 System 模块共用。宿主可以只安装 core;个人中心、AI 助手和系统管理能力必须由 System 模块提供。
|
|
4
6
|
|
|
5
7
|
浏览器认证使用 Cookie-only 刷新令牌与内存访问令牌。Core 不持久化任何访问令牌或刷新令牌,刷新请求统一携带 `X-Refresh-Token-Transport: cookie` 并启用凭据 Cookie。
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { HotPayload, Plugin, WebSocketClient } from "vite";
|
|
2
|
+
|
|
3
|
+
/** 暂缓生成期间的开发热更新,释放后统一刷新以加载完整产物。 */
|
|
4
|
+
export function codegenHmrPlugin(): Plugin {
|
|
5
|
+
return {
|
|
6
|
+
name: "admin-codegen-hmr",
|
|
7
|
+
apply: "serve",
|
|
8
|
+
configureServer(server) {
|
|
9
|
+
const clients = new Set<WebSocketClient>();
|
|
10
|
+
const send = server.ws.send.bind(server.ws);
|
|
11
|
+
let pending = false;
|
|
12
|
+
const release = (client: WebSocketClient) => {
|
|
13
|
+
clients.delete(client);
|
|
14
|
+
if (!clients.size && pending) {
|
|
15
|
+
pending = false;
|
|
16
|
+
send({ type: "full-reload", path: "*" });
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
server.ws.send = (payload: HotPayload | string, data?: unknown) => {
|
|
20
|
+
if (clients.size && typeof payload !== "string" && (payload.type === "update" || payload.type === "full-reload")) {
|
|
21
|
+
pending = true;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (typeof payload === "string") send(payload, data);
|
|
25
|
+
else send(payload);
|
|
26
|
+
};
|
|
27
|
+
server.ws.on("admin:codegen-hold", (_data, client) => {
|
|
28
|
+
if (!clients.has(client)) {
|
|
29
|
+
clients.add(client);
|
|
30
|
+
client.socket.once("close", () => release(client));
|
|
31
|
+
}
|
|
32
|
+
client.send("admin:codegen-held", {});
|
|
33
|
+
});
|
|
34
|
+
server.ws.on("admin:codegen-release", (_data, client) => release(client));
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
package/build/plugins.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { codegenHmrPlugin } from "./codegen-hmr";
|
|
1
2
|
import { resolve } from "path";
|
|
2
3
|
import { PluginOption } from "vite";
|
|
3
4
|
import { VitePWA } from "vite-plugin-pwa";
|
|
@@ -37,6 +38,7 @@ export const createVitePlugins = (viteEnv: ViteEnv, options: VitePluginOptions =
|
|
|
37
38
|
const { VITE_GLOB_APP_TITLE, VITE_REPORT, VITE_DEVTOOLS, VITE_PWA, VITE_CODEINSPECTOR } = viteEnv;
|
|
38
39
|
const sourcePatterns = options.sourcePatterns;
|
|
39
40
|
return [
|
|
41
|
+
codegenHmrPlugin(),
|
|
40
42
|
vue(),
|
|
41
43
|
// vue 可以使用 jsx/tsx 语法
|
|
42
44
|
vueJsx(),
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** 为 API 和组件自动导入创建跨平台源码匹配规则,包含 npm 包内源码。 */
|
|
2
|
+
export function createSourcePatterns(sourceRoots: string[]): RegExp[] {
|
|
3
|
+
return [...new Set(sourceRoots.map(sourceRoot => sourceRoot.replaceAll("\\", "/")))].map(sourceRoot => {
|
|
4
|
+
const escapedRoot = sourceRoot.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5
|
+
return new RegExp(`^${escapedRoot.replaceAll("/", "[/\\\\]")}[/\\\\].*\\.(?:vue|[jt]sx?)(?:\\?.*)?$`);
|
|
6
|
+
});
|
|
7
|
+
}
|
|
@@ -4,18 +4,23 @@ interface ProFormItemProps {
|
|
|
4
4
|
field: ProFormField;
|
|
5
5
|
model: Record<string, any>;
|
|
6
6
|
}
|
|
7
|
-
declare var
|
|
7
|
+
declare var __VLS_10: string, __VLS_11: {
|
|
8
|
+
field: ProFormField;
|
|
9
|
+
model: Record<string, any>;
|
|
10
|
+
}, __VLS_133: string, __VLS_134: {
|
|
8
11
|
option: import("element-plus").TransferDataItem;
|
|
9
12
|
field: ProFormField;
|
|
10
13
|
model: Record<string, any>;
|
|
11
|
-
},
|
|
14
|
+
}, __VLS_179: string, __VLS_180: {
|
|
12
15
|
field: ProFormField;
|
|
13
16
|
model: Record<string, any>;
|
|
14
17
|
};
|
|
15
18
|
type __VLS_Slots = {} & {
|
|
16
|
-
[K in NonNullable<typeof
|
|
19
|
+
[K in NonNullable<typeof __VLS_10>]?: (props: typeof __VLS_11) => any;
|
|
20
|
+
} & {
|
|
21
|
+
[K in NonNullable<typeof __VLS_133>]?: (props: typeof __VLS_134) => any;
|
|
17
22
|
} & {
|
|
18
|
-
[K in NonNullable<typeof
|
|
23
|
+
[K in NonNullable<typeof __VLS_179>]?: (props: typeof __VLS_180) => any;
|
|
19
24
|
};
|
|
20
25
|
declare const __VLS_base: import("vue").DefineComponent<ProFormItemProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ProFormItemProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
26
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import "./vite-env.d.ts";
|
|
2
|
+
import "./typings/global.d.ts";
|
|
3
|
+
import "./typings/utils.d.ts";
|
|
4
|
+
import "../types/generated/auto-imports.d.ts";
|
|
5
|
+
import "../types/generated/components.d.ts";
|
|
1
6
|
export * from "./modules";
|
|
2
7
|
export * from "./locales";
|
|
3
8
|
export { defLanguageService } from "./api/base/v1/language";
|
|
@@ -181,6 +181,7 @@ export declare const LOCALE_MESSAGES: {
|
|
|
181
181
|
"core.login.welcome": string;
|
|
182
182
|
"core.login.mfa_title": string;
|
|
183
183
|
"core.login.mfa_code": string;
|
|
184
|
+
"core.login.mfa_remember_device": string;
|
|
184
185
|
"core.login.mfa_recovery_code": string;
|
|
185
186
|
"core.login.mfa_setup_title": string;
|
|
186
187
|
"core.login.mfa_setup_qr_alt": string;
|
|
@@ -337,6 +338,8 @@ export declare const LOCALE_MESSAGES: {
|
|
|
337
338
|
"common.resource.default": string;
|
|
338
339
|
"common.action.delete_resource": string;
|
|
339
340
|
"common.action.set_field_status": string;
|
|
341
|
+
"core.home.demo_scope": string;
|
|
342
|
+
"core.home.main_title": string;
|
|
340
343
|
};
|
|
341
344
|
readonly "en-US": {
|
|
342
345
|
"common.action.back": string;
|
|
@@ -514,6 +517,7 @@ export declare const LOCALE_MESSAGES: {
|
|
|
514
517
|
"core.login.tenant_code": string;
|
|
515
518
|
"core.login.user_name": string;
|
|
516
519
|
"core.login.welcome": string;
|
|
520
|
+
"core.login.mfa_remember_device": string;
|
|
517
521
|
"core.login.mfa_title": string;
|
|
518
522
|
"core.login.mfa_code": string;
|
|
519
523
|
"core.login.mfa_recovery_code": string;
|
|
@@ -672,6 +676,8 @@ export declare const LOCALE_MESSAGES: {
|
|
|
672
676
|
"common.resource.default": string;
|
|
673
677
|
"common.action.delete_resource": string;
|
|
674
678
|
"common.action.set_field_status": string;
|
|
679
|
+
"core.home.demo_scope": string;
|
|
680
|
+
"core.home.main_title": string;
|
|
675
681
|
};
|
|
676
682
|
readonly "ja-JP": {
|
|
677
683
|
"common.action.back": string;
|
|
@@ -730,6 +736,7 @@ export declare const LOCALE_MESSAGES: {
|
|
|
730
736
|
"core.layout.avatar": string;
|
|
731
737
|
"core.layout.logo_alt": string;
|
|
732
738
|
"core.login.background_alt": string;
|
|
739
|
+
"core.login.mfa_remember_device": string;
|
|
733
740
|
"core.login.mfa_title": string;
|
|
734
741
|
"core.login.mfa_code": string;
|
|
735
742
|
"core.login.mfa_recovery_code": string;
|
|
@@ -1007,6 +1014,8 @@ export declare const LOCALE_MESSAGES: {
|
|
|
1007
1014
|
"common.resource.default": string;
|
|
1008
1015
|
"common.action.delete_resource": string;
|
|
1009
1016
|
"common.action.set_field_status": string;
|
|
1017
|
+
"core.home.demo_scope": string;
|
|
1018
|
+
"core.home.main_title": string;
|
|
1010
1019
|
};
|
|
1011
1020
|
readonly "zh-TW": {
|
|
1012
1021
|
"common.action.back": string;
|
|
@@ -1065,6 +1074,7 @@ export declare const LOCALE_MESSAGES: {
|
|
|
1065
1074
|
"core.layout.avatar": string;
|
|
1066
1075
|
"core.layout.logo_alt": string;
|
|
1067
1076
|
"core.login.background_alt": string;
|
|
1077
|
+
"core.login.mfa_remember_device": string;
|
|
1068
1078
|
"core.login.mfa_title": string;
|
|
1069
1079
|
"core.login.mfa_code": string;
|
|
1070
1080
|
"core.login.mfa_recovery_code": string;
|
|
@@ -1342,6 +1352,8 @@ export declare const LOCALE_MESSAGES: {
|
|
|
1342
1352
|
"common.resource.default": string;
|
|
1343
1353
|
"common.action.delete_resource": string;
|
|
1344
1354
|
"common.action.set_field_status": string;
|
|
1355
|
+
"core.home.demo_scope": string;
|
|
1356
|
+
"core.home.main_title": string;
|
|
1345
1357
|
};
|
|
1346
1358
|
};
|
|
1347
1359
|
export type GeneratedLocale = keyof typeof LOCALE_MESSAGES;
|
|
@@ -13,7 +13,7 @@ export interface OptionLanguageResponse {
|
|
|
13
13
|
/** 当前支持的语言列表 */
|
|
14
14
|
languages: LanguageItem[];
|
|
15
15
|
}
|
|
16
|
-
/** 语言公共服务。 */
|
|
16
|
+
/** Base语言公共服务。 */
|
|
17
17
|
export interface LanguageService {
|
|
18
18
|
/** 查询当前支持的语言选项。 */
|
|
19
19
|
OptionLanguage(request: OptionLanguageRequest): Promise<OptionLanguageResponse>;
|
|
@@ -89,6 +89,8 @@ export interface CreateOauthSessionResponse {
|
|
|
89
89
|
mfa_method: string;
|
|
90
90
|
/** WebAuthn认证选项JSON */
|
|
91
91
|
mfa_webauthn_options_json: string;
|
|
92
|
+
/** 当前登录策略允许的MFA设备免验证天数 */
|
|
93
|
+
mfa_remember_days: number;
|
|
92
94
|
}
|
|
93
95
|
/** 三方登录回调请求 */
|
|
94
96
|
export interface HandleOauthCallbackRequest {
|
|
@@ -133,6 +135,8 @@ export interface ExchangeOauthTicketResponse {
|
|
|
133
135
|
mfa_method: string;
|
|
134
136
|
/** WebAuthn认证选项JSON */
|
|
135
137
|
mfa_webauthn_options_json: string;
|
|
138
|
+
/** 当前登录策略允许的MFA设备免验证天数 */
|
|
139
|
+
mfa_remember_days: number;
|
|
136
140
|
}
|
|
137
141
|
/** 个人中心三方账号绑定回调请求 */
|
|
138
142
|
export interface HandleOauthBindingCallbackRequest {
|
|
@@ -16,7 +16,7 @@ export interface IssueOauthClientTokenResponse {
|
|
|
16
16
|
/** 令牌有效时间,单位为秒 */
|
|
17
17
|
expires_in: number;
|
|
18
18
|
}
|
|
19
|
-
/** 开放授权客户端令牌服务。 */
|
|
19
|
+
/** Base开放授权客户端令牌服务。 */
|
|
20
20
|
export interface OauthClientService {
|
|
21
21
|
/** 使用客户端凭据换取访问令牌。 */
|
|
22
22
|
IssueOauthClientToken(request: IssueOauthClientTokenRequest): Promise<IssueOauthClientTokenResponse>;
|
|
@@ -70,7 +70,7 @@ export interface CodeGenLocaleConfig {
|
|
|
70
70
|
/** 左树描述 */
|
|
71
71
|
left_tree_comment: string;
|
|
72
72
|
}
|
|
73
|
-
/** 国际化翻译信息服务。 */
|
|
73
|
+
/** Admin国际化翻译信息服务。 */
|
|
74
74
|
export interface BaseI18nService {
|
|
75
75
|
/** 翻译单个文本。 */
|
|
76
76
|
DraftBaseI18n(request: DraftBaseI18nRequest): Promise<DraftBaseI18nResponse>;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import "go-captcha-vue/dist/style.css";
|
|
2
|
-
|
|
2
|
+
/** 登录表单属性,验证弹窗以外层登录卡片的中心定位。 */
|
|
3
|
+
interface LoginFormProps {
|
|
4
|
+
dialogAnchor?: HTMLElement;
|
|
5
|
+
}
|
|
6
|
+
declare const __VLS_export: import("vue").DefineComponent<LoginFormProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<LoginFormProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
3
7
|
declare const _default: typeof __VLS_export;
|
|
4
8
|
export default _default;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<el-input v-if="field.component === 'input'" v-model.trim="fieldValue" v-bind="fieldProps"
|
|
2
|
+
<el-input v-if="field.component === 'input'" v-model.trim="fieldValue" v-bind="fieldProps">
|
|
3
|
+
<template v-if="field.suffixSlotName" #append>
|
|
4
|
+
<slot :name="field.suffixSlotName" :field="field" :model="model" />
|
|
5
|
+
</template>
|
|
6
|
+
</el-input>
|
|
3
7
|
|
|
4
8
|
<el-input
|
|
5
9
|
v-else-if="field.component === 'password'"
|
|
@@ -16,11 +16,21 @@
|
|
|
16
16
|
</el-tooltip>
|
|
17
17
|
</div>
|
|
18
18
|
</template>
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
<div class="pro-form__control">
|
|
20
|
+
<div class="pro-form__input">
|
|
21
|
+
<ProFormItem :field="field" :model="model">
|
|
22
|
+
<template v-for="slotName in slotNames" #[slotName]="slotScope">
|
|
23
|
+
<slot :name="slotName" v-bind="slotScope" />
|
|
24
|
+
</template>
|
|
25
|
+
</ProFormItem>
|
|
26
|
+
</div>
|
|
27
|
+
<slot
|
|
28
|
+
v-if="field.suffixSlotName && field.component !== 'input'"
|
|
29
|
+
:name="field.suffixSlotName"
|
|
30
|
+
:model="model"
|
|
31
|
+
:field="field"
|
|
32
|
+
/>
|
|
33
|
+
</div>
|
|
24
34
|
</el-form-item>
|
|
25
35
|
</el-col>
|
|
26
36
|
</template>
|
|
@@ -104,6 +114,18 @@ defineExpose({
|
|
|
104
114
|
</script>
|
|
105
115
|
|
|
106
116
|
<style scoped lang="scss">
|
|
117
|
+
.pro-form__control {
|
|
118
|
+
display: flex;
|
|
119
|
+
align-items: flex-start;
|
|
120
|
+
gap: 8px;
|
|
121
|
+
width: 100%;
|
|
122
|
+
min-width: 0;
|
|
123
|
+
}
|
|
124
|
+
.pro-form__input {
|
|
125
|
+
flex: 1;
|
|
126
|
+
min-width: 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
107
129
|
.pro-form__row-break {
|
|
108
130
|
flex: 0 0 100%;
|
|
109
131
|
height: 0;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import "./vite-env.d.ts";
|
|
2
|
+
import "./typings/global.d.ts";
|
|
3
|
+
import "./typings/utils.d.ts";
|
|
4
|
+
import "../types/generated/auto-imports.d.ts";
|
|
5
|
+
import "../types/generated/components.d.ts";
|
|
6
6
|
|
|
7
7
|
export * from "./modules";
|
|
8
8
|
export * from "./locales";
|
|
@@ -174,6 +174,7 @@
|
|
|
174
174
|
"core.login.tenant_code": "Enter tenant code",
|
|
175
175
|
"core.login.user_name": "Enter username",
|
|
176
176
|
"core.login.welcome": "Welcome to the admin console",
|
|
177
|
+
"core.login.mfa_remember_device": "Skip verification on this device for {days} days",
|
|
177
178
|
"core.login.mfa_title": "Multi-factor authentication",
|
|
178
179
|
"core.login.mfa_code": "Enter the authenticator code",
|
|
179
180
|
"core.login.mfa_recovery_code": "Recovery code (optional)",
|
|
@@ -331,5 +332,7 @@
|
|
|
331
332
|
"common.value.top_level": "Top level",
|
|
332
333
|
"common.resource.default": "{resource}",
|
|
333
334
|
"common.action.delete_resource": "Delete {resource}",
|
|
334
|
-
"common.action.set_field_status": "Set {field}"
|
|
335
|
+
"common.action.set_field_status": "Set {field}",
|
|
336
|
+
"core.home.demo_scope": "Overview",
|
|
337
|
+
"core.home.main_title": "Admin Application"
|
|
335
338
|
}
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"core.layout.avatar": "ユーザーアバター",
|
|
56
56
|
"core.layout.logo_alt": "システムロゴ",
|
|
57
57
|
"core.login.background_alt": "ログイン画面の背景",
|
|
58
|
+
"core.login.mfa_remember_device": "この端末では{days}日間、追加認証を省略する",
|
|
58
59
|
"core.login.mfa_title": "多要素認証",
|
|
59
60
|
"core.login.mfa_code": "認証コードを入力",
|
|
60
61
|
"core.login.mfa_recovery_code": "リカバリーコード(任意)",
|
|
@@ -331,5 +332,7 @@
|
|
|
331
332
|
"common.value.top_level": "トップレベル",
|
|
332
333
|
"common.resource.default": "{resource}",
|
|
333
334
|
"common.action.delete_resource": "{resource}を削除",
|
|
334
|
-
"common.action.set_field_status": "{field}を設定"
|
|
335
|
+
"common.action.set_field_status": "{field}を設定",
|
|
336
|
+
"core.home.demo_scope": "機能概要",
|
|
337
|
+
"core.home.main_title": "管理アプリケーション"
|
|
335
338
|
}
|
|
@@ -176,6 +176,7 @@
|
|
|
176
176
|
"core.login.welcome": "欢迎登录管理后台",
|
|
177
177
|
"core.login.mfa_title": "多因素认证",
|
|
178
178
|
"core.login.mfa_code": "请输入动态口令",
|
|
179
|
+
"core.login.mfa_remember_device": "{days}天内免验证此设备",
|
|
179
180
|
"core.login.mfa_recovery_code": "恢复码(可选)",
|
|
180
181
|
"core.login.mfa_setup_title": "绑定多因素认证",
|
|
181
182
|
"core.login.mfa_setup_qr_alt": "多因素认证绑定二维码",
|
|
@@ -331,5 +332,7 @@
|
|
|
331
332
|
"common.value.top_level": "顶级节点",
|
|
332
333
|
"common.resource.default": "{resource}",
|
|
333
334
|
"common.action.delete_resource": "删除{resource}",
|
|
334
|
-
"common.action.set_field_status": "设置{field}"
|
|
335
|
+
"common.action.set_field_status": "设置{field}",
|
|
336
|
+
"core.home.demo_scope": "功能概览",
|
|
337
|
+
"core.home.main_title": "管理应用"
|
|
335
338
|
}
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"core.layout.avatar": "使用者頭像",
|
|
56
56
|
"core.layout.logo_alt": "系統標誌",
|
|
57
57
|
"core.login.background_alt": "登入頁背景",
|
|
58
|
+
"core.login.mfa_remember_device": "{days}天內免驗證此裝置",
|
|
58
59
|
"core.login.mfa_title": "多因素認證",
|
|
59
60
|
"core.login.mfa_code": "請輸入動態密碼",
|
|
60
61
|
"core.login.mfa_recovery_code": "恢復碼(可選)",
|
|
@@ -331,5 +332,7 @@
|
|
|
331
332
|
"common.value.top_level": "頂級節點",
|
|
332
333
|
"common.resource.default": "{resource}",
|
|
333
334
|
"common.action.delete_resource": "刪除{resource}",
|
|
334
|
-
"common.action.set_field_status": "設定{field}"
|
|
335
|
+
"common.action.set_field_status": "設定{field}",
|
|
336
|
+
"core.home.demo_scope": "功能概覽",
|
|
337
|
+
"core.home.main_title": "管理應用程式"
|
|
335
338
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
2
|
// versions:
|
|
3
|
-
// protoc-gen-ts_proto v2.
|
|
3
|
+
// protoc-gen-ts_proto v2.11.8
|
|
4
4
|
// protoc unknown
|
|
5
5
|
// source: base/v1/language.proto
|
|
6
6
|
|
|
@@ -24,7 +24,7 @@ export interface OptionLanguageResponse {
|
|
|
24
24
|
languages: LanguageItem[];
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/** 语言公共服务。 */
|
|
27
|
+
/** Base语言公共服务。 */
|
|
28
28
|
export interface LanguageService {
|
|
29
29
|
/** 查询当前支持的语言选项。 */
|
|
30
30
|
OptionLanguage(request: OptionLanguageRequest): Promise<OptionLanguageResponse>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
2
|
// versions:
|
|
3
|
-
// protoc-gen-ts_proto v2.
|
|
3
|
+
// protoc-gen-ts_proto v2.11.8
|
|
4
4
|
// protoc unknown
|
|
5
5
|
// source: base/v1/login.proto
|
|
6
6
|
|
|
@@ -155,6 +155,8 @@ export interface LoginResponse {
|
|
|
155
155
|
mfa_method: string;
|
|
156
156
|
/** WebAuthn认证选项JSON */
|
|
157
157
|
mfa_webauthn_options_json: string;
|
|
158
|
+
/** 当前登录策略允许的MFA设备免验证天数 */
|
|
159
|
+
mfa_remember_days: number;
|
|
158
160
|
}
|
|
159
161
|
|
|
160
162
|
/** Base登录公共服务 */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
2
|
// versions:
|
|
3
|
-
// protoc-gen-ts_proto v2.
|
|
3
|
+
// protoc-gen-ts_proto v2.11.8
|
|
4
4
|
// protoc unknown
|
|
5
5
|
// source: base/v1/mfa.proto
|
|
6
6
|
|
|
@@ -19,6 +19,8 @@ export interface VerifyMfaRequest {
|
|
|
19
19
|
recovery_code: string;
|
|
20
20
|
/** WebAuthn认证响应JSON */
|
|
21
21
|
webauthn_response_json: string;
|
|
22
|
+
/** 是否记住当前设备 */
|
|
23
|
+
remember_device: boolean;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
/** 登录强制绑定多因素认证请求。 */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
2
|
// versions:
|
|
3
|
-
// protoc-gen-ts_proto v2.
|
|
3
|
+
// protoc-gen-ts_proto v2.11.8
|
|
4
4
|
// protoc unknown
|
|
5
5
|
// source: base/v1/oauth.proto
|
|
6
6
|
|
|
@@ -109,6 +109,8 @@ export interface CreateOauthSessionResponse {
|
|
|
109
109
|
mfa_method: string;
|
|
110
110
|
/** WebAuthn认证选项JSON */
|
|
111
111
|
mfa_webauthn_options_json: string;
|
|
112
|
+
/** 当前登录策略允许的MFA设备免验证天数 */
|
|
113
|
+
mfa_remember_days: number;
|
|
112
114
|
}
|
|
113
115
|
|
|
114
116
|
/** 三方登录回调请求 */
|
|
@@ -157,6 +159,8 @@ export interface ExchangeOauthTicketResponse {
|
|
|
157
159
|
mfa_method: string;
|
|
158
160
|
/** WebAuthn认证选项JSON */
|
|
159
161
|
mfa_webauthn_options_json: string;
|
|
162
|
+
/** 当前登录策略允许的MFA设备免验证天数 */
|
|
163
|
+
mfa_remember_days: number;
|
|
160
164
|
}
|
|
161
165
|
|
|
162
166
|
/** 个人中心三方账号绑定回调请求 */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
2
|
// versions:
|
|
3
|
-
// protoc-gen-ts_proto v2.
|
|
3
|
+
// protoc-gen-ts_proto v2.11.8
|
|
4
4
|
// protoc unknown
|
|
5
5
|
// source: base/v1/oauth_client.proto
|
|
6
6
|
|
|
@@ -26,7 +26,7 @@ export interface IssueOauthClientTokenResponse {
|
|
|
26
26
|
expires_in: number;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/** 开放授权客户端令牌服务。 */
|
|
29
|
+
/** Base开放授权客户端令牌服务。 */
|
|
30
30
|
export interface OauthClientService {
|
|
31
31
|
/** 使用客户端凭据换取访问令牌。 */
|
|
32
32
|
IssueOauthClientToken(request: IssueOauthClientTokenRequest): Promise<IssueOauthClientTokenResponse>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
2
|
// versions:
|
|
3
|
-
// protoc-gen-ts_proto v2.
|
|
3
|
+
// protoc-gen-ts_proto v2.11.8
|
|
4
4
|
// protoc unknown
|
|
5
5
|
// source: system/admin/v1/base_i18n.proto
|
|
6
6
|
|
|
@@ -85,7 +85,7 @@ export interface CodeGenLocaleConfig {
|
|
|
85
85
|
left_tree_comment: string;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
/** 国际化翻译信息服务。 */
|
|
88
|
+
/** Admin国际化翻译信息服务。 */
|
|
89
89
|
export interface BaseI18nService {
|
|
90
90
|
/** 翻译单个文本。 */
|
|
91
91
|
DraftBaseI18n(request: DraftBaseI18nRequest): Promise<DraftBaseI18nResponse>;
|
|
@@ -63,13 +63,7 @@
|
|
|
63
63
|
<el-icon><CircleClose /></el-icon>
|
|
64
64
|
{{ t("common.action.reset") }}
|
|
65
65
|
</el-button>
|
|
66
|
-
<el-button
|
|
67
|
-
round
|
|
68
|
-
size="large"
|
|
69
|
-
type="primary"
|
|
70
|
-
:loading="loading || oauthTicketLoading"
|
|
71
|
-
@click="handleLogin(loginFormRef)"
|
|
72
|
-
>
|
|
66
|
+
<el-button round size="large" type="primary" :loading="loading || oauthTicketLoading" @click="handleLogin(loginFormRef)">
|
|
73
67
|
<el-icon><UserFilled /></el-icon>
|
|
74
68
|
{{ t("common.action.login") }}
|
|
75
69
|
</el-button>
|
|
@@ -102,11 +96,11 @@
|
|
|
102
96
|
<ProDialog
|
|
103
97
|
v-model="behaviorDialogVisible"
|
|
104
98
|
width="364px"
|
|
105
|
-
|
|
99
|
+
:style="loginDialogStyle"
|
|
106
100
|
:show-close="false"
|
|
107
101
|
:show-footer="false"
|
|
108
102
|
append-to-body
|
|
109
|
-
class="behavior-captcha-dialog"
|
|
103
|
+
class="login-verification-dialog behavior-captcha-dialog"
|
|
110
104
|
>
|
|
111
105
|
<div v-loading="behaviorLoading" class="behavior-captcha-body">
|
|
112
106
|
<GoCaptchaSlide
|
|
@@ -132,7 +126,15 @@
|
|
|
132
126
|
/>
|
|
133
127
|
</div>
|
|
134
128
|
</ProDialog>
|
|
135
|
-
<ProDialog
|
|
129
|
+
<ProDialog
|
|
130
|
+
v-model="mfaDialogVisible"
|
|
131
|
+
:title="t('core.login.mfa_title')"
|
|
132
|
+
width="364px"
|
|
133
|
+
:style="loginDialogStyle"
|
|
134
|
+
class="login-verification-dialog"
|
|
135
|
+
append-to-body
|
|
136
|
+
:close-on-click-modal="false"
|
|
137
|
+
>
|
|
136
138
|
<ProForm
|
|
137
139
|
ref="mfaLoginFormRef"
|
|
138
140
|
:model="mfaLoginForm"
|
|
@@ -142,6 +144,9 @@
|
|
|
142
144
|
label-width="auto"
|
|
143
145
|
@keyup.enter.prevent="verifyMfaLogin"
|
|
144
146
|
/>
|
|
147
|
+
<el-checkbox v-if="mfaRememberDays > 0" v-model="rememberMfaDevice">
|
|
148
|
+
{{ t("core.login.mfa_remember_device", { days: mfaRememberDays }) }}
|
|
149
|
+
</el-checkbox>
|
|
145
150
|
<template #footer>
|
|
146
151
|
<el-button @click="mfaDialogVisible = false">{{ t("common.action.cancel") }}</el-button>
|
|
147
152
|
<el-button type="primary" :loading="mfaLoading" @click="verifyMfaLogin">
|
|
@@ -149,7 +154,15 @@
|
|
|
149
154
|
</el-button>
|
|
150
155
|
</template>
|
|
151
156
|
</ProDialog>
|
|
152
|
-
<ProDialog
|
|
157
|
+
<ProDialog
|
|
158
|
+
v-model="mfaSetupDialogVisible"
|
|
159
|
+
:title="t('core.login.mfa_setup_title')"
|
|
160
|
+
width="520px"
|
|
161
|
+
:style="loginDialogStyle"
|
|
162
|
+
class="login-verification-dialog"
|
|
163
|
+
append-to-body
|
|
164
|
+
:close-on-click-modal="false"
|
|
165
|
+
>
|
|
153
166
|
<template v-if="mfaSetupMethod !== 'webauthn'">
|
|
154
167
|
<MfaSetupPanel :uri="mfaSetupUri" />
|
|
155
168
|
<ProForm
|
|
@@ -172,6 +185,9 @@
|
|
|
172
185
|
<MfaRecoveryCodesDialog
|
|
173
186
|
v-model="recoveryCodesDialogVisible"
|
|
174
187
|
:codes="recoveryCodes"
|
|
188
|
+
:style="loginDialogStyle"
|
|
189
|
+
class="login-verification-dialog"
|
|
190
|
+
append-to-body
|
|
175
191
|
@confirm="finishMfaEnrollment"
|
|
176
192
|
/>
|
|
177
193
|
</template>
|
|
@@ -179,6 +195,7 @@
|
|
|
179
195
|
<script setup lang="ts">
|
|
180
196
|
import { computed, ref, reactive, onMounted, watch } from "vue";
|
|
181
197
|
import { useRoute, useRouter } from "vue-router";
|
|
198
|
+
import { useElementBounding } from "@vueuse/core";
|
|
182
199
|
import { HOME_URL } from "../../../config";
|
|
183
200
|
import { getTimeState } from "../../../utils";
|
|
184
201
|
import { defLoginService } from "../../../api/base/v1/login";
|
|
@@ -207,6 +224,19 @@ import "go-captcha-vue/dist/style.css";
|
|
|
207
224
|
import { useLocaleStore } from "../../../locales";
|
|
208
225
|
import { clearPasswordChangeRequired, handlePasswordChangeRequired } from "../../../utils/request";
|
|
209
226
|
|
|
227
|
+
/** 登录表单属性,验证弹窗以外层登录卡片的中心定位。 */
|
|
228
|
+
interface LoginFormProps {
|
|
229
|
+
dialogAnchor?: HTMLElement;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const props = defineProps<LoginFormProps>();
|
|
233
|
+
const dialogAnchorBounds = useElementBounding(() => props.dialogAnchor);
|
|
234
|
+
const loginDialogStyle = computed(() => ({
|
|
235
|
+
"--login-dialog-center-x": `${dialogAnchorBounds.left.value + dialogAnchorBounds.width.value / 2}px`,
|
|
236
|
+
"--login-dialog-center-y": `${dialogAnchorBounds.top.value + dialogAnchorBounds.height.value / 2}px`,
|
|
237
|
+
"--login-dialog-anchor-width": `${dialogAnchorBounds.width.value}px`
|
|
238
|
+
}));
|
|
239
|
+
|
|
210
240
|
const router = useRouter();
|
|
211
241
|
const route = useRoute();
|
|
212
242
|
const userStore = useUserStore();
|
|
@@ -242,6 +272,8 @@ const mfaChallengeId = ref("");
|
|
|
242
272
|
const mfaLoginFormRef = ref<ProFormInstance>();
|
|
243
273
|
const mfaLoginForm = reactive({ code: "", recoveryCode: "" });
|
|
244
274
|
const mfaMethod = ref("totp");
|
|
275
|
+
const mfaRememberDays = ref(0);
|
|
276
|
+
const rememberMfaDevice = ref(false);
|
|
245
277
|
const mfaWebAuthnOptionsJson = ref("");
|
|
246
278
|
const mfaSetupDialogVisible = ref(false);
|
|
247
279
|
const mfaSetupTicket = ref("");
|
|
@@ -576,6 +608,8 @@ const handleLoginResponse = async (result: LoginResponse) => {
|
|
|
576
608
|
if (result.status === LoginStatus.LOGIN_STATUS_MFA_REQUIRED) {
|
|
577
609
|
mfaChallengeId.value = result.mfa_challenge_id;
|
|
578
610
|
mfaMethod.value = result.mfa_method || "totp";
|
|
611
|
+
mfaRememberDays.value = result.mfa_remember_days || 0;
|
|
612
|
+
rememberMfaDevice.value = false;
|
|
579
613
|
mfaWebAuthnOptionsJson.value = result.mfa_webauthn_options_json || "";
|
|
580
614
|
mfaLoginForm.code = "";
|
|
581
615
|
mfaLoginForm.recoveryCode = "";
|
|
@@ -612,7 +646,8 @@ const verifyMfaLogin = async () => {
|
|
|
612
646
|
challenge_id: mfaChallengeId.value,
|
|
613
647
|
code: useRecoveryCode ? "" : mfaLoginForm.code,
|
|
614
648
|
recovery_code: mfaLoginForm.recoveryCode,
|
|
615
|
-
webauthn_response_json: webauthnResponseJson
|
|
649
|
+
webauthn_response_json: webauthnResponseJson,
|
|
650
|
+
remember_device: rememberMfaDevice.value
|
|
616
651
|
});
|
|
617
652
|
mfaDialogVisible.value = false;
|
|
618
653
|
await handleLoginResponse(result);
|
|
@@ -960,6 +995,25 @@ watch(
|
|
|
960
995
|
color: var(--el-color-primary);
|
|
961
996
|
}
|
|
962
997
|
|
|
998
|
+
/* 各验证步骤共用登录卡片中心;靠近视口边缘时限制尺寸,内容在弹窗内滚动。 */
|
|
999
|
+
:global(.login-verification-dialog.el-dialog) {
|
|
1000
|
+
--login-dialog-width: min(var(--el-dialog-width), var(--login-dialog-anchor-width), calc(100vw - 32px));
|
|
1001
|
+
--login-dialog-y: clamp(25dvh, var(--login-dialog-center-y), 75dvh);
|
|
1002
|
+
|
|
1003
|
+
position: fixed;
|
|
1004
|
+
top: var(--login-dialog-y);
|
|
1005
|
+
left: clamp(
|
|
1006
|
+
calc(var(--login-dialog-width) / 2 + 16px),
|
|
1007
|
+
var(--login-dialog-center-x),
|
|
1008
|
+
calc(100vw - var(--login-dialog-width) / 2 - 16px)
|
|
1009
|
+
);
|
|
1010
|
+
width: var(--login-dialog-width);
|
|
1011
|
+
max-height: calc(min(var(--login-dialog-y), 100dvh - var(--login-dialog-y)) * 2 - 32px);
|
|
1012
|
+
margin: 0;
|
|
1013
|
+
overflow: auto;
|
|
1014
|
+
translate: -50% -50%;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
963
1017
|
:global(.behavior-captcha-dialog) {
|
|
964
1018
|
--go-captcha-theme-text-color: var(--el-text-color-primary);
|
|
965
1019
|
--go-captcha-theme-bg-color: var(--el-bg-color);
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
.login-container {
|
|
2
|
+
box-sizing: border-box;
|
|
3
|
+
width: 100%;
|
|
4
|
+
max-width: 100%;
|
|
5
|
+
overflow-x: hidden;
|
|
2
6
|
height: 100%;
|
|
3
7
|
min-height: 550px;
|
|
4
8
|
background-color: #eeeeee;
|
|
@@ -9,6 +13,8 @@
|
|
|
9
13
|
position: relative;
|
|
10
14
|
box-sizing: border-box;
|
|
11
15
|
display: flex;
|
|
16
|
+
min-width: 0;
|
|
17
|
+
max-width: calc(100% - 32px);
|
|
12
18
|
align-items: center;
|
|
13
19
|
justify-content: space-around;
|
|
14
20
|
width: 96.5%;
|
|
@@ -28,6 +34,9 @@
|
|
|
28
34
|
right: 72px;
|
|
29
35
|
}
|
|
30
36
|
.login-left {
|
|
37
|
+
min-width: 0;
|
|
38
|
+
max-width: 800px;
|
|
39
|
+
flex: 1 1 800px;
|
|
31
40
|
width: 800px;
|
|
32
41
|
margin-right: 10px;
|
|
33
42
|
.login-left-img {
|
|
@@ -36,7 +45,10 @@
|
|
|
36
45
|
}
|
|
37
46
|
}
|
|
38
47
|
.login-form {
|
|
48
|
+
position: relative;
|
|
39
49
|
box-sizing: border-box;
|
|
50
|
+
min-width: 0;
|
|
51
|
+
flex: 0 1 420px;
|
|
40
52
|
width: 420px;
|
|
41
53
|
max-width: 100%;
|
|
42
54
|
padding: 50px 40px 45px;
|
|
@@ -82,7 +94,8 @@
|
|
|
82
94
|
margin-top: 40px;
|
|
83
95
|
white-space: nowrap;
|
|
84
96
|
.el-button {
|
|
85
|
-
width:
|
|
97
|
+
width: calc(50% - 6px);
|
|
98
|
+
min-width: 0;
|
|
86
99
|
}
|
|
87
100
|
}
|
|
88
101
|
}
|
|
@@ -93,11 +106,20 @@
|
|
|
93
106
|
.login-left {
|
|
94
107
|
display: none;
|
|
95
108
|
}
|
|
109
|
+
|
|
110
|
+
.login-container .login-box {
|
|
111
|
+
justify-content: center;
|
|
112
|
+
}
|
|
96
113
|
}
|
|
97
114
|
|
|
98
115
|
@media screen and (width <= 600px) {
|
|
116
|
+
.login-container .login-box {
|
|
117
|
+
max-width: calc(100% - 16px);
|
|
118
|
+
padding: 0 8px;
|
|
119
|
+
}
|
|
120
|
+
|
|
99
121
|
.login-form {
|
|
100
|
-
width:
|
|
122
|
+
width: 100% !important;
|
|
101
123
|
padding: 40px 24px 32px !important;
|
|
102
124
|
.login-logo {
|
|
103
125
|
margin-bottom: 32px !important;
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
<div class="login-left">
|
|
7
7
|
<img class="login-left-img" :src="backgroundUrl" :alt="t('core.login.background_alt')" />
|
|
8
8
|
</div>
|
|
9
|
-
<div class="login-form">
|
|
9
|
+
<div ref="loginFormRef" class="login-form">
|
|
10
10
|
<div ref="loginLogoRef" class="login-logo">
|
|
11
11
|
<img v-show="showLogoIcon" ref="logoIconRef" class="login-icon" :src="logoUrl" alt="" />
|
|
12
12
|
<h2 ref="logoTextRef" class="logo-text" :style="{ fontSize: `${logoFontSize}px` }">{{ projectName }}</h2>
|
|
13
13
|
</div>
|
|
14
|
-
<LoginForm />
|
|
14
|
+
<LoginForm :dialog-anchor="loginFormRef" />
|
|
15
15
|
</div>
|
|
16
16
|
</div>
|
|
17
17
|
</div>
|
|
@@ -36,6 +36,7 @@ const PREFERRED_MIN_LOGO_FONT_SIZE = 30;
|
|
|
36
36
|
const MIN_LOGO_FONT_SIZE = 8;
|
|
37
37
|
const LOGO_TEXT_GAP = 16;
|
|
38
38
|
|
|
39
|
+
const loginFormRef = ref<HTMLElement>();
|
|
39
40
|
const loginLogoRef = ref<HTMLElement>();
|
|
40
41
|
const logoIconRef = ref<HTMLImageElement>();
|
|
41
42
|
const logoTextRef = ref<HTMLElement>();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liujitcn/kratos-admin-core",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.40",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "kratos-admin frontend runtime and base modules",
|
|
7
7
|
"author": {
|
|
@@ -224,7 +224,7 @@
|
|
|
224
224
|
"scripts": {
|
|
225
225
|
"build": "pnpm build:package",
|
|
226
226
|
"build:package": "node ../../scripts/build-package.mjs .",
|
|
227
|
-
"test": "tsc -p tsconfig.test.json && node --test dist/test/tests/modules.test.js dist/test/tests/dict.test.js dist/test/tests/menu.test.js",
|
|
227
|
+
"test": "tsc -p tsconfig.test.json && node --test dist/test/tests/modules.test.js dist/test/tests/dict.test.js dist/test/tests/menu.test.js dist/test/tests/source-patterns.test.js",
|
|
228
228
|
"type:check": "vue-tsc --noEmit --skipLibCheck"
|
|
229
229
|
}
|
|
230
230
|
}
|
package/vite.config.ts
CHANGED
|
@@ -8,6 +8,7 @@ import dayjs from "dayjs";
|
|
|
8
8
|
import { wrapperEnv } from "./build/getEnv";
|
|
9
9
|
import { createProxy } from "./build/proxy";
|
|
10
10
|
import { createVitePlugins } from "./build/plugins";
|
|
11
|
+
import { createSourcePatterns } from "./build/source-patterns";
|
|
11
12
|
|
|
12
13
|
const coreRoot = dirname(fileURLToPath(import.meta.url));
|
|
13
14
|
const viteLogger = createLogger();
|
|
@@ -52,9 +53,7 @@ export function defineAdminViteConfig(options: AdminViteConfigOptions = {}) {
|
|
|
52
53
|
...resolvePackageSource(root, packageName)
|
|
53
54
|
}));
|
|
54
55
|
const sourceRoots = [resolve(root, "src"), coreSourceRoot, ...modulePackages.map(item => item.sourceRoot)];
|
|
55
|
-
const sourcePatterns =
|
|
56
|
-
sourceRoot => new RegExp(`${escapeRegExp(sourceRoot)}[\\/\\\\].*\\.(?:vue|[jt]sx?)(?:\\?.*)?$`)
|
|
57
|
-
);
|
|
56
|
+
const sourcePatterns = createSourcePatterns(sourceRoots);
|
|
58
57
|
const aliases = [
|
|
59
58
|
{ find: "@", replacement: coreSourceRoot },
|
|
60
59
|
...createPackageAliases(corePackage),
|