adminforth 1.3.54-next.9 → 1.3.55-next.0
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/dist/auth.d.ts +31 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +42 -56
- package/dist/auth.js.map +1 -0
- package/dist/basePlugin.d.ts +18 -0
- package/dist/basePlugin.d.ts.map +1 -0
- package/dist/basePlugin.js +1 -0
- package/dist/basePlugin.js.map +1 -0
- package/dist/dataConnectors/baseConnector.d.ts +94 -0
- package/dist/dataConnectors/baseConnector.d.ts.map +1 -0
- package/dist/dataConnectors/baseConnector.js +108 -122
- package/dist/dataConnectors/baseConnector.js.map +1 -0
- package/dist/dataConnectors/clickhouse.d.ts +92 -0
- package/dist/dataConnectors/clickhouse.d.ts.map +1 -0
- package/dist/dataConnectors/clickhouse.js +132 -149
- package/dist/dataConnectors/clickhouse.js.map +1 -0
- package/dist/dataConnectors/mongo.d.ts +93 -0
- package/dist/dataConnectors/mongo.d.ts.map +1 -0
- package/dist/dataConnectors/mongo.js +75 -101
- package/dist/dataConnectors/mongo.js.map +1 -0
- package/dist/dataConnectors/postgres.d.ts +71 -0
- package/dist/dataConnectors/postgres.d.ts.map +1 -0
- package/dist/dataConnectors/postgres.js +124 -143
- package/dist/dataConnectors/postgres.js.map +1 -0
- package/dist/dataConnectors/sqlite.d.ts +67 -0
- package/dist/dataConnectors/sqlite.d.ts.map +1 -0
- package/dist/dataConnectors/sqlite.js +113 -130
- package/dist/dataConnectors/sqlite.js.map +1 -0
- package/dist/index.d.ts +92 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +197 -217
- package/dist/index.js.map +1 -0
- package/dist/modules/codeInjector.d.ts +35 -0
- package/dist/modules/codeInjector.d.ts.map +1 -0
- package/dist/modules/codeInjector.js +480 -486
- package/dist/modules/codeInjector.js.map +1 -0
- package/dist/modules/configValidator.d.ts +12 -0
- package/dist/modules/configValidator.d.ts.map +1 -0
- package/dist/modules/configValidator.js +31 -22
- package/dist/modules/configValidator.js.map +1 -0
- package/dist/modules/operationalResource.d.ts +17 -0
- package/dist/modules/operationalResource.d.ts.map +1 -0
- package/dist/modules/operationalResource.js +50 -70
- package/dist/modules/operationalResource.js.map +1 -0
- package/dist/modules/restApi.d.ts +10 -0
- package/dist/modules/restApi.d.ts.map +1 -0
- package/dist/modules/restApi.js +104 -116
- package/dist/modules/restApi.js.map +1 -0
- package/dist/modules/styleGenerator.d.ts +9 -0
- package/dist/modules/styleGenerator.d.ts.map +1 -0
- package/dist/modules/styleGenerator.js +1 -0
- package/dist/modules/styleGenerator.js.map +1 -0
- package/dist/modules/styles.d.ts +96 -0
- package/dist/modules/styles.d.ts.map +1 -0
- package/dist/modules/styles.js +1 -0
- package/dist/modules/styles.js.map +1 -0
- package/dist/modules/utils.d.ts +39 -0
- package/dist/modules/utils.d.ts.map +1 -0
- package/dist/modules/utils.js +1 -0
- package/dist/modules/utils.js.map +1 -0
- package/dist/plugins/audit-log/types.d.ts +35 -0
- package/dist/plugins/audit-log/types.d.ts.map +1 -0
- package/dist/plugins/audit-log/types.js +2 -0
- package/dist/plugins/audit-log/types.js.map +1 -0
- package/dist/plugins/chat-gpt/types.d.ts +82 -0
- package/dist/plugins/chat-gpt/types.d.ts.map +1 -0
- package/dist/plugins/chat-gpt/types.js +2 -0
- package/dist/plugins/chat-gpt/types.js.map +1 -0
- package/dist/plugins/email-password-reset/types.d.ts +28 -0
- package/dist/plugins/email-password-reset/types.d.ts.map +1 -0
- package/dist/plugins/email-password-reset/types.js +2 -0
- package/dist/plugins/email-password-reset/types.js.map +1 -0
- package/dist/plugins/foreign-inline-list/types.d.ts +19 -0
- package/dist/plugins/foreign-inline-list/types.d.ts.map +1 -0
- package/dist/plugins/foreign-inline-list/types.js +2 -0
- package/dist/plugins/foreign-inline-list/types.js.map +1 -0
- package/dist/plugins/import-export/types.d.ts +3 -0
- package/dist/plugins/import-export/types.d.ts.map +1 -0
- package/dist/plugins/import-export/types.js +2 -0
- package/dist/plugins/import-export/types.js.map +1 -0
- package/dist/plugins/rich-editor/custom/async-queue.d.ts +8 -0
- package/dist/plugins/rich-editor/custom/async-queue.d.ts.map +1 -0
- package/dist/plugins/rich-editor/custom/async-queue.js +29 -0
- package/dist/plugins/rich-editor/custom/async-queue.js.map +1 -0
- package/dist/plugins/rich-editor/dist/custom/async-queue.d.ts +8 -0
- package/dist/plugins/rich-editor/dist/custom/async-queue.d.ts.map +1 -0
- package/dist/plugins/rich-editor/dist/custom/async-queue.js +29 -0
- package/dist/plugins/rich-editor/dist/custom/async-queue.js.map +1 -0
- package/dist/plugins/rich-editor/types.d.ts +153 -0
- package/dist/plugins/rich-editor/types.d.ts.map +1 -0
- package/dist/plugins/rich-editor/types.js +16 -0
- package/dist/plugins/rich-editor/types.js.map +1 -0
- package/dist/plugins/two-factors-auth/types.d.ts +18 -0
- package/dist/plugins/two-factors-auth/types.d.ts.map +1 -0
- package/dist/plugins/two-factors-auth/types.js +2 -0
- package/dist/plugins/two-factors-auth/types.js.map +1 -0
- package/dist/plugins/upload/types.d.ts +132 -0
- package/dist/plugins/upload/types.d.ts.map +1 -0
- package/dist/plugins/upload/types.js +2 -0
- package/dist/plugins/upload/types.js.map +1 -0
- package/dist/servers/express.d.ts +18 -0
- package/dist/servers/express.d.ts.map +1 -0
- package/dist/servers/express.js +30 -42
- package/dist/servers/express.js.map +1 -0
- package/dist/types/AdminForthConfig.d.ts +1619 -0
- package/dist/types/AdminForthConfig.d.ts.map +1 -0
- package/dist/types/AdminForthConfig.js +1 -0
- package/dist/types/AdminForthConfig.js.map +1 -0
- package/{types/FrontendAPI.ts → dist/types/FrontendAPI.d.ts} +27 -52
- package/dist/types/FrontendAPI.d.ts.map +1 -0
- package/dist/types/FrontendAPI.js +1 -0
- package/dist/types/FrontendAPI.js.map +1 -0
- package/package.json +15 -5
- package/auth.ts +0 -140
- package/basePlugin.ts +0 -70
- package/dataConnectors/baseConnector.ts +0 -216
- package/dataConnectors/clickhouse.ts +0 -338
- package/dataConnectors/mongo.ts +0 -202
- package/dataConnectors/postgres.ts +0 -306
- package/dataConnectors/sqlite.ts +0 -254
- package/dist/spa/.eslintrc.cjs +0 -14
- package/dist/spa/README.md +0 -39
- package/dist/spa/env.d.ts +0 -1
- package/dist/spa/index.html +0 -23
- package/dist/spa/package-lock.json +0 -4573
- package/dist/spa/package.json +0 -49
- package/dist/spa/postcss.config.js +0 -6
- package/dist/spa/public/assets/favicon.png +0 -0
- package/dist/spa/src/App.vue +0 -314
- package/dist/spa/src/assets/base.css +0 -2
- package/dist/spa/src/assets/logo.svg +0 -19
- package/dist/spa/src/components/AcceptModal.vue +0 -45
- package/dist/spa/src/components/Breadcrumbs.vue +0 -41
- package/dist/spa/src/components/BreadcrumbsWithButtons.vue +0 -26
- package/dist/spa/src/components/CustomDatePicker.vue +0 -176
- package/dist/spa/src/components/CustomDateRangePicker.vue +0 -218
- package/dist/spa/src/components/CustomRangePicker.vue +0 -152
- package/dist/spa/src/components/Dropdown.vue +0 -168
- package/dist/spa/src/components/Filters.vue +0 -222
- package/dist/spa/src/components/HelloWorld.vue +0 -17
- package/dist/spa/src/components/MenuLink.vue +0 -24
- package/dist/spa/src/components/ResourceForm.vue +0 -294
- package/dist/spa/src/components/ResourceListTable.vue +0 -394
- package/dist/spa/src/components/SingleSkeletLoader.vue +0 -13
- package/dist/spa/src/components/SkeleteLoader.vue +0 -23
- package/dist/spa/src/components/Toast.vue +0 -77
- package/dist/spa/src/components/ValueRenderer.vue +0 -66
- package/dist/spa/src/components/icons/IconCalendar.vue +0 -5
- package/dist/spa/src/components/icons/IconCommunity.vue +0 -7
- package/dist/spa/src/components/icons/IconDocumentation.vue +0 -7
- package/dist/spa/src/components/icons/IconEcosystem.vue +0 -7
- package/dist/spa/src/components/icons/IconSupport.vue +0 -7
- package/dist/spa/src/components/icons/IconTime.vue +0 -5
- package/dist/spa/src/components/icons/IconTooling.vue +0 -19
- package/dist/spa/src/composables/useFrontendApi.ts +0 -26
- package/dist/spa/src/composables/useStores.ts +0 -127
- package/dist/spa/src/index.scss +0 -27
- package/dist/spa/src/main.ts +0 -18
- package/dist/spa/src/router/index.ts +0 -63
- package/dist/spa/src/spa_types/core.ts +0 -51
- package/dist/spa/src/stores/core.ts +0 -144
- package/dist/spa/src/stores/filters.ts +0 -22
- package/dist/spa/src/stores/modal.ts +0 -48
- package/dist/spa/src/stores/toast.ts +0 -15
- package/dist/spa/src/stores/user.ts +0 -72
- package/dist/spa/src/types/AdminForthConfig.ts +0 -1477
- package/dist/spa/src/types/FrontendAPI.ts +0 -121
- package/dist/spa/src/utils.ts +0 -103
- package/dist/spa/src/views/CreateView.vue +0 -156
- package/dist/spa/src/views/EditView.vue +0 -157
- package/dist/spa/src/views/ListView.vue +0 -258
- package/dist/spa/src/views/LoginView.vue +0 -160
- package/dist/spa/src/views/ResourceParent.vue +0 -17
- package/dist/spa/src/views/ShowView.vue +0 -184
- package/dist/spa/tailwind.config.js +0 -17
- package/dist/spa/tsconfig.app.json +0 -14
- package/dist/spa/tsconfig.json +0 -11
- package/dist/spa/tsconfig.node.json +0 -19
- package/dist/spa/vite.config.ts +0 -56
- package/index.ts +0 -428
- package/modules/codeInjector.ts +0 -736
- package/modules/configValidator.ts +0 -571
- package/modules/operationalResource.ts +0 -98
- package/modules/restApi.ts +0 -718
- package/modules/styleGenerator.ts +0 -55
- package/modules/styles.ts +0 -126
- package/modules/utils.ts +0 -472
- package/servers/express.ts +0 -259
- package/spa/.eslintrc.cjs +0 -14
- package/spa/README.md +0 -39
- package/spa/env.d.ts +0 -1
- package/spa/index.html +0 -23
- package/spa/package-lock.json +0 -4602
- package/spa/package.json +0 -51
- package/spa/postcss.config.js +0 -6
- package/spa/public/assets/favicon.png +0 -0
- package/spa/src/App.vue +0 -418
- package/spa/src/assets/base.css +0 -2
- package/spa/src/assets/logo.svg +0 -19
- package/spa/src/components/AcceptModal.vue +0 -45
- package/spa/src/components/Breadcrumbs.vue +0 -41
- package/spa/src/components/BreadcrumbsWithButtons.vue +0 -26
- package/spa/src/components/CustomDatePicker.vue +0 -176
- package/spa/src/components/CustomDateRangePicker.vue +0 -218
- package/spa/src/components/CustomRangePicker.vue +0 -156
- package/spa/src/components/Dropdown.vue +0 -168
- package/spa/src/components/Filters.vue +0 -222
- package/spa/src/components/HelloWorld.vue +0 -17
- package/spa/src/components/MenuLink.vue +0 -27
- package/spa/src/components/ResourceForm.vue +0 -290
- package/spa/src/components/ResourceListTable.vue +0 -466
- package/spa/src/components/SingleSkeletLoader.vue +0 -13
- package/spa/src/components/SkeleteLoader.vue +0 -23
- package/spa/src/components/ThreeDotsMenu.vue +0 -43
- package/spa/src/components/Toast.vue +0 -78
- package/spa/src/components/ValueRenderer.vue +0 -114
- package/spa/src/components/icons/IconCalendar.vue +0 -5
- package/spa/src/components/icons/IconCommunity.vue +0 -7
- package/spa/src/components/icons/IconDocumentation.vue +0 -7
- package/spa/src/components/icons/IconEcosystem.vue +0 -7
- package/spa/src/components/icons/IconSupport.vue +0 -7
- package/spa/src/components/icons/IconTime.vue +0 -5
- package/spa/src/components/icons/IconTooling.vue +0 -19
- package/spa/src/composables/useFrontendApi.ts +0 -26
- package/spa/src/composables/useStores.ts +0 -131
- package/spa/src/index.scss +0 -31
- package/spa/src/main.ts +0 -18
- package/spa/src/renderers/CompactUUID.vue +0 -48
- package/spa/src/renderers/CountryFlag.vue +0 -69
- package/spa/src/router/index.ts +0 -59
- package/spa/src/spa_types/core.ts +0 -53
- package/spa/src/stores/core.ts +0 -148
- package/spa/src/stores/filters.ts +0 -27
- package/spa/src/stores/modal.ts +0 -48
- package/spa/src/stores/toast.ts +0 -31
- package/spa/src/stores/user.ts +0 -72
- package/spa/src/utils.ts +0 -160
- package/spa/src/views/CreateView.vue +0 -167
- package/spa/src/views/EditView.vue +0 -170
- package/spa/src/views/ListView.vue +0 -352
- package/spa/src/views/LoginView.vue +0 -192
- package/spa/src/views/ResourceParent.vue +0 -17
- package/spa/src/views/ShowView.vue +0 -186
- package/spa/tailwind.config.js +0 -17
- package/spa/tsconfig.app.json +0 -14
- package/spa/tsconfig.json +0 -11
- package/spa/tsconfig.node.json +0 -19
- package/spa/vite.config.ts +0 -56
- package/tsconfig.json +0 -112
- package/types/AdminForthConfig.ts +0 -1762
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { exec, spawn } from 'child_process';
|
|
11
2
|
import crypto from 'crypto';
|
|
12
3
|
import filewatcher from 'filewatcher';
|
|
@@ -38,21 +29,19 @@ function findHomePage(menuItem) {
|
|
|
38
29
|
}
|
|
39
30
|
return undefined;
|
|
40
31
|
}
|
|
41
|
-
function findFirstMenuItemWithResource(menuItem) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return found;
|
|
51
|
-
}
|
|
32
|
+
async function findFirstMenuItemWithResource(menuItem) {
|
|
33
|
+
for (const item of menuItem) {
|
|
34
|
+
if (item.path || item.resourceId) {
|
|
35
|
+
return item;
|
|
36
|
+
}
|
|
37
|
+
if (item.children) {
|
|
38
|
+
const found = await findFirstMenuItemWithResource(item.children);
|
|
39
|
+
if (found) {
|
|
40
|
+
return found;
|
|
52
41
|
}
|
|
53
42
|
}
|
|
54
|
-
|
|
55
|
-
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
56
45
|
}
|
|
57
46
|
const execAsync = promisify(exec);
|
|
58
47
|
function hashify(obj) {
|
|
@@ -88,548 +77,553 @@ class CodeInjector {
|
|
|
88
77
|
// console.timeEnd(`${command} done in`);
|
|
89
78
|
// console.log(`Command ${command} output:`, out, err);
|
|
90
79
|
// }
|
|
91
|
-
runNpmShell(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
env,
|
|
101
|
-
});
|
|
102
|
-
console.timeEnd(`npm ${command} done in`);
|
|
103
|
-
process.env.HEAVY_DEBUG && console.log(`🪲 npm ${command} output:`, out);
|
|
104
|
-
if (err) {
|
|
105
|
-
process.env.HEAVY_DEBUG && console.error(`🪲npm ${command} errors/warnings:`, err);
|
|
106
|
-
}
|
|
80
|
+
async runNpmShell({ command, cwd }) {
|
|
81
|
+
const nodeBinary = process.execPath; // Path to the Node.js binary running this script
|
|
82
|
+
const npmPath = path.join(path.dirname(nodeBinary), 'npm'); // Path to the npm executable
|
|
83
|
+
const env = Object.assign({ VITE_ADMINFORTH_PUBLIC_PATH: this.adminforth.config.baseUrl, FORCE_COLOR: '1' }, process.env);
|
|
84
|
+
console.log(`⚙️ exec: npm ${command}...`);
|
|
85
|
+
console.time(`npm ${command} done in`);
|
|
86
|
+
const { stdout: out, stderr: err } = await execAsync(`${nodeBinary} ${npmPath} ${command}`, {
|
|
87
|
+
cwd,
|
|
88
|
+
env,
|
|
107
89
|
});
|
|
90
|
+
console.timeEnd(`npm ${command} done in`);
|
|
91
|
+
process.env.HEAVY_DEBUG && console.log(`🪲 npm ${command} output:`, out);
|
|
92
|
+
if (err) {
|
|
93
|
+
process.env.HEAVY_DEBUG && console.error(`🪲npm ${command} errors/warnings:`, err);
|
|
94
|
+
}
|
|
108
95
|
}
|
|
109
|
-
rmTmpDir() {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
});
|
|
96
|
+
async rmTmpDir() {
|
|
97
|
+
// remove spa_tmp folder if it is exists
|
|
98
|
+
try {
|
|
99
|
+
await fs.promises.rm(CodeInjector.SPA_TMP_PATH, { recursive: true });
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
// ignore
|
|
103
|
+
}
|
|
119
104
|
}
|
|
120
|
-
packagesFromNpm(dir) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
105
|
+
async packagesFromNpm(dir) {
|
|
106
|
+
const usersPackagePath = path.join(dir, 'package.json');
|
|
107
|
+
let packageContent = null;
|
|
108
|
+
let lockHash = '';
|
|
109
|
+
let packages = [];
|
|
110
|
+
try {
|
|
111
|
+
packageContent = JSON.parse(await fs.promises.readFile(usersPackagePath, 'utf-8'));
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
// user package.json does not exist, user does not have custom components
|
|
115
|
+
}
|
|
116
|
+
if (packageContent) {
|
|
117
|
+
const lockPath = path.join(dir, 'package-lock.json');
|
|
118
|
+
let lock = null;
|
|
126
119
|
try {
|
|
127
|
-
|
|
120
|
+
lock = JSON.parse(await fs.promises.readFile(lockPath, 'utf-8'));
|
|
128
121
|
}
|
|
129
122
|
catch (e) {
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
if (packageContent) {
|
|
133
|
-
const lockPath = path.join(dir, 'package-lock.json');
|
|
134
|
-
let lock = null;
|
|
135
|
-
try {
|
|
136
|
-
lock = JSON.parse(yield fs.promises.readFile(lockPath, 'utf-8'));
|
|
137
|
-
}
|
|
138
|
-
catch (e) {
|
|
139
|
-
throw new Error(`Custom package-lock.json does not exist in ${dir}, but package.json does.
|
|
123
|
+
throw new Error(`Custom package-lock.json does not exist in ${dir}, but package.json does.
|
|
140
124
|
We can't determine version of packages without package-lock.json. Please run npm install in ${dir}`);
|
|
141
|
-
}
|
|
142
|
-
lockHash = hashify(lock);
|
|
143
|
-
packages = [
|
|
144
|
-
...Object.keys(packageContent.dependencies || []),
|
|
145
|
-
...Object.keys(packageContent.devDependencies || [])
|
|
146
|
-
].reduce((acc, packageName) => {
|
|
147
|
-
const pack = lock.packages[`node_modules/${packageName}`];
|
|
148
|
-
if (!pack) {
|
|
149
|
-
throw new Error(`Package ${packageName} is not in package-lock.json but is in package.json. Please run 'npm install' in ${dir}`);
|
|
150
|
-
}
|
|
151
|
-
const version = pack.version;
|
|
152
|
-
acc.push(`${packageName}@${version}`);
|
|
153
|
-
return acc;
|
|
154
|
-
}, []);
|
|
155
125
|
}
|
|
156
|
-
|
|
157
|
-
|
|
126
|
+
lockHash = hashify(lock);
|
|
127
|
+
packages = [
|
|
128
|
+
...Object.keys(packageContent.dependencies || []),
|
|
129
|
+
...Object.keys(packageContent.devDependencies || [])
|
|
130
|
+
].reduce((acc, packageName) => {
|
|
131
|
+
const pack = lock.packages[`node_modules/${packageName}`];
|
|
132
|
+
if (!pack) {
|
|
133
|
+
throw new Error(`Package ${packageName} is not in package-lock.json but is in package.json. Please run 'npm install' in ${dir}`);
|
|
134
|
+
}
|
|
135
|
+
const version = pack.version;
|
|
136
|
+
acc.push(`${packageName}@${version}`);
|
|
137
|
+
return acc;
|
|
138
|
+
}, []);
|
|
139
|
+
}
|
|
140
|
+
return [lockHash, packages];
|
|
158
141
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
142
|
+
getSpaDir() {
|
|
143
|
+
let spaDir = path.join(ADMIN_FORTH_ABSOLUTE_PATH, 'spa');
|
|
144
|
+
if (!fs.existsSync(spaDir)) {
|
|
145
|
+
spaDir = path.join(ADMIN_FORTH_ABSOLUTE_PATH, 'dist', 'spa');
|
|
146
|
+
}
|
|
147
|
+
return spaDir;
|
|
148
|
+
}
|
|
149
|
+
async prepareSources({ filesUpdated }) {
|
|
150
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
151
|
+
// check SPA_TMP_PATH exists and create if not
|
|
152
|
+
try {
|
|
153
|
+
await fs.promises.access(CodeInjector.SPA_TMP_PATH, fs.constants.F_OK);
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
await fs.promises.mkdir(CodeInjector.SPA_TMP_PATH, { recursive: true });
|
|
157
|
+
}
|
|
158
|
+
const icons = [];
|
|
159
|
+
let routes = '';
|
|
160
|
+
let routerComponents = '';
|
|
161
|
+
const collectAssetsFromMenu = (menu) => {
|
|
162
|
+
menu.forEach((item) => {
|
|
163
|
+
var _a, _b, _c, _d;
|
|
164
|
+
if (item.icon) {
|
|
165
|
+
icons.push(item.icon);
|
|
166
|
+
}
|
|
167
|
+
if (item.component) {
|
|
168
|
+
if (Object.keys(item).includes('isStaticRoute')) {
|
|
169
|
+
if (!item.isStaticRoute) {
|
|
170
|
+
routes += `{
|
|
182
171
|
path: '${item.path}',
|
|
183
172
|
name: '${item.path}',
|
|
184
173
|
component: () => import('${item.component}'),
|
|
185
174
|
meta: { title: '${((_a = item === null || item === void 0 ? void 0 : item.meta) === null || _a === void 0 ? void 0 : _a.title) || item.path.replace('/', '')}'}
|
|
186
175
|
},\n`;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
routes += `{
|
|
190
179
|
path: '${item.path}',
|
|
191
180
|
name: '${item.path}',
|
|
192
181
|
component: ${getComponentNameFromPath(item.component)},
|
|
193
182
|
meta: { title: '${((_b = item === null || item === void 0 ? void 0 : item.meta) === null || _b === void 0 ? void 0 : _b.title) || item.path.replace('/', '')}'}
|
|
194
183
|
},\n`;
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
184
|
+
const componentName = `${getComponentNameFromPath(item.component)}`;
|
|
185
|
+
routerComponents += `import ${componentName} from '${item.component}';\n`;
|
|
198
186
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
if (item.homepage) {
|
|
190
|
+
routes += `{
|
|
202
191
|
path: '${item.path}',
|
|
203
192
|
name: '${item.path}',
|
|
204
193
|
component: ${getComponentNameFromPath(item.component)},
|
|
205
194
|
meta: { title: '${((_c = item === null || item === void 0 ? void 0 : item.meta) === null || _c === void 0 ? void 0 : _c.title) || item.path.replace('/', '')}'}
|
|
206
195
|
},\n`;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
196
|
+
const componentName = `${getComponentNameFromPath(item.component)}`;
|
|
197
|
+
routerComponents += `import ${componentName} from '${item.component}';\n`;
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
routes += `{
|
|
212
201
|
path: '${item.path}',
|
|
213
202
|
name: '${item.path}',
|
|
214
203
|
component: () => import('${item.component}'),
|
|
215
204
|
meta: { title: '${((_d = item === null || item === void 0 ? void 0 : item.meta) === null || _d === void 0 ? void 0 : _d.title) || item.path.replace('/', '')}'}
|
|
216
205
|
},\n`;
|
|
217
|
-
}
|
|
218
206
|
}
|
|
219
207
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
208
|
+
}
|
|
209
|
+
if (item.children) {
|
|
210
|
+
collectAssetsFromMenu(item.children);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
};
|
|
214
|
+
const registerCustomPages = (config) => {
|
|
215
|
+
if (config.customization.customPages) {
|
|
216
|
+
config.customization.customPages.forEach((page) => {
|
|
217
|
+
var _a, _b, _c;
|
|
218
|
+
routes += `{
|
|
230
219
|
path: '${page.path}',
|
|
231
220
|
name: '${page.path}',
|
|
232
221
|
component: () => import('${((_a = page === null || page === void 0 ? void 0 : page.component) === null || _a === void 0 ? void 0 : _a.file) || page.component}'),
|
|
233
222
|
meta: ${JSON.stringify(Object.assign(Object.assign({}, (((_b = page === null || page === void 0 ? void 0 : page.component) === null || _b === void 0 ? void 0 : _b.meta) || {})), { title: ((_c = page.meta) === null || _c === void 0 ? void 0 : _c.title) || page.path.replace('/', '') }))}
|
|
234
223
|
},`;
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
|
-
registerCustomPages(this.adminforth.config);
|
|
239
|
-
collectAssetsFromMenu(this.adminforth.config.menu);
|
|
240
|
-
if (filesUpdated) {
|
|
241
|
-
// copy only updated files
|
|
242
|
-
yield Promise.all(filesUpdated.map((file) => __awaiter(this, void 0, void 0, function* () {
|
|
243
|
-
const src = path.join(ADMIN_FORTH_ABSOLUTE_PATH, 'spa', file);
|
|
244
|
-
const dest = path.join(CodeInjector.SPA_TMP_PATH, file);
|
|
245
|
-
// overwrite:true can't be used to not destroy cache
|
|
246
|
-
yield fsExtra.copy(src, dest, {
|
|
247
|
-
dereference: true, // needed to dereference types
|
|
248
|
-
});
|
|
249
|
-
if (process.env.HEAVY_DEBUG) {
|
|
250
|
-
console.log('🪲⚙️ fsExtra.copy copy single file', src, dest);
|
|
251
|
-
}
|
|
252
|
-
})));
|
|
224
|
+
});
|
|
253
225
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
// overwrite can't be used to not destroy cache
|
|
266
|
-
yield fsExtra.copy(path.join(ADMIN_FORTH_ABSOLUTE_PATH, 'spa'), CodeInjector.SPA_TMP_PATH, {
|
|
267
|
-
filter: (src) => {
|
|
268
|
-
const filterPasses = !src.includes('/adminforth/spa/node_modules') && !src.includes('/adminforth/spa/dist');
|
|
269
|
-
if (process.env.HEAVY_DEBUG && !filterPasses) {
|
|
270
|
-
console.log('🪲⚙️ fsExtra.copy filtered out', src);
|
|
271
|
-
}
|
|
272
|
-
return filterPasses;
|
|
273
|
-
},
|
|
226
|
+
};
|
|
227
|
+
registerCustomPages(this.adminforth.config);
|
|
228
|
+
collectAssetsFromMenu(this.adminforth.config.menu);
|
|
229
|
+
const spaDir = this.getSpaDir();
|
|
230
|
+
if (filesUpdated) {
|
|
231
|
+
// copy only updated files
|
|
232
|
+
await Promise.all(filesUpdated.map(async (file) => {
|
|
233
|
+
const src = path.join(spaDir, file);
|
|
234
|
+
const dest = path.join(CodeInjector.SPA_TMP_PATH, file);
|
|
235
|
+
// overwrite:true can't be used to not destroy cache
|
|
236
|
+
await fsExtra.copy(src, dest, {
|
|
274
237
|
dereference: true, // needed to dereference types
|
|
275
238
|
});
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
// resolve customComponentsDir to absolute path, so ./aa will be resolved to /path/to/current/dir/aa
|
|
279
|
-
const customCompAbsPath = path.resolve(this.adminforth.config.customization.customComponentsDir);
|
|
280
|
-
this.srcFoldersToSync[customCompAbsPath] = './';
|
|
281
|
-
}
|
|
282
|
-
// if this.adminforth.config.customization.favicon is set, copy it to assets
|
|
283
|
-
const customFav = (_c = this.adminforth.config.customization) === null || _c === void 0 ? void 0 : _c.favicon;
|
|
284
|
-
if (customFav) {
|
|
285
|
-
const faviconPath = path.join((_d = this.adminforth.config.customization) === null || _d === void 0 ? void 0 : _d.customComponentsDir, customFav.replace('@@/', ''));
|
|
286
|
-
const dest = path.join(CodeInjector.SPA_TMP_PATH, 'public', 'assets', customFav.replace('@@/', ''));
|
|
287
|
-
// make sure all folders in dest exist
|
|
288
|
-
yield fsExtra.ensureDir(path.dirname(dest));
|
|
289
|
-
yield fsExtra.copy(faviconPath, dest);
|
|
239
|
+
if (process.env.HEAVY_DEBUG) {
|
|
240
|
+
console.log('🪲⚙️ fsExtra.copy copy single file', src, dest);
|
|
290
241
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
242
|
+
}));
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
let spaDir = this.getSpaDir();
|
|
246
|
+
if (process.env.HEAVY_DEBUG) {
|
|
247
|
+
console.log(`🪲⚙️ fsExtra.copy from ${spaDir} -> ${CodeInjector.SPA_TMP_PATH}`);
|
|
248
|
+
}
|
|
249
|
+
// try to rm SPA_TMP_PATH/src/types directory
|
|
250
|
+
try {
|
|
251
|
+
await fs.promises.rm(path.join(CodeInjector.SPA_TMP_PATH, 'src', 'types'), { recursive: true });
|
|
252
|
+
}
|
|
253
|
+
catch (e) {
|
|
254
|
+
// ignore
|
|
255
|
+
}
|
|
256
|
+
// overwrite can't be used to not destroy cache
|
|
257
|
+
await fsExtra.copy(spaDir, CodeInjector.SPA_TMP_PATH, {
|
|
258
|
+
filter: (src) => {
|
|
259
|
+
const filterPasses = !src.includes('/adminforth/spa/node_modules') && !src.includes('/adminforth/spa/dist');
|
|
260
|
+
if (process.env.HEAVY_DEBUG && !filterPasses) {
|
|
261
|
+
console.log('🪲⚙️ fsExtra.copy filtered out', src);
|
|
295
262
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
263
|
+
return filterPasses;
|
|
264
|
+
},
|
|
265
|
+
dereference: true, // needed to dereference types
|
|
266
|
+
});
|
|
267
|
+
// copy whole custom directory
|
|
268
|
+
if ((_a = this.adminforth.config.customization) === null || _a === void 0 ? void 0 : _a.customComponentsDir) {
|
|
269
|
+
// resolve customComponentsDir to absolute path, so ./aa will be resolved to /path/to/current/dir/aa
|
|
270
|
+
const customCompAbsPath = path.resolve(this.adminforth.config.customization.customComponentsDir);
|
|
271
|
+
this.srcFoldersToSync[customCompAbsPath] = './';
|
|
272
|
+
}
|
|
273
|
+
// if this.adminforth.config.customization.favicon is set, copy it to assets
|
|
274
|
+
const customFav = (_b = this.adminforth.config.customization) === null || _b === void 0 ? void 0 : _b.favicon;
|
|
275
|
+
if (customFav) {
|
|
276
|
+
const faviconPath = path.join((_c = this.adminforth.config.customization) === null || _c === void 0 ? void 0 : _c.customComponentsDir, customFav.replace('@@/', ''));
|
|
277
|
+
const dest = path.join(CodeInjector.SPA_TMP_PATH, 'public', 'assets', customFav.replace('@@/', ''));
|
|
278
|
+
// make sure all folders in dest exist
|
|
279
|
+
await fsExtra.ensureDir(path.dirname(dest));
|
|
280
|
+
await fsExtra.copy(faviconPath, dest);
|
|
281
|
+
}
|
|
282
|
+
for (const [src, dest] of Object.entries(this.srcFoldersToSync)) {
|
|
283
|
+
const to = path.join(CodeInjector.SPA_TMP_PATH, 'src', 'custom', dest);
|
|
284
|
+
if (process.env.HEAVY_DEBUG) {
|
|
285
|
+
console.log(`🪲⚙️ fsExtra.copy from ${src}, ${to}`);
|
|
300
286
|
}
|
|
287
|
+
await fsExtra.copy(src, to, {
|
|
288
|
+
recursive: true,
|
|
289
|
+
dereference: true,
|
|
290
|
+
});
|
|
301
291
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
});
|
|
313
|
-
const uniqueIcons = Array.from(new Set(icons));
|
|
314
|
-
// icons are collectionName:iconName. Get list of all unique collection names:
|
|
315
|
-
const collections = new Set(icons.map((icon) => icon.split(':')[0]));
|
|
316
|
-
// package names @iconify-prerendered/vue-<collection name>
|
|
317
|
-
const iconPackageNames = Array.from(collections).map((collection) => `@iconify-prerendered/vue-${collection}`);
|
|
318
|
-
// for each icon generate import statement
|
|
319
|
-
const iconImports = uniqueIcons.map((icon) => {
|
|
320
|
-
const [collection, iconName] = icon.split(':');
|
|
321
|
-
const PascalIconName = 'Icon' + iconName.split('-').map((part, index) => {
|
|
322
|
-
return part[0].toUpperCase() + part.slice(1);
|
|
323
|
-
}).join('');
|
|
324
|
-
return `import { ${PascalIconName} } from '@iconify-prerendered/vue-${collection}';`;
|
|
325
|
-
}).join('\n');
|
|
326
|
-
// for each custom component generate import statement
|
|
327
|
-
const customResourceComponents = [];
|
|
328
|
-
function checkInjections(filePathes) {
|
|
329
|
-
filePathes.forEach(({ file }) => {
|
|
330
|
-
if (!customResourceComponents.includes(file)) {
|
|
331
|
-
if (file === undefined) {
|
|
332
|
-
throw new Error('file is undefined');
|
|
333
|
-
}
|
|
334
|
-
customResourceComponents.push(file);
|
|
292
|
+
}
|
|
293
|
+
//collect all 'icon' fields from resources bulkActions
|
|
294
|
+
this.adminforth.config.resources.forEach((resource) => {
|
|
295
|
+
var _a;
|
|
296
|
+
if ((_a = resource.options) === null || _a === void 0 ? void 0 : _a.bulkActions) {
|
|
297
|
+
resource.options.bulkActions.forEach((action) => {
|
|
298
|
+
if (action.icon) {
|
|
299
|
+
icons.push(action.icon);
|
|
335
300
|
}
|
|
336
301
|
});
|
|
337
302
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
303
|
+
});
|
|
304
|
+
const uniqueIcons = Array.from(new Set(icons));
|
|
305
|
+
// icons are collectionName:iconName. Get list of all unique collection names:
|
|
306
|
+
const collections = new Set(icons.map((icon) => icon.split(':')[0]));
|
|
307
|
+
// package names @iconify-prerendered/vue-<collection name>
|
|
308
|
+
const iconPackageNames = Array.from(collections).map((collection) => `@iconify-prerendered/vue-${collection}`);
|
|
309
|
+
// for each icon generate import statement
|
|
310
|
+
const iconImports = uniqueIcons.map((icon) => {
|
|
311
|
+
const [collection, iconName] = icon.split(':');
|
|
312
|
+
const PascalIconName = 'Icon' + iconName.split('-').map((part, index) => {
|
|
313
|
+
return part[0].toUpperCase() + part.slice(1);
|
|
314
|
+
}).join('');
|
|
315
|
+
return `import { ${PascalIconName} } from '@iconify-prerendered/vue-${collection}';`;
|
|
316
|
+
}).join('\n');
|
|
317
|
+
// for each custom component generate import statement
|
|
318
|
+
const customResourceComponents = [];
|
|
319
|
+
function checkInjections(filePathes) {
|
|
320
|
+
filePathes.forEach(({ file }) => {
|
|
321
|
+
if (!customResourceComponents.includes(file)) {
|
|
322
|
+
if (file === undefined) {
|
|
323
|
+
throw new Error('file is undefined');
|
|
350
324
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
325
|
+
customResourceComponents.push(file);
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
this.adminforth.config.resources.forEach((resource) => {
|
|
330
|
+
var _a;
|
|
331
|
+
resource.columns.forEach((column) => {
|
|
332
|
+
if (column.components) {
|
|
333
|
+
Object.values(column.components).forEach(({ file }) => {
|
|
334
|
+
if (!customResourceComponents.includes(file)) {
|
|
335
|
+
if (file === undefined) {
|
|
336
|
+
throw new Error('file is undefined from field.components, field:' + JSON.stringify(column));
|
|
337
|
+
}
|
|
338
|
+
customResourceComponents.push(file);
|
|
339
|
+
}
|
|
355
340
|
});
|
|
356
|
-
}
|
|
341
|
+
}
|
|
357
342
|
});
|
|
358
|
-
|
|
359
|
-
Object.values(
|
|
360
|
-
checkInjections(
|
|
343
|
+
(Object.values(((_a = resource.options) === null || _a === void 0 ? void 0 : _a.pageInjections) || {})).forEach((injection) => {
|
|
344
|
+
Object.values(injection).forEach((filePathes) => {
|
|
345
|
+
checkInjections(filePathes);
|
|
361
346
|
});
|
|
362
|
-
}
|
|
363
|
-
customResourceComponents.forEach((filePath) => {
|
|
364
|
-
const componentName = getComponentNameFromPath(filePath);
|
|
365
|
-
this.allComponentNames[filePath] = componentName;
|
|
366
347
|
});
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
348
|
+
});
|
|
349
|
+
if ((_d = this.adminforth.config.customization) === null || _d === void 0 ? void 0 : _d.globalInjections) {
|
|
350
|
+
Object.values(this.adminforth.config.customization.globalInjections).forEach((injection) => {
|
|
351
|
+
checkInjections(injection);
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
customResourceComponents.forEach((filePath) => {
|
|
355
|
+
const componentName = getComponentNameFromPath(filePath);
|
|
356
|
+
this.allComponentNames[filePath] = componentName;
|
|
357
|
+
});
|
|
358
|
+
// console.log('🔧 Injecting code into Vue sources...', this.allComponentNames);
|
|
359
|
+
let customComponentsImports = '';
|
|
360
|
+
for (const [targetPath, component] of Object.entries(this.allComponentNames)) {
|
|
361
|
+
customComponentsImports += `import ${component} from '${targetPath}';\n`;
|
|
362
|
+
}
|
|
363
|
+
// Generate Vue.component statements for each icon
|
|
364
|
+
const iconComponents = uniqueIcons.map((icon) => {
|
|
365
|
+
const [collection, iconName] = icon.split(':');
|
|
366
|
+
const PascalIconName = 'Icon' + iconName.split('-').map((part, index) => {
|
|
367
|
+
return part[0].toUpperCase() + part.slice(1);
|
|
368
|
+
}).join('');
|
|
369
|
+
return `app.component('${PascalIconName}', ${PascalIconName});`;
|
|
370
|
+
}).join('\n');
|
|
371
|
+
// Generate Vue.component statements for each custom component
|
|
372
|
+
let customComponentsComponents = '';
|
|
373
|
+
for (const name of Object.values(this.allComponentNames)) {
|
|
374
|
+
customComponentsComponents += `app.component('${name}', ${name});\n`;
|
|
375
|
+
}
|
|
376
|
+
let imports = iconImports + '\n';
|
|
377
|
+
imports += customComponentsImports + '\n';
|
|
378
|
+
if ((_e = this.adminforth.config.customization) === null || _e === void 0 ? void 0 : _e.vueUsesFile) {
|
|
379
|
+
imports += `import addCustomUses from '${this.adminforth.config.customization.vueUsesFile}';\n`;
|
|
380
|
+
}
|
|
381
|
+
// inject that code into spa_tmp/src/App.vue
|
|
382
|
+
const appVuePath = path.join(CodeInjector.SPA_TMP_PATH, 'src', 'main.ts');
|
|
383
|
+
let appVueContent = await fs.promises.readFile(appVuePath, 'utf-8');
|
|
384
|
+
appVueContent = appVueContent.replace('/* IMPORTANT:ADMINFORTH IMPORTS */', imports);
|
|
385
|
+
appVueContent = appVueContent.replace('/* IMPORTANT:ADMINFORTH COMPONENT REGISTRATIONS */', iconComponents + '\n' + customComponentsComponents + '\n');
|
|
386
|
+
if ((_f = this.adminforth.config.customization) === null || _f === void 0 ? void 0 : _f.vueUsesFile) {
|
|
387
|
+
appVueContent = appVueContent.replace('/* IMPORTANT:ADMINFORTH CUSTOM USES */', 'addCustomUses(app);');
|
|
388
|
+
}
|
|
389
|
+
await fs.promises.writeFile(appVuePath, appVueContent);
|
|
390
|
+
// generate tailwind extend styles
|
|
391
|
+
const stylesGenerator = new StylesGenerator((_g = this.adminforth.config.customization) === null || _g === void 0 ? void 0 : _g.styles);
|
|
392
|
+
const stylesText = JSON.stringify(stylesGenerator.mergeStyles(), null, 2).slice(1, -1);
|
|
393
|
+
let tailwindConfigPath = path.join(CodeInjector.SPA_TMP_PATH, 'tailwind.config.js');
|
|
394
|
+
let tailwindConfigContent = await fs.promises.readFile(tailwindConfigPath, 'utf-8');
|
|
395
|
+
tailwindConfigContent = tailwindConfigContent.replace('/* IMPORTANT:ADMINFORTH TAILWIND STYLES */', stylesText);
|
|
396
|
+
await fs.promises.writeFile(tailwindConfigPath, tailwindConfigContent);
|
|
397
|
+
const routerVuePath = path.join(CodeInjector.SPA_TMP_PATH, 'src', 'router', 'index.ts');
|
|
398
|
+
let routerVueContent = await fs.promises.readFile(routerVuePath, 'utf-8');
|
|
399
|
+
routerVueContent = routerVueContent.replace('/* IMPORTANT:ADMINFORTH ROUTES IMPORTS */', routerComponents);
|
|
400
|
+
// inject title to index.html
|
|
401
|
+
const indexHtmlPath = path.join(CodeInjector.SPA_TMP_PATH, 'index.html');
|
|
402
|
+
let indexHtmlContent = await fs.promises.readFile(indexHtmlPath, 'utf-8');
|
|
403
|
+
indexHtmlContent = indexHtmlContent.replace('/* IMPORTANT:ADMINFORTH TITLE */', `${this.adminforth.config.customization.title || 'AdminForth'}`);
|
|
404
|
+
indexHtmlContent = indexHtmlContent.replace('/* IMPORTANT:ADMINFORTH FAVICON */', ((_h = this.adminforth.config.customization.favicon) === null || _h === void 0 ? void 0 : _h.replace('@@/', `${this.adminforth.baseUrlSlashed}assets/`))
|
|
405
|
+
||
|
|
406
|
+
`${this.adminforth.baseUrlSlashed}assets/favicon.png`);
|
|
407
|
+
await fs.promises.writeFile(indexHtmlPath, indexHtmlContent);
|
|
408
|
+
/* generate custom routes */
|
|
409
|
+
let homepageMenuItem = findHomePage(this.adminforth.config.menu);
|
|
410
|
+
if (!homepageMenuItem) {
|
|
411
|
+
// find first item with path or resourceId. If we face a menu item with children earlier then path/resourceId, we should search in children
|
|
412
|
+
homepageMenuItem = await findFirstMenuItemWithResource(this.adminforth.config.menu);
|
|
413
|
+
}
|
|
414
|
+
if (!homepageMenuItem) {
|
|
415
|
+
throw new Error('No homepage found in menu and no menu item with path/resourceId found. AdminForth can not generate routes');
|
|
416
|
+
}
|
|
417
|
+
let homePagePath = homepageMenuItem.path || `/resource/${homepageMenuItem.resourceId}`;
|
|
418
|
+
if (!homePagePath) {
|
|
419
|
+
homePagePath = ((_j = this.adminforth.config.menu.filter((mi) => mi.path)[0]) === null || _j === void 0 ? void 0 : _j.path) || `/resource/${(_k = this.adminforth.config.menu.filter((mi) => mi.children)[0]) === null || _k === void 0 ? void 0 : _k.resourceId}`;
|
|
420
|
+
}
|
|
421
|
+
routes += `{
|
|
431
422
|
path: '/',
|
|
432
423
|
name: 'home',
|
|
433
424
|
//redirect to login
|
|
434
425
|
redirect: '${homePagePath}'
|
|
435
426
|
},\n`;
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
// form string "pluginName:lockHash::pLugin2Name:lockHash"
|
|
462
|
-
const pluginsLockHash = pluginPackages.map(({ pluginName, lockHash }) => `${pluginName}>${lockHash}`).join('::');
|
|
463
|
-
const iconPackagesNamesHash = hashify(iconPackageNames);
|
|
464
|
-
const fullHash = `spa>${spaLockHash}::icons>${iconPackagesNamesHash}::user/custom>${usersLockHash}::${pluginsLockHash}`;
|
|
465
|
-
const hashPath = path.join(CodeInjector.SPA_TMP_PATH, 'node_modules', '.adminforth_hash');
|
|
466
|
-
try {
|
|
467
|
-
const existingHash = yield fs.promises.readFile(hashPath, 'utf-8');
|
|
468
|
-
if (existingHash === fullHash) {
|
|
469
|
-
process.env.HEAVY_DEBUG && console.log(`🪲Hashes match, skipping npm ci/install, from file: ${existingHash}, actual: ${fullHash}`);
|
|
470
|
-
return;
|
|
471
|
-
}
|
|
472
|
-
else {
|
|
473
|
-
process.env.HEAVY_DEBUG && console.log(`🪲 Hashes do not match: from file: ${existingHash} actual: ${fullHash}, proceeding with npm ci/install`);
|
|
474
|
-
}
|
|
427
|
+
routerVueContent = routerVueContent.replace('/* IMPORTANT:ADMINFORTH ROUTES */', routes);
|
|
428
|
+
await fs.promises.writeFile(routerVuePath, routerVueContent);
|
|
429
|
+
/* hash checking */
|
|
430
|
+
const spaPackageLockPath = path.join(CodeInjector.SPA_TMP_PATH, 'package-lock.json');
|
|
431
|
+
const spaPackageLock = JSON.parse(await fs.promises.readFile(spaPackageLockPath, 'utf-8'));
|
|
432
|
+
const spaLockHash = hashify(spaPackageLock);
|
|
433
|
+
/* customPackageLock */
|
|
434
|
+
let usersLockHash = '';
|
|
435
|
+
let usersPackages = [];
|
|
436
|
+
if ((_l = this.adminforth.config.customization) === null || _l === void 0 ? void 0 : _l.customComponentsDir) {
|
|
437
|
+
[usersLockHash, usersPackages] = await this.packagesFromNpm(this.adminforth.config.customization.customComponentsDir);
|
|
438
|
+
}
|
|
439
|
+
const pluginPackages = [];
|
|
440
|
+
// for every installed plugin generate packages
|
|
441
|
+
for (const plugin of this.adminforth.activatedPlugins) {
|
|
442
|
+
process.env.HEAVY_DEBUG && console.log('🔧 Checking packages for plugin', plugin.constructor.name, plugin.customFolderPath);
|
|
443
|
+
const [lockHash, packages] = await this.packagesFromNpm(plugin.customFolderPath);
|
|
444
|
+
if (packages.length) {
|
|
445
|
+
pluginPackages.push({
|
|
446
|
+
pluginName: plugin.constructor.name,
|
|
447
|
+
lockHash,
|
|
448
|
+
packages,
|
|
449
|
+
});
|
|
475
450
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
451
|
+
}
|
|
452
|
+
// form string "pluginName:lockHash::pLugin2Name:lockHash"
|
|
453
|
+
const pluginsLockHash = pluginPackages.map(({ pluginName, lockHash }) => `${pluginName}>${lockHash}`).join('::');
|
|
454
|
+
const iconPackagesNamesHash = hashify(iconPackageNames);
|
|
455
|
+
const fullHash = `spa>${spaLockHash}::icons>${iconPackagesNamesHash}::user/custom>${usersLockHash}::${pluginsLockHash}`;
|
|
456
|
+
const hashPath = path.join(CodeInjector.SPA_TMP_PATH, 'node_modules', '.adminforth_hash');
|
|
457
|
+
try {
|
|
458
|
+
const existingHash = await fs.promises.readFile(hashPath, 'utf-8');
|
|
459
|
+
if (existingHash === fullHash) {
|
|
460
|
+
process.env.HEAVY_DEBUG && console.log(`🪲Hashes match, skipping npm ci/install, from file: ${existingHash}, actual: ${fullHash}`);
|
|
461
|
+
return;
|
|
479
462
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
const npmInstallCommand = `install ${[
|
|
483
|
-
...iconPackageNames,
|
|
484
|
-
...usersPackages,
|
|
485
|
-
...pluginPackages.map(({ packages }) => packages.join(' ')),
|
|
486
|
-
].join(' ')}`;
|
|
487
|
-
yield this.runNpmShell({ command: npmInstallCommand, cwd: CodeInjector.SPA_TMP_PATH });
|
|
463
|
+
else {
|
|
464
|
+
process.env.HEAVY_DEBUG && console.log(`🪲 Hashes do not match: from file: ${existingHash} actual: ${fullHash}, proceeding with npm ci/install`);
|
|
488
465
|
}
|
|
489
|
-
|
|
466
|
+
}
|
|
467
|
+
catch (e) {
|
|
468
|
+
// ignore
|
|
469
|
+
process.env.HEAVY_DEBUG && console.log('🪲Hash file does not exist, proceeding with npm ci/install');
|
|
470
|
+
}
|
|
471
|
+
await this.runNpmShell({ command: 'ci', cwd: CodeInjector.SPA_TMP_PATH });
|
|
472
|
+
const allPacks = [
|
|
473
|
+
...iconPackageNames,
|
|
474
|
+
...usersPackages,
|
|
475
|
+
...pluginPackages.reduce((acc, { packages }) => {
|
|
476
|
+
acc.push(...packages);
|
|
477
|
+
return acc;
|
|
478
|
+
}, []),
|
|
479
|
+
];
|
|
480
|
+
const EXCLUDE_PACKS = ['@iconify-prerendered/vue-flowbite'];
|
|
481
|
+
const allPacksFiltered = allPacks.filter((pack) => {
|
|
482
|
+
return !EXCLUDE_PACKS.some((exclude) => pack.startsWith(exclude));
|
|
490
483
|
});
|
|
484
|
+
const allPacksUnique = Array.from(new Set(allPacksFiltered));
|
|
485
|
+
if (allPacks.length) {
|
|
486
|
+
const npmInstallCommand = `install ${allPacksUnique.join(' ')}`;
|
|
487
|
+
await this.runNpmShell({ command: npmInstallCommand, cwd: CodeInjector.SPA_TMP_PATH });
|
|
488
|
+
}
|
|
489
|
+
await fs.promises.writeFile(hashPath, fullHash);
|
|
491
490
|
}
|
|
492
|
-
watchForReprepare(
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
const
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
yield collectDirectories(path.join(dir, file.name));
|
|
506
|
-
}
|
|
491
|
+
async watchForReprepare({}) {
|
|
492
|
+
const spaPath = this.getSpaDir();
|
|
493
|
+
// get list of all subdirectories in spa recursively
|
|
494
|
+
const directories = [];
|
|
495
|
+
const collectDirectories = async (dir) => {
|
|
496
|
+
const files = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
497
|
+
for (const file of files) {
|
|
498
|
+
if (['node_modules', 'dist'].includes(file.name)) {
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
if (file.isDirectory()) {
|
|
502
|
+
directories.push(path.join(dir, file.name));
|
|
503
|
+
await collectDirectories(path.join(dir, file.name));
|
|
507
504
|
}
|
|
508
|
-
});
|
|
509
|
-
yield collectDirectories(spaPath);
|
|
510
|
-
if (process.env.HEAVY_DEBUG) {
|
|
511
|
-
console.log('🪲🔎 Watch for:', directories.join(','));
|
|
512
505
|
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
506
|
+
};
|
|
507
|
+
await collectDirectories(spaPath);
|
|
508
|
+
if (process.env.HEAVY_DEBUG) {
|
|
509
|
+
console.log('🪲🔎 Watch for:', directories.join(','));
|
|
510
|
+
}
|
|
511
|
+
const watcher = filewatcher();
|
|
512
|
+
directories.forEach((dir) => {
|
|
513
|
+
watcher.add(dir);
|
|
514
|
+
});
|
|
515
|
+
watcher.on('change', async (file, x) => {
|
|
516
|
+
console.log(`File ${file} changed ${x}, preparing sources...`);
|
|
517
|
+
await this.prepareSources({ filesUpdated: [file.replace(spaPath + '/', '')] });
|
|
523
518
|
});
|
|
519
|
+
watcher.on('fallback', notifyWatcherIssue);
|
|
520
|
+
this.allWatchers.push(watcher);
|
|
524
521
|
}
|
|
525
|
-
watchCustomComponentsForCopy(
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
522
|
+
async watchCustomComponentsForCopy({ customComponentsDir, destination }) {
|
|
523
|
+
if (!customComponentsDir) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
// check if folder exists
|
|
527
|
+
try {
|
|
528
|
+
await fs.promises.access(customComponentsDir, fs.constants.F_OK);
|
|
529
|
+
}
|
|
530
|
+
catch (e) {
|
|
531
|
+
process.env.HEAVY_DEBUG && console.log(`🪲Custom components dir ${customComponentsDir} does not exist, skipping watching`);
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
// get all subdirs
|
|
535
|
+
const directories = [];
|
|
536
|
+
const files = [];
|
|
537
|
+
const collectDirectories = async (dir) => {
|
|
538
|
+
if (['node_modules', 'dist'].includes(path.basename(dir))) {
|
|
536
539
|
return;
|
|
537
540
|
}
|
|
538
|
-
|
|
539
|
-
const
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
if (
|
|
543
|
-
|
|
544
|
-
}
|
|
545
|
-
directories.push(dir);
|
|
546
|
-
const filesAndDirs = yield fs.promises.readdir(dir, { withFileTypes: true });
|
|
547
|
-
yield Promise.all(filesAndDirs.map((file) => __awaiter(this, void 0, void 0, function* () {
|
|
548
|
-
const isDir = fs.lstatSync(path.join(dir, file.name)).isDirectory();
|
|
549
|
-
if (isDir) {
|
|
550
|
-
yield collectDirectories(path.join(dir, file.name));
|
|
551
|
-
}
|
|
552
|
-
else {
|
|
553
|
-
files.push(path.join(dir, file.name));
|
|
554
|
-
}
|
|
555
|
-
})));
|
|
556
|
-
});
|
|
557
|
-
yield collectDirectories(customComponentsDir);
|
|
558
|
-
const watcher = filewatcher();
|
|
559
|
-
files.forEach((file) => {
|
|
560
|
-
process.env.HEAVY_DEBUG && console.log(`🪲🔎 Watch for file ${file}`);
|
|
561
|
-
watcher.add(file);
|
|
562
|
-
});
|
|
563
|
-
if (process.env.HEAVY_DEBUG) {
|
|
564
|
-
console.log('🪲🔎 Watch for:', directories.join(','));
|
|
565
|
-
}
|
|
566
|
-
watcher.on('change', (fileOrDir) => __awaiter(this, void 0, void 0, function* () {
|
|
567
|
-
// copy one file
|
|
568
|
-
const relativeFilename = fileOrDir.replace(customComponentsDir + '/', '');
|
|
569
|
-
if (process.env.HEAVY_DEBUG) {
|
|
570
|
-
console.log(`🔎 fileOrDir ${fileOrDir} changed`);
|
|
571
|
-
console.log(`🔎 relativeFilename ${relativeFilename}`);
|
|
572
|
-
console.log(`🔎 customComponentsDir ${customComponentsDir}`);
|
|
573
|
-
console.log(`🔎 destination ${destination}`);
|
|
574
|
-
}
|
|
575
|
-
const isFile = fs.lstatSync(fileOrDir).isFile();
|
|
576
|
-
if (isFile) {
|
|
577
|
-
const destPath = path.join(CodeInjector.SPA_TMP_PATH, 'src', 'custom', destination, relativeFilename);
|
|
578
|
-
process.env.HEAVY_DEBUG && console.log(`🔎 Copying file ${fileOrDir} to ${destPath}`);
|
|
579
|
-
yield fsExtra.copy(fileOrDir, destPath);
|
|
580
|
-
return;
|
|
541
|
+
directories.push(dir);
|
|
542
|
+
const filesAndDirs = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
543
|
+
await Promise.all(filesAndDirs.map(async (file) => {
|
|
544
|
+
const isDir = fs.lstatSync(path.join(dir, file.name)).isDirectory();
|
|
545
|
+
if (isDir) {
|
|
546
|
+
await collectDirectories(path.join(dir, file.name));
|
|
581
547
|
}
|
|
582
548
|
else {
|
|
583
|
-
|
|
549
|
+
files.push(path.join(dir, file.name));
|
|
584
550
|
}
|
|
585
551
|
}));
|
|
586
|
-
|
|
587
|
-
|
|
552
|
+
};
|
|
553
|
+
await collectDirectories(customComponentsDir);
|
|
554
|
+
const watcher = filewatcher();
|
|
555
|
+
files.forEach((file) => {
|
|
556
|
+
process.env.HEAVY_DEBUG && console.log(`🪲🔎 Watch for file ${file}`);
|
|
557
|
+
watcher.add(file);
|
|
588
558
|
});
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
if (
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
const cwd = CodeInjector.SPA_TMP_PATH;
|
|
608
|
-
if (!hotReload) {
|
|
609
|
-
// probably add option to build with tsh check (plain 'build')
|
|
610
|
-
yield this.runNpmShell({ command: 'run build-only', cwd });
|
|
559
|
+
if (process.env.HEAVY_DEBUG) {
|
|
560
|
+
console.log('🪲🔎 Watch for:', directories.join(','));
|
|
561
|
+
}
|
|
562
|
+
watcher.on('change', async (fileOrDir) => {
|
|
563
|
+
// copy one file
|
|
564
|
+
const relativeFilename = fileOrDir.replace(customComponentsDir + '/', '');
|
|
565
|
+
if (process.env.HEAVY_DEBUG) {
|
|
566
|
+
console.log(`🔎 fileOrDir ${fileOrDir} changed`);
|
|
567
|
+
console.log(`🔎 relativeFilename ${relativeFilename}`);
|
|
568
|
+
console.log(`🔎 customComponentsDir ${customComponentsDir}`);
|
|
569
|
+
console.log(`🔎 destination ${destination}`);
|
|
570
|
+
}
|
|
571
|
+
const isFile = fs.lstatSync(fileOrDir).isFile();
|
|
572
|
+
if (isFile) {
|
|
573
|
+
const destPath = path.join(CodeInjector.SPA_TMP_PATH, 'src', 'custom', destination, relativeFilename);
|
|
574
|
+
process.env.HEAVY_DEBUG && console.log(`🔎 Copying file ${fileOrDir} to ${destPath}`);
|
|
575
|
+
await fsExtra.copy(fileOrDir, destPath);
|
|
576
|
+
return;
|
|
611
577
|
}
|
|
612
578
|
else {
|
|
613
|
-
|
|
614
|
-
console.log(`🪲⚙️ spawn: npm ${command}...`);
|
|
615
|
-
const nodeBinary = process.execPath;
|
|
616
|
-
const npmPath = path.join(path.dirname(nodeBinary), 'npm');
|
|
617
|
-
const env = Object.assign({ VITE_ADMINFORTH_PUBLIC_PATH: this.adminforth.config.baseUrl, FORCE_COLOR: '1' }, process.env);
|
|
618
|
-
const devServer = spawn(`${nodeBinary}`, [`${npmPath}`, ...command.split(' ')], {
|
|
619
|
-
cwd,
|
|
620
|
-
env,
|
|
621
|
-
});
|
|
622
|
-
devServer.stdout.on('data', (data) => {
|
|
623
|
-
console.log(`[AdminForth SPA]:`);
|
|
624
|
-
process.stdout.write(data);
|
|
625
|
-
});
|
|
626
|
-
devServer.stderr.on('data', (data) => {
|
|
627
|
-
console.error(`[AdminForth SPA ERR]:`);
|
|
628
|
-
process.stdout.write(data);
|
|
629
|
-
});
|
|
579
|
+
// for now do nothing
|
|
630
580
|
}
|
|
631
581
|
});
|
|
582
|
+
watcher.on('fallback', notifyWatcherIssue);
|
|
583
|
+
this.allWatchers.push(watcher);
|
|
584
|
+
}
|
|
585
|
+
async bundleNow({ hotReload = false }) {
|
|
586
|
+
console.log(`AdminForth bundling ${hotReload ? ' and listening for changes (🔥 Hotreload)' : ' (no hot reload)'}`);
|
|
587
|
+
this.adminforth.runningHotReload = hotReload;
|
|
588
|
+
await this.prepareSources({});
|
|
589
|
+
if (hotReload) {
|
|
590
|
+
await Promise.all([
|
|
591
|
+
this.watchForReprepare({}),
|
|
592
|
+
...Object.entries(this.srcFoldersToSync).map(async ([src, dest]) => {
|
|
593
|
+
await this.watchCustomComponentsForCopy({
|
|
594
|
+
customComponentsDir: src,
|
|
595
|
+
destination: dest,
|
|
596
|
+
});
|
|
597
|
+
}),
|
|
598
|
+
]);
|
|
599
|
+
}
|
|
600
|
+
console.log('AdminForth bundling');
|
|
601
|
+
const cwd = CodeInjector.SPA_TMP_PATH;
|
|
602
|
+
if (!hotReload) {
|
|
603
|
+
// probably add option to build with tsh check (plain 'build')
|
|
604
|
+
await this.runNpmShell({ command: 'run build-only', cwd });
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
const command = 'run dev';
|
|
608
|
+
console.log(`🪲⚙️ spawn: npm ${command}...`);
|
|
609
|
+
const nodeBinary = process.execPath;
|
|
610
|
+
const npmPath = path.join(path.dirname(nodeBinary), 'npm');
|
|
611
|
+
const env = Object.assign({ VITE_ADMINFORTH_PUBLIC_PATH: this.adminforth.config.baseUrl, FORCE_COLOR: '1' }, process.env);
|
|
612
|
+
const devServer = spawn(`${nodeBinary}`, [`${npmPath}`, ...command.split(' ')], {
|
|
613
|
+
cwd,
|
|
614
|
+
env,
|
|
615
|
+
});
|
|
616
|
+
devServer.stdout.on('data', (data) => {
|
|
617
|
+
console.log(`[AdminForth SPA]:`);
|
|
618
|
+
process.stdout.write(data);
|
|
619
|
+
});
|
|
620
|
+
devServer.stderr.on('data', (data) => {
|
|
621
|
+
console.error(`[AdminForth SPA ERR]:`);
|
|
622
|
+
process.stdout.write(data);
|
|
623
|
+
});
|
|
624
|
+
}
|
|
632
625
|
}
|
|
633
626
|
}
|
|
634
627
|
CodeInjector.SPA_TMP_PATH = path.join(TMP_DIR, 'adminforth', 'spa_tmp');
|
|
635
628
|
export default CodeInjector;
|
|
629
|
+
//# sourceMappingURL=codeInjector.js.map
|