@nocobase/portal-template-default 1.0.4 → 1.0.6
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 +77 -0
- package/package.json +23 -17
- package/registry/nocobase-acl/demo/prompt-generator.tsx +6 -39
- package/registry/nocobase-acl/demo/role-switcher-prompt-generator.tsx +6 -42
- package/registry/nocobase-ai/demo/page-context-prompt-generator.tsx +1 -1
- package/registry/nocobase-ai/demo/prompt-card.tsx +7 -28
- package/registry/nocobase-ai/demo/prompt-generator.tsx +9 -30
- package/registry/nocobase-ai/demo/shortcut.tsx +1 -1
- package/registry/nocobase-ai/demo/tool-cards.tsx +10 -30
- package/registry/nocobase-auth-cas/README.md +6 -0
- package/registry/nocobase-auth-cas/cas-sign-in-button.tsx +41 -0
- package/registry/nocobase-auth-cas/demo.tsx +20 -0
- package/registry/nocobase-auth-cas/extension.tsx +46 -0
- package/registry/nocobase-auth-cas/index.ts +1 -0
- package/registry/nocobase-auth-cas/use-cas-sign-in.ts +29 -0
- package/registry/nocobase-auth-dingtalk/README.md +7 -0
- package/registry/nocobase-auth-dingtalk/auto-login-provider.tsx +154 -0
- package/registry/nocobase-auth-dingtalk/demo.tsx +23 -0
- package/registry/nocobase-auth-dingtalk/dingtalk-sign-in-button.tsx +45 -0
- package/registry/nocobase-auth-dingtalk/extension.tsx +55 -0
- package/registry/nocobase-auth-dingtalk/index.ts +4 -0
- package/registry/nocobase-auth-dingtalk/use-dingtalk-sign-in.ts +64 -0
- package/registry/nocobase-auth-ldap/README.md +6 -0
- package/registry/nocobase-auth-ldap/demo.tsx +21 -0
- package/registry/nocobase-auth-ldap/extension.tsx +46 -0
- package/registry/nocobase-auth-ldap/index.ts +1 -0
- package/registry/nocobase-auth-ldap/ldap-sign-in-form.tsx +69 -0
- package/registry/nocobase-auth-ldap/use-ldap-sign-in.ts +5 -0
- package/registry/nocobase-auth-oidc/README.md +11 -0
- package/registry/nocobase-auth-oidc/auto-redirect-provider.tsx +13 -0
- package/registry/nocobase-auth-oidc/demo.tsx +20 -0
- package/registry/nocobase-auth-oidc/extension.tsx +51 -0
- package/registry/nocobase-auth-oidc/index.ts +1 -0
- package/registry/nocobase-auth-oidc/oidc-sign-in-button.tsx +44 -0
- package/registry/nocobase-auth-oidc/use-oidc-sign-in.ts +58 -0
- package/registry/nocobase-auth-saml/README.md +6 -0
- package/registry/nocobase-auth-saml/auto-redirect-provider.tsx +13 -0
- package/registry/nocobase-auth-saml/demo.tsx +20 -0
- package/registry/nocobase-auth-saml/extension.tsx +51 -0
- package/registry/nocobase-auth-saml/index.ts +1 -0
- package/registry/nocobase-auth-saml/saml-sign-in-button.tsx +43 -0
- package/registry/nocobase-auth-saml/use-saml-sign-in.ts +51 -0
- package/registry/nocobase-auth-sms/README.md +7 -0
- package/registry/nocobase-auth-sms/demo.tsx +25 -0
- package/registry/nocobase-auth-sms/extension.tsx +46 -0
- package/registry/nocobase-auth-sms/index.ts +1 -0
- package/registry/nocobase-auth-sms/sms-sign-in-form.tsx +107 -0
- package/registry/nocobase-auth-sms/use-sms-sign-in.ts +88 -0
- package/registry/nocobase-auth-wecom/README.md +6 -0
- package/registry/nocobase-auth-wecom/auto-login-provider.tsx +21 -0
- package/registry/nocobase-auth-wecom/demo.tsx +23 -0
- package/registry/nocobase-auth-wecom/extension.tsx +49 -0
- package/registry/nocobase-auth-wecom/index.ts +1 -0
- package/registry/nocobase-auth-wecom/use-wecom-sign-in.ts +62 -0
- package/registry/nocobase-auth-wecom/wecom-sign-in-button.tsx +70 -0
- package/registry/nocobase-i18n/demo/prompt-generator.tsx +30 -54
- package/registry/nocobase-route-surfaces/demo/prompt-generator.tsx +18 -21
- package/registry.config.json +112 -0
- package/scripts/build-html.mjs +106 -0
- package/src/App.tsx +34 -8
- package/src/app/extension.ts +4 -0
- package/src/app/extensions.tsx +24 -1
- package/src/components/auth/authenticator-adapters.ts +20 -0
- package/src/components/auth/auto-redirect-provider.tsx +84 -0
- package/src/components/auth/basic-sign-in-form.tsx +101 -0
- package/src/components/auth/default-sign-in-page.tsx +20 -0
- package/src/components/auth/demo/auth-demo-page.tsx +236 -0
- package/src/components/auth/demo/auth-demo-prompt-generator.tsx +93 -0
- package/src/components/auth/demo/auth-demo-route.tsx +11 -0
- package/src/components/auth/demo/auth-method-demo.tsx +48 -0
- package/src/components/auth/demo/index.ts +4 -0
- package/src/components/auth/dynamic-sign-in.tsx +191 -0
- package/src/components/auth/forgot-password-form.tsx +13 -5
- package/src/components/auth/index.ts +13 -0
- package/src/components/auth/sign-in-form.tsx +1 -111
- package/src/components/auth/sign-up-form.tsx +14 -37
- package/src/components/auth/types.ts +38 -0
- package/src/components/auth/use-authenticator-sign-in.ts +14 -0
- package/src/components/auth/use-public-authenticators.ts +26 -0
- package/src/components/data-table/data-table-filter.tsx +107 -153
- package/src/components/demo/prompt-output.tsx +71 -0
- package/src/components/ui/alert-dialog.tsx +2 -0
- package/src/components/ui/attachment.tsx +207 -0
- package/src/components/ui/bubble.tsx +128 -0
- package/src/components/ui/button-group.tsx +87 -0
- package/src/components/ui/button.tsx +6 -6
- package/src/components/ui/calendar.tsx +0 -2
- package/src/components/ui/card.tsx +1 -1
- package/src/components/ui/carousel.tsx +2 -0
- package/src/components/ui/combobox.tsx +297 -0
- package/src/components/ui/command.tsx +43 -41
- package/src/components/ui/dialog.tsx +0 -2
- package/src/components/ui/direction.tsx +4 -0
- package/src/components/ui/drawer.tsx +2 -0
- package/src/components/ui/dropdown-menu.tsx +0 -2
- package/src/components/ui/empty.tsx +104 -0
- package/src/components/ui/field.tsx +238 -0
- package/src/components/ui/hover-card.tsx +2 -0
- package/src/components/ui/input-group.tsx +0 -2
- package/src/components/ui/input-otp.tsx +0 -2
- package/src/components/ui/input.tsx +1 -1
- package/src/components/ui/item.tsx +201 -0
- package/src/components/ui/kbd.tsx +26 -0
- package/src/components/ui/label.tsx +2 -0
- package/src/components/ui/marker.tsx +71 -0
- package/src/components/ui/message-scroller.tsx +131 -0
- package/src/components/ui/message.tsx +92 -0
- package/src/components/ui/native-select.tsx +61 -0
- package/src/components/ui/popover.tsx +0 -2
- package/src/components/ui/progress.tsx +2 -0
- package/src/components/ui/radio-group.tsx +0 -2
- package/src/components/ui/resizable.tsx +2 -0
- package/src/components/ui/scroll-area.tsx +0 -2
- package/src/components/ui/select.tsx +6 -4
- package/src/components/ui/separator.tsx +0 -2
- package/src/components/ui/sheet.tsx +21 -22
- package/src/components/ui/sidebar.tsx +1 -3
- package/src/components/ui/sonner.tsx +2 -0
- package/src/components/ui/spinner.tsx +10 -0
- package/src/components/ui/switch.tsx +0 -2
- package/src/components/ui/table.tsx +4 -2
- package/src/components/ui/tabs.tsx +0 -2
- package/src/components/ui/textarea.tsx +1 -1
- package/src/components/ui/toggle-group.tsx +2 -0
- package/src/components/ui/toggle.tsx +2 -0
- package/src/components/ui/tooltip.tsx +0 -2
- package/src/index.tsx +3 -0
- package/src/lib/nocobase/client.ts +32 -2
- package/src/lib/utils.ts +2 -1
- package/src/locales/en-US.ts +4 -2
- package/src/locales/zh-CN.ts +4 -2
- package/src/pages/login/index.tsx +2 -2
- package/src/pages/users/list.tsx +144 -16
- package/src/providers/auth-callback.ts +21 -0
- package/src/providers/auth.ts +108 -22
- package/src/providers/constants.ts +4 -1
- package/src/providers/runtime-config.ts +19 -0
- package/src/vite-env.d.ts +5 -0
- package/vite.config.ts +55 -2
package/src/providers/auth.ts
CHANGED
|
@@ -25,6 +25,10 @@ type NocoBaseSignInResponse = {
|
|
|
25
25
|
user?: NocoBaseUser;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
+
type NocoBaseSignOutResponse = {
|
|
29
|
+
redirect?: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
28
32
|
type CurrentUserCache = {
|
|
29
33
|
token: string;
|
|
30
34
|
user: NocoBaseUser;
|
|
@@ -77,25 +81,26 @@ const getCurrentUser = async (): Promise<NocoBaseUser> => {
|
|
|
77
81
|
};
|
|
78
82
|
|
|
79
83
|
export const authProvider: AuthProvider = {
|
|
80
|
-
login: async (
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
login: async (params) => {
|
|
85
|
+
const {
|
|
86
|
+
authenticator = nocobaseClient.getAuthenticator(),
|
|
87
|
+
username,
|
|
88
|
+
email,
|
|
89
|
+
redirectTo = "/",
|
|
90
|
+
...values
|
|
91
|
+
} = params ?? {};
|
|
92
|
+
const account = values.account ?? username ?? email;
|
|
93
|
+
const body = {
|
|
94
|
+
...values,
|
|
95
|
+
...(account ? { account } : {}),
|
|
96
|
+
};
|
|
91
97
|
|
|
92
|
-
|
|
93
|
-
if (!account || !password) {
|
|
98
|
+
if (Object.keys(body).length === 0) {
|
|
94
99
|
return {
|
|
95
100
|
success: false,
|
|
96
101
|
error: {
|
|
97
102
|
name: "LoginError",
|
|
98
|
-
message: "Please enter your
|
|
103
|
+
message: "Please enter your sign-in details.",
|
|
99
104
|
},
|
|
100
105
|
};
|
|
101
106
|
}
|
|
@@ -106,8 +111,8 @@ export const authProvider: AuthProvider = {
|
|
|
106
111
|
"signIn",
|
|
107
112
|
{
|
|
108
113
|
method: "POST",
|
|
109
|
-
|
|
110
|
-
body
|
|
114
|
+
authenticator,
|
|
115
|
+
body,
|
|
111
116
|
}
|
|
112
117
|
);
|
|
113
118
|
if (!result.token) {
|
|
@@ -120,11 +125,12 @@ export const authProvider: AuthProvider = {
|
|
|
120
125
|
};
|
|
121
126
|
}
|
|
122
127
|
|
|
128
|
+
nocobaseClient.setAuthenticator(authenticator);
|
|
123
129
|
nocobaseClient.setToken(result.token);
|
|
124
130
|
nocobaseClient.setRole(null);
|
|
125
131
|
clearCurrentUserCache();
|
|
126
132
|
clearAcl();
|
|
127
|
-
return { success: true, redirectTo
|
|
133
|
+
return { success: true, redirectTo };
|
|
128
134
|
} catch (error) {
|
|
129
135
|
return {
|
|
130
136
|
success: false,
|
|
@@ -140,23 +146,101 @@ export const authProvider: AuthProvider = {
|
|
|
140
146
|
}
|
|
141
147
|
},
|
|
142
148
|
|
|
149
|
+
register: async (params) => {
|
|
150
|
+
const {
|
|
151
|
+
authenticator = nocobaseClient.getAuthenticator(),
|
|
152
|
+
redirectTo = "/login",
|
|
153
|
+
...values
|
|
154
|
+
} = params ?? {};
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
await nocobaseClient.action("auth", "signUp", {
|
|
158
|
+
method: "POST",
|
|
159
|
+
authenticator,
|
|
160
|
+
body: values,
|
|
161
|
+
});
|
|
162
|
+
return {
|
|
163
|
+
success: true,
|
|
164
|
+
redirectTo,
|
|
165
|
+
successNotification: {
|
|
166
|
+
message: "Account created",
|
|
167
|
+
description: "You can now sign in with your new account.",
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
} catch (error) {
|
|
171
|
+
return {
|
|
172
|
+
success: false,
|
|
173
|
+
error: {
|
|
174
|
+
name: "RegistrationError",
|
|
175
|
+
message: getErrorMessage(error, "Unable to create the account."),
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
forgotPassword: async (params) => {
|
|
182
|
+
const {
|
|
183
|
+
authenticator = nocobaseClient.getAuthenticator(),
|
|
184
|
+
...values
|
|
185
|
+
} = params ?? {};
|
|
186
|
+
const baseURL =
|
|
187
|
+
typeof window === "undefined"
|
|
188
|
+
? undefined
|
|
189
|
+
: window.location.href.split("/forgot-password")[0];
|
|
190
|
+
|
|
191
|
+
try {
|
|
192
|
+
await nocobaseClient.action("auth", "lostPassword", {
|
|
193
|
+
method: "POST",
|
|
194
|
+
authenticator,
|
|
195
|
+
body: { ...values, baseURL },
|
|
196
|
+
});
|
|
197
|
+
return {
|
|
198
|
+
success: true,
|
|
199
|
+
successNotification: {
|
|
200
|
+
message: "Reset link sent",
|
|
201
|
+
description: "Check your inbox for password reset instructions.",
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
} catch (error) {
|
|
205
|
+
return {
|
|
206
|
+
success: false,
|
|
207
|
+
error: {
|
|
208
|
+
name: "PasswordResetError",
|
|
209
|
+
message: getErrorMessage(error, "Unable to send the reset link."),
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
|
|
143
215
|
logout: async () => {
|
|
144
216
|
const token = nocobaseClient.getToken();
|
|
217
|
+
let redirect: string | undefined;
|
|
145
218
|
try {
|
|
146
219
|
if (token) {
|
|
147
|
-
await nocobaseClient.action(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
220
|
+
const result = await nocobaseClient.action<NocoBaseSignOutResponse>(
|
|
221
|
+
"auth",
|
|
222
|
+
"signOut",
|
|
223
|
+
{
|
|
224
|
+
method: "POST",
|
|
225
|
+
token,
|
|
226
|
+
includeAuthenticator: true,
|
|
227
|
+
}
|
|
228
|
+
);
|
|
229
|
+
redirect = result?.redirect;
|
|
152
230
|
}
|
|
153
231
|
} finally {
|
|
154
232
|
nocobaseClient.setToken(null);
|
|
233
|
+
nocobaseClient.setAuthenticator(null);
|
|
155
234
|
nocobaseClient.setRole(null);
|
|
156
235
|
clearCurrentUserCache();
|
|
157
236
|
clearAcl();
|
|
158
237
|
}
|
|
159
238
|
|
|
239
|
+
if (redirect && typeof window !== "undefined") {
|
|
240
|
+
window.location.assign(nocobaseClient.resolveUrl(redirect));
|
|
241
|
+
return { success: true };
|
|
242
|
+
}
|
|
243
|
+
|
|
160
244
|
return { success: true, redirectTo: "/login" };
|
|
161
245
|
},
|
|
162
246
|
|
|
@@ -166,6 +250,7 @@ export const authProvider: AuthProvider = {
|
|
|
166
250
|
return { authenticated: true };
|
|
167
251
|
} catch {
|
|
168
252
|
nocobaseClient.setToken(null);
|
|
253
|
+
nocobaseClient.setAuthenticator(null);
|
|
169
254
|
nocobaseClient.setRole(null);
|
|
170
255
|
clearCurrentUserCache();
|
|
171
256
|
clearAcl();
|
|
@@ -207,6 +292,7 @@ export const authProvider: AuthProvider = {
|
|
|
207
292
|
|
|
208
293
|
if (status === 401) {
|
|
209
294
|
nocobaseClient.setToken(null);
|
|
295
|
+
nocobaseClient.setAuthenticator(null);
|
|
210
296
|
nocobaseClient.setRole(null);
|
|
211
297
|
clearCurrentUserCache();
|
|
212
298
|
clearAcl();
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { getRuntimeApiUrl } from "./runtime-config";
|
|
2
|
+
|
|
1
3
|
const rawApiUrl =
|
|
2
|
-
|
|
4
|
+
getRuntimeApiUrl() ?? "http://127.0.0.1:13000/api";
|
|
3
5
|
|
|
4
6
|
const getDefaultProxyTarget = (apiUrl?: string) => {
|
|
5
7
|
if (!apiUrl || apiUrl.startsWith("/")) return undefined;
|
|
@@ -35,6 +37,7 @@ const toProxyRelativeUrl = (url: string, target?: string) => {
|
|
|
35
37
|
export const API_URL = toProxyRelativeUrl(rawApiUrl, proxyTarget);
|
|
36
38
|
export const API_ORIGIN = getDefaultProxyTarget(rawApiUrl);
|
|
37
39
|
export const NOCOBASE_TOKEN_KEY = "nocobase-auth-token";
|
|
40
|
+
export const NOCOBASE_AUTHENTICATOR_KEY = "nocobase-authenticator";
|
|
38
41
|
export const NOCOBASE_ROLE_KEY = "nocobase-auth-role";
|
|
39
42
|
export const NOCOBASE_LOCALE_KEY = "nocobase-locale";
|
|
40
43
|
export const NOCOBASE_AUTHENTICATOR =
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const getWindowValue = (key: "NOCOBASE_PORTAL_BASE" | "NOCOBASE_API_URL") => {
|
|
2
|
+
if (typeof window === "undefined") return undefined;
|
|
3
|
+
const value = window[key];
|
|
4
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const normalizePortalBase = (base?: string) => {
|
|
8
|
+
const normalized = String(base || "/").trim();
|
|
9
|
+
if (!normalized || normalized === "/") return "/";
|
|
10
|
+
return `/${normalized.replace(/^\/+|\/+$/g, "")}/`;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const getPortalBase = () =>
|
|
14
|
+
normalizePortalBase(
|
|
15
|
+
getWindowValue("NOCOBASE_PORTAL_BASE") ?? import.meta.env.BASE_URL
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
export const getRuntimeApiUrl = () =>
|
|
19
|
+
getWindowValue("NOCOBASE_API_URL") ?? import.meta.env.NOCOBASE_API_URL;
|
package/src/vite-env.d.ts
CHANGED
package/vite.config.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import tailwindcss from "@tailwindcss/vite";
|
|
2
2
|
import react from "@vitejs/plugin-react";
|
|
3
|
+
import fs from "node:fs";
|
|
3
4
|
import path from "path";
|
|
4
5
|
import { defineConfig, loadEnv } from "vite";
|
|
5
6
|
|
|
@@ -30,6 +31,56 @@ const normalizeBase = (base?: string) => {
|
|
|
30
31
|
return `/${normalized.replace(/^\/+|\/+$/g, "")}/`;
|
|
31
32
|
};
|
|
32
33
|
|
|
34
|
+
const getBasePrefix = (base: string) => base.replace(/\/$/, "");
|
|
35
|
+
|
|
36
|
+
const defaultRuntimeConfig = `<!-- nocobase-runtime-config:start -->
|
|
37
|
+
<script>
|
|
38
|
+
window.NOCOBASE_PORTAL_BASE = "/";
|
|
39
|
+
window.NOCOBASE_API_URL = "/api";
|
|
40
|
+
</script>
|
|
41
|
+
<!-- nocobase-runtime-config:end -->
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
const stripBaseFromIndexHtml = (html: string, base: string) => {
|
|
45
|
+
const basePrefix = getBasePrefix(base);
|
|
46
|
+
if (!basePrefix) return html;
|
|
47
|
+
|
|
48
|
+
const attributePattern = /\b(src|href|content)=(["'])\/(?!\/)([^"']*)\2/g;
|
|
49
|
+
|
|
50
|
+
return html.replace(attributePattern, (match, attribute, quote, path) => {
|
|
51
|
+
const value = `/${path}`;
|
|
52
|
+
if (!value.startsWith(`${basePrefix}/`)) return match;
|
|
53
|
+
return `${attribute}=${quote}${value.slice(basePrefix.length) || "/"}${quote}`;
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const copyRawIndexHtmlPlugin = (base: string) => ({
|
|
58
|
+
name: "copy-raw-index-html",
|
|
59
|
+
closeBundle() {
|
|
60
|
+
const distDir = path.resolve(__dirname, "dist");
|
|
61
|
+
const indexHtml = path.join(distDir, "index.html");
|
|
62
|
+
const rawIndexHtml = path.join(distDir, "index.raw.html");
|
|
63
|
+
|
|
64
|
+
if (fs.existsSync(indexHtml)) {
|
|
65
|
+
const html = fs.readFileSync(indexHtml, "utf8");
|
|
66
|
+
const rawHtml = stripBaseFromIndexHtml(html, base);
|
|
67
|
+
const moduleScriptPattern =
|
|
68
|
+
/<script\s+[^>]*type=["']module["'][^>]*>/i;
|
|
69
|
+
const moduleScriptMatch = rawHtml.match(moduleScriptPattern);
|
|
70
|
+
|
|
71
|
+
if (moduleScriptMatch?.index === undefined) {
|
|
72
|
+
fs.writeFileSync(rawIndexHtml, rawHtml);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fs.writeFileSync(
|
|
77
|
+
rawIndexHtml,
|
|
78
|
+
`${rawHtml.slice(0, moduleScriptMatch.index)}${defaultRuntimeConfig}${rawHtml.slice(moduleScriptMatch.index)}`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
33
84
|
// https://vite.dev/config/
|
|
34
85
|
export default defineConfig(({ mode }) => {
|
|
35
86
|
const env = loadEnv(mode, process.cwd(), "");
|
|
@@ -44,10 +95,12 @@ export default defineConfig(({ mode }) => {
|
|
|
44
95
|
})()
|
|
45
96
|
: undefined;
|
|
46
97
|
|
|
98
|
+
const portalBase = normalizeBase(env.NOCOBASE_PORTAL_BASE);
|
|
99
|
+
|
|
47
100
|
return {
|
|
48
|
-
base:
|
|
101
|
+
base: portalBase,
|
|
49
102
|
envPrefix: ["VITE_", "NOCOBASE_"],
|
|
50
|
-
plugins: [react(), tailwindcss()],
|
|
103
|
+
plugins: [react(), tailwindcss(), copyRawIndexHtmlPlugin(portalBase)],
|
|
51
104
|
resolve: {
|
|
52
105
|
alias: {
|
|
53
106
|
"@": path.resolve(__dirname, "./src"),
|