adminforth 1.2.10 → 1.2.12
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/index.js +2 -2
- package/dist/modules/codeInjector.js +47 -56
- package/dist/modules/restApi.js +10 -9
- package/dist/spa/spa/src/stores/user.ts +1 -2
- package/index.ts +2 -2
- package/modules/codeInjector.ts +21 -31
- package/modules/restApi.ts +12 -11
- package/package.json +1 -1
- package/spa/src/stores/user.ts +1 -2
package/dist/index.js
CHANGED
|
@@ -104,8 +104,8 @@ class AdminForth {
|
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
bundleNow(_b) {
|
|
107
|
-
return __awaiter(this, arguments, void 0, function* ({ hotReload = false
|
|
108
|
-
yield this.codeInjector.bundleNow({ hotReload
|
|
107
|
+
return __awaiter(this, arguments, void 0, function* ({ hotReload = false }) {
|
|
108
|
+
yield this.codeInjector.bundleNow({ hotReload });
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
111
|
getUserByPk(pk) {
|
|
@@ -51,7 +51,7 @@ class CodeInjector {
|
|
|
51
51
|
process.exit();
|
|
52
52
|
}));
|
|
53
53
|
}
|
|
54
|
-
// async runShell({command
|
|
54
|
+
// async runShell({ command }) {
|
|
55
55
|
// console.log(`⚙️ Running shell ${command}...`);
|
|
56
56
|
// console.time(`${command} done in`);
|
|
57
57
|
// const { stdout: out, stderr: err } = await execAsync(command);
|
|
@@ -59,22 +59,20 @@ class CodeInjector {
|
|
|
59
59
|
// console.log(`Command ${command} output:`, out, err);
|
|
60
60
|
// }
|
|
61
61
|
runNpmShell(_a) {
|
|
62
|
-
return __awaiter(this, arguments, void 0, function* ({ command,
|
|
62
|
+
return __awaiter(this, arguments, void 0, function* ({ command, cwd }) {
|
|
63
63
|
const nodeBinary = process.execPath; // Path to the Node.js binary running this script
|
|
64
64
|
const npmPath = path.join(path.dirname(nodeBinary), 'npm'); // Path to the npm executable
|
|
65
65
|
const env = Object.assign({ VITE_ADMINFORTH_PUBLIC_PATH: this.adminforth.config.baseUrl, FORCE_COLOR: '1' }, process.env);
|
|
66
|
-
console.log(`⚙️
|
|
66
|
+
console.log(`⚙️ exec: npm ${command}...`);
|
|
67
67
|
console.time(`npm ${command} done in`);
|
|
68
68
|
const { stdout: out, stderr: err } = yield execAsync(`${nodeBinary} ${npmPath} ${command}`, {
|
|
69
69
|
cwd,
|
|
70
70
|
env,
|
|
71
71
|
});
|
|
72
72
|
console.timeEnd(`npm ${command} done in`);
|
|
73
|
-
|
|
74
|
-
console.log(`npm ${command} output:`, out);
|
|
75
|
-
}
|
|
73
|
+
process.env.HEAVY_DEBUG && console.log(`🪲 npm ${command} output:`, out);
|
|
76
74
|
if (err) {
|
|
77
|
-
console.error(
|
|
75
|
+
process.env.HEAVY_DEBUG && console.error(`🪲npm ${command} errors/warnings:`, err);
|
|
78
76
|
}
|
|
79
77
|
});
|
|
80
78
|
}
|
|
@@ -90,7 +88,7 @@ class CodeInjector {
|
|
|
90
88
|
});
|
|
91
89
|
}
|
|
92
90
|
prepareSources(_a) {
|
|
93
|
-
return __awaiter(this, arguments, void 0, function* ({ filesUpdated
|
|
91
|
+
return __awaiter(this, arguments, void 0, function* ({ filesUpdated }) {
|
|
94
92
|
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
95
93
|
// check SPA_TMP_PATH exists and create if not
|
|
96
94
|
try {
|
|
@@ -361,9 +359,9 @@ class CodeInjector {
|
|
|
361
359
|
/* customPackageLock */
|
|
362
360
|
let usersLockHash = '';
|
|
363
361
|
let usersLock = null;
|
|
362
|
+
let usersPackage = null;
|
|
364
363
|
if ((_m = this.adminforth.config.customization) === null || _m === void 0 ? void 0 : _m.customComponentsDir) {
|
|
365
364
|
const usersPackagePath = path.join(this.adminforth.config.customization.customComponentsDir, 'package.json');
|
|
366
|
-
let usersPackage = null;
|
|
367
365
|
try {
|
|
368
366
|
usersPackage = JSON.parse(yield fs.promises.readFile(usersPackagePath, 'utf-8'));
|
|
369
367
|
}
|
|
@@ -381,49 +379,45 @@ class CodeInjector {
|
|
|
381
379
|
}
|
|
382
380
|
usersLockHash = hashify(usersLock);
|
|
383
381
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
else {
|
|
394
|
-
if (verbose) {
|
|
395
|
-
console.log(`Hashes do not match: existing ${existingHash} new ${fullHash}, proceeding with npm ci/install`);
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
catch (e) {
|
|
400
|
-
// ignore
|
|
401
|
-
if (verbose) {
|
|
402
|
-
console.log('Hash file does not exist, proceeding with npm ci/install');
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
yield this.runNpmShell({ command: 'ci', verbose, cwd: CodeInjector.SPA_TMP_PATH });
|
|
406
|
-
let customPackgeNames = [];
|
|
407
|
-
if (usersPackage && usersLock) {
|
|
408
|
-
customPackgeNames = [
|
|
409
|
-
...Object.keys(usersPackage.dependencies || []),
|
|
410
|
-
...Object.keys(usersPackage.devDependencies || [])
|
|
411
|
-
].reduce((acc, packageName) => {
|
|
412
|
-
const version = usersLock.packages[`node_modules/${packageName}`].version;
|
|
413
|
-
acc.push(`${packageName}@${version}`);
|
|
414
|
-
return acc;
|
|
415
|
-
}, []);
|
|
382
|
+
}
|
|
383
|
+
const iconPackagesNamesHash = hashify(iconPackageNames);
|
|
384
|
+
const fullHash = `${spaLockHash}::${iconPackagesNamesHash}::${usersLockHash}`;
|
|
385
|
+
const hashPath = path.join(CodeInjector.SPA_TMP_PATH, 'node_modules', '.adminforth_hash');
|
|
386
|
+
try {
|
|
387
|
+
const existingHash = yield fs.promises.readFile(hashPath, 'utf-8');
|
|
388
|
+
if (existingHash === fullHash) {
|
|
389
|
+
process.env.HEAVY_DEBUG && console.log(`🪲Hashes match, skipping npm ci/install, from file: ${existingHash}, actual: ${fullHash}`);
|
|
390
|
+
return;
|
|
416
391
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
yield this.runNpmShell({ command: npmInstallCommand, cwd: CodeInjector.SPA_TMP_PATH });
|
|
392
|
+
else {
|
|
393
|
+
process.env.HEAVY_DEBUG && console.log(`🪲 Hashes do not match: from file: ${existingHash} actual: ${fullHash}, proceeding with npm ci/install`);
|
|
420
394
|
}
|
|
421
|
-
yield fs.promises.writeFile(hashPath, fullHash);
|
|
422
395
|
}
|
|
396
|
+
catch (e) {
|
|
397
|
+
// ignore
|
|
398
|
+
process.env.HEAVY_DEBUG && console.log('🪲Hash file does not exist, proceeding with npm ci/install');
|
|
399
|
+
}
|
|
400
|
+
yield this.runNpmShell({ command: 'ci', cwd: CodeInjector.SPA_TMP_PATH });
|
|
401
|
+
let customPackgeNames = [];
|
|
402
|
+
if (usersPackage && usersLock) {
|
|
403
|
+
customPackgeNames = [
|
|
404
|
+
...Object.keys(usersPackage.dependencies || []),
|
|
405
|
+
...Object.keys(usersPackage.devDependencies || [])
|
|
406
|
+
].reduce((acc, packageName) => {
|
|
407
|
+
const version = usersLock.packages[`node_modules/${packageName}`].version;
|
|
408
|
+
acc.push(`${packageName}@${version}`);
|
|
409
|
+
return acc;
|
|
410
|
+
}, []);
|
|
411
|
+
}
|
|
412
|
+
if (iconPackageNames.length) {
|
|
413
|
+
const npmInstallCommand = `install ${[...iconPackageNames, ...customPackgeNames].join(' ')}`;
|
|
414
|
+
yield this.runNpmShell({ command: npmInstallCommand, cwd: CodeInjector.SPA_TMP_PATH });
|
|
415
|
+
}
|
|
416
|
+
yield fs.promises.writeFile(hashPath, fullHash);
|
|
423
417
|
});
|
|
424
418
|
}
|
|
425
419
|
watchForReprepare(_a) {
|
|
426
|
-
return __awaiter(this, arguments, void 0, function* ({
|
|
420
|
+
return __awaiter(this, arguments, void 0, function* ({}) {
|
|
427
421
|
const spaPath = path.join(ADMIN_FORTH_ABSOLUTE_PATH, 'spa');
|
|
428
422
|
// get list of all subdirectories in spa recursively
|
|
429
423
|
const directories = [];
|
|
@@ -456,7 +450,7 @@ class CodeInjector {
|
|
|
456
450
|
});
|
|
457
451
|
}
|
|
458
452
|
watchCustomComponentsForCopy(_a) {
|
|
459
|
-
return __awaiter(this, arguments, void 0, function* ({
|
|
453
|
+
return __awaiter(this, arguments, void 0, function* ({ customComponentsDir, destination }) {
|
|
460
454
|
if (!customComponentsDir) {
|
|
461
455
|
return;
|
|
462
456
|
}
|
|
@@ -465,9 +459,7 @@ class CodeInjector {
|
|
|
465
459
|
yield fs.promises.access(customComponentsDir, fs.constants.F_OK);
|
|
466
460
|
}
|
|
467
461
|
catch (e) {
|
|
468
|
-
|
|
469
|
-
console.log(`Custom components dir ${customComponentsDir} does not exist, skipping watching`);
|
|
470
|
-
}
|
|
462
|
+
process.env.HEAVY_DEBUG && console.log(`🪲Custom components dir ${customComponentsDir} does not exist, skipping watching`);
|
|
471
463
|
return;
|
|
472
464
|
}
|
|
473
465
|
// get all subdirs
|
|
@@ -520,16 +512,15 @@ class CodeInjector {
|
|
|
520
512
|
});
|
|
521
513
|
}
|
|
522
514
|
bundleNow(_a) {
|
|
523
|
-
return __awaiter(this, arguments, void 0, function* ({ hotReload = false
|
|
515
|
+
return __awaiter(this, arguments, void 0, function* ({ hotReload = false }) {
|
|
524
516
|
console.log(`AdminForth bundling ${hotReload ? ' and listening for changes (🔥 Hotreload)' : ' (no hot reload)'}`);
|
|
525
517
|
this.adminforth.runningHotReload = hotReload;
|
|
526
|
-
yield this.prepareSources({
|
|
518
|
+
yield this.prepareSources({});
|
|
527
519
|
if (hotReload) {
|
|
528
520
|
yield Promise.all([
|
|
529
|
-
this.watchForReprepare({
|
|
521
|
+
this.watchForReprepare({}),
|
|
530
522
|
...Object.entries(this.srcFoldersToSync).map((_b) => __awaiter(this, [_b], void 0, function* ([src, dest]) {
|
|
531
523
|
yield this.watchCustomComponentsForCopy({
|
|
532
|
-
verbose,
|
|
533
524
|
customComponentsDir: src,
|
|
534
525
|
destination: dest,
|
|
535
526
|
});
|
|
@@ -540,11 +531,11 @@ class CodeInjector {
|
|
|
540
531
|
const cwd = CodeInjector.SPA_TMP_PATH;
|
|
541
532
|
if (!hotReload) {
|
|
542
533
|
// probably add option to build with tsh check (plain 'build')
|
|
543
|
-
yield this.runNpmShell({ command: 'run build-only',
|
|
534
|
+
yield this.runNpmShell({ command: 'run build-only', cwd });
|
|
544
535
|
}
|
|
545
536
|
else {
|
|
546
537
|
const command = 'run dev';
|
|
547
|
-
console.log(`⚙️
|
|
538
|
+
console.log(`⚙️ spawn: npm ${command}...`);
|
|
548
539
|
const nodeBinary = process.execPath;
|
|
549
540
|
const npmPath = path.join(path.dirname(nodeBinary), 'npm');
|
|
550
541
|
const env = Object.assign({ VITE_ADMINFORTH_PUBLIC_PATH: this.adminforth.config.baseUrl, FORCE_COLOR: '1' }, process.env);
|
package/dist/modules/restApi.js
CHANGED
|
@@ -339,15 +339,6 @@ export default class AdminForthRestAPI {
|
|
|
339
339
|
item[col.name] = targetDataMap[item[col.name]];
|
|
340
340
|
});
|
|
341
341
|
})));
|
|
342
|
-
for (const hook of listify((_t = (_s = resource.hooks) === null || _s === void 0 ? void 0 : _s[source]) === null || _t === void 0 ? void 0 : _t.afterDatasourceResponse)) {
|
|
343
|
-
const resp = yield hook({ resource, response: data.data, adminUser });
|
|
344
|
-
if (!resp || (!resp.ok && !resp.error)) {
|
|
345
|
-
throw new Error(`Hook must return object with {ok: true} or { error: 'Error' } `);
|
|
346
|
-
}
|
|
347
|
-
if (resp.error) {
|
|
348
|
-
return { error: resp.error };
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
342
|
// remove all columns which are not defined in resources, or defined but backendOnly
|
|
352
343
|
data.data.forEach((item) => {
|
|
353
344
|
Object.keys(item).forEach((key) => {
|
|
@@ -359,6 +350,16 @@ export default class AdminForthRestAPI {
|
|
|
359
350
|
data.data.forEach((item) => {
|
|
360
351
|
item._label = resource.recordLabel(item);
|
|
361
352
|
});
|
|
353
|
+
// only after adminforth made all post processing, give user ability to edit it
|
|
354
|
+
for (const hook of listify((_t = (_s = resource.hooks) === null || _s === void 0 ? void 0 : _s[source]) === null || _t === void 0 ? void 0 : _t.afterDatasourceResponse)) {
|
|
355
|
+
const resp = yield hook({ resource, response: data.data, adminUser });
|
|
356
|
+
if (!resp || (!resp.ok && !resp.error)) {
|
|
357
|
+
throw new Error(`Hook must return object with {ok: true} or { error: 'Error' } `);
|
|
358
|
+
}
|
|
359
|
+
if (resp.error) {
|
|
360
|
+
return { error: resp.error };
|
|
361
|
+
}
|
|
362
|
+
}
|
|
362
363
|
return Object.assign(Object.assign({}, data), { options: resource === null || resource === void 0 ? void 0 : resource.options });
|
|
363
364
|
}),
|
|
364
365
|
});
|
package/index.ts
CHANGED
|
@@ -138,8 +138,8 @@ class AdminForth implements IAdminForth {
|
|
|
138
138
|
// console.log('⚙️⚙️⚙️ Database discovery done', JSON.stringify(this.config.resources, null, 2));
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
async bundleNow({ hotReload=false
|
|
142
|
-
await this.codeInjector.bundleNow({ hotReload
|
|
141
|
+
async bundleNow({ hotReload=false }) {
|
|
142
|
+
await this.codeInjector.bundleNow({ hotReload });
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
async getUserByPk(pk: string) {
|
package/modules/codeInjector.ts
CHANGED
|
@@ -62,7 +62,7 @@ class CodeInjector implements ICodeInjector {
|
|
|
62
62
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
// async runShell({command
|
|
65
|
+
// async runShell({ command }) {
|
|
66
66
|
// console.log(`⚙️ Running shell ${command}...`);
|
|
67
67
|
// console.time(`${command} done in`);
|
|
68
68
|
// const { stdout: out, stderr: err } = await execAsync(command);
|
|
@@ -70,7 +70,7 @@ class CodeInjector implements ICodeInjector {
|
|
|
70
70
|
// console.log(`Command ${command} output:`, out, err);
|
|
71
71
|
// }
|
|
72
72
|
|
|
73
|
-
async runNpmShell({command,
|
|
73
|
+
async runNpmShell({command, cwd}) {
|
|
74
74
|
const nodeBinary = process.execPath; // Path to the Node.js binary running this script
|
|
75
75
|
const npmPath = path.join(path.dirname(nodeBinary), 'npm'); // Path to the npm executable
|
|
76
76
|
|
|
@@ -80,7 +80,7 @@ class CodeInjector implements ICodeInjector {
|
|
|
80
80
|
...process.env,
|
|
81
81
|
};
|
|
82
82
|
|
|
83
|
-
console.log(`⚙️
|
|
83
|
+
console.log(`⚙️ exec: npm ${command}...`);
|
|
84
84
|
console.time(`npm ${command} done in`);
|
|
85
85
|
const { stdout: out, stderr: err } = await execAsync(`${nodeBinary} ${npmPath} ${command}`, {
|
|
86
86
|
cwd,
|
|
@@ -88,11 +88,9 @@ class CodeInjector implements ICodeInjector {
|
|
|
88
88
|
});
|
|
89
89
|
console.timeEnd(`npm ${command} done in`);
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
console.log(`npm ${command} output:`, out);
|
|
93
|
-
}
|
|
91
|
+
process.env.HEAVY_DEBUG && console.log(`🪲 npm ${command} output:`, out);
|
|
94
92
|
if (err) {
|
|
95
|
-
console.error(
|
|
93
|
+
process.env.HEAVY_DEBUG && console.error(`🪲npm ${command} errors/warnings:`, err);
|
|
96
94
|
}
|
|
97
95
|
}
|
|
98
96
|
|
|
@@ -105,7 +103,7 @@ class CodeInjector implements ICodeInjector {
|
|
|
105
103
|
}
|
|
106
104
|
}
|
|
107
105
|
|
|
108
|
-
async prepareSources({ filesUpdated
|
|
106
|
+
async prepareSources({ filesUpdated }: { filesUpdated?: string[] }) {
|
|
109
107
|
// check SPA_TMP_PATH exists and create if not
|
|
110
108
|
try {
|
|
111
109
|
await fs.promises.access(CodeInjector.SPA_TMP_PATH, fs.constants.F_OK);
|
|
@@ -386,7 +384,6 @@ class CodeInjector implements ICodeInjector {
|
|
|
386
384
|
await fs.promises.writeFile(indexHtmlPath, indexHtmlContent);
|
|
387
385
|
|
|
388
386
|
|
|
389
|
-
|
|
390
387
|
/* generate custom routes */
|
|
391
388
|
const homepageMenuItem = this.adminforth.config.menu.find((mi)=>mi.homepage);
|
|
392
389
|
let childrenHomePageMenuItem = this.adminforth.config.menu.find((mi)=>mi.children && mi.children?.find((mi)=>mi.homepage));
|
|
@@ -414,9 +411,10 @@ class CodeInjector implements ICodeInjector {
|
|
|
414
411
|
/* customPackageLock */
|
|
415
412
|
let usersLockHash = '';
|
|
416
413
|
let usersLock = null;
|
|
414
|
+
let usersPackage = null;
|
|
415
|
+
|
|
417
416
|
if (this.adminforth.config.customization?.customComponentsDir) {
|
|
418
417
|
const usersPackagePath = path.join(this.adminforth.config.customization.customComponentsDir, 'package.json');
|
|
419
|
-
let usersPackage = null;
|
|
420
418
|
try {
|
|
421
419
|
usersPackage = JSON.parse(await fs.promises.readFile(usersPackagePath, 'utf-8'));
|
|
422
420
|
} catch (e) {
|
|
@@ -432,6 +430,7 @@ class CodeInjector implements ICodeInjector {
|
|
|
432
430
|
}
|
|
433
431
|
usersLockHash = hashify(usersLock);
|
|
434
432
|
}
|
|
433
|
+
}
|
|
435
434
|
|
|
436
435
|
const iconPackagesNamesHash = hashify(iconPackageNames);
|
|
437
436
|
|
|
@@ -441,21 +440,17 @@ class CodeInjector implements ICodeInjector {
|
|
|
441
440
|
try {
|
|
442
441
|
const existingHash = await fs.promises.readFile(hashPath, 'utf-8');
|
|
443
442
|
if (existingHash === fullHash) {
|
|
444
|
-
console.log(
|
|
443
|
+
process.env.HEAVY_DEBUG && console.log(`🪲Hashes match, skipping npm ci/install, from file: ${existingHash}, actual: ${fullHash}`);
|
|
445
444
|
return;
|
|
446
445
|
} else {
|
|
447
|
-
|
|
448
|
-
console.log(`Hashes do not match: existing ${existingHash} new ${fullHash}, proceeding with npm ci/install`);
|
|
449
|
-
}
|
|
446
|
+
process.env.HEAVY_DEBUG && console.log(`🪲 Hashes do not match: from file: ${existingHash} actual: ${fullHash}, proceeding with npm ci/install`);
|
|
450
447
|
}
|
|
451
448
|
} catch (e) {
|
|
452
449
|
// ignore
|
|
453
|
-
|
|
454
|
-
console.log('Hash file does not exist, proceeding with npm ci/install');
|
|
455
|
-
}
|
|
450
|
+
process.env.HEAVY_DEBUG && console.log('🪲Hash file does not exist, proceeding with npm ci/install');
|
|
456
451
|
}
|
|
457
452
|
|
|
458
|
-
await this.runNpmShell({command: 'ci',
|
|
453
|
+
await this.runNpmShell({command: 'ci', cwd: CodeInjector.SPA_TMP_PATH});
|
|
459
454
|
|
|
460
455
|
let customPackgeNames = [];
|
|
461
456
|
if (usersPackage && usersLock) {
|
|
@@ -477,11 +472,9 @@ class CodeInjector implements ICodeInjector {
|
|
|
477
472
|
}
|
|
478
473
|
|
|
479
474
|
await fs.promises.writeFile(hashPath, fullHash);
|
|
480
|
-
|
|
481
475
|
}
|
|
482
|
-
}
|
|
483
476
|
|
|
484
|
-
async watchForReprepare({
|
|
477
|
+
async watchForReprepare({}) {
|
|
485
478
|
const spaPath = path.join(ADMIN_FORTH_ABSOLUTE_PATH, 'spa');
|
|
486
479
|
// get list of all subdirectories in spa recursively
|
|
487
480
|
const directories = [];
|
|
@@ -519,7 +512,7 @@ async watchForReprepare({ verbose }) {
|
|
|
519
512
|
this.allWatchers.push(watcher);
|
|
520
513
|
}
|
|
521
514
|
|
|
522
|
-
async watchCustomComponentsForCopy({
|
|
515
|
+
async watchCustomComponentsForCopy({ customComponentsDir, destination }) {
|
|
523
516
|
if (!customComponentsDir) {
|
|
524
517
|
return;
|
|
525
518
|
}
|
|
@@ -527,9 +520,7 @@ async watchForReprepare({ verbose }) {
|
|
|
527
520
|
try {
|
|
528
521
|
await fs.promises.access(customComponentsDir, fs.constants.F_OK);
|
|
529
522
|
} catch (e) {
|
|
530
|
-
|
|
531
|
-
console.log(`Custom components dir ${customComponentsDir} does not exist, skipping watching`);
|
|
532
|
-
}
|
|
523
|
+
process.env.HEAVY_DEBUG && console.log(`🪲Custom components dir ${customComponentsDir} does not exist, skipping watching`);
|
|
533
524
|
return;
|
|
534
525
|
}
|
|
535
526
|
|
|
@@ -594,19 +585,18 @@ async watchForReprepare({ verbose }) {
|
|
|
594
585
|
this.allWatchers.push(watcher);
|
|
595
586
|
}
|
|
596
587
|
|
|
597
|
-
async bundleNow({hotReload = false
|
|
588
|
+
async bundleNow({ hotReload = false }: { hotReload: boolean }) {
|
|
598
589
|
console.log(`AdminForth bundling ${hotReload ? ' and listening for changes (🔥 Hotreload)' : ' (no hot reload)'}`);
|
|
599
590
|
this.adminforth.runningHotReload = hotReload;
|
|
600
591
|
|
|
601
|
-
await this.prepareSources({
|
|
592
|
+
await this.prepareSources({});
|
|
602
593
|
|
|
603
594
|
if (hotReload) {
|
|
604
595
|
await Promise.all([
|
|
605
|
-
this.watchForReprepare({
|
|
596
|
+
this.watchForReprepare({}),
|
|
606
597
|
...Object.entries(this.srcFoldersToSync).map(async ([src, dest]) => {
|
|
607
598
|
|
|
608
599
|
await this.watchCustomComponentsForCopy({
|
|
609
|
-
verbose,
|
|
610
600
|
customComponentsDir: src,
|
|
611
601
|
destination: dest,
|
|
612
602
|
});
|
|
@@ -620,10 +610,10 @@ async watchForReprepare({ verbose }) {
|
|
|
620
610
|
|
|
621
611
|
if (!hotReload) {
|
|
622
612
|
// probably add option to build with tsh check (plain 'build')
|
|
623
|
-
await this.runNpmShell({command: 'run build-only',
|
|
613
|
+
await this.runNpmShell({command: 'run build-only', cwd});
|
|
624
614
|
} else {
|
|
625
615
|
const command = 'run dev';
|
|
626
|
-
console.log(`⚙️
|
|
616
|
+
console.log(`⚙️ spawn: npm ${command}...`);
|
|
627
617
|
const nodeBinary = process.execPath;
|
|
628
618
|
const npmPath = path.join(path.dirname(nodeBinary), 'npm');
|
|
629
619
|
const env = {
|
package/modules/restApi.ts
CHANGED
|
@@ -391,17 +391,6 @@ export default class AdminForthRestAPI {
|
|
|
391
391
|
})
|
|
392
392
|
);
|
|
393
393
|
|
|
394
|
-
for (const hook of listify(resource.hooks?.[source]?.afterDatasourceResponse)) {
|
|
395
|
-
const resp = await hook({ resource, response: data.data, adminUser });
|
|
396
|
-
if (!resp || (!resp.ok && !resp.error)) {
|
|
397
|
-
throw new Error(`Hook must return object with {ok: true} or { error: 'Error' } `);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
if (resp.error) {
|
|
401
|
-
return { error: resp.error };
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
394
|
// remove all columns which are not defined in resources, or defined but backendOnly
|
|
406
395
|
data.data.forEach((item) => {
|
|
407
396
|
Object.keys(item).forEach((key) => {
|
|
@@ -415,6 +404,18 @@ export default class AdminForthRestAPI {
|
|
|
415
404
|
item._label = resource.recordLabel(item);
|
|
416
405
|
});
|
|
417
406
|
|
|
407
|
+
// only after adminforth made all post processing, give user ability to edit it
|
|
408
|
+
for (const hook of listify(resource.hooks?.[source]?.afterDatasourceResponse)) {
|
|
409
|
+
const resp = await hook({ resource, response: data.data, adminUser });
|
|
410
|
+
if (!resp || (!resp.ok && !resp.error)) {
|
|
411
|
+
throw new Error(`Hook must return object with {ok: true} or { error: 'Error' } `);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
if (resp.error) {
|
|
415
|
+
return { error: resp.error };
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
418
419
|
return {
|
|
419
420
|
...data,
|
|
420
421
|
options: resource?.options,
|
package/package.json
CHANGED