UNPKG

3.18 kBJavaScriptView Raw
1import { debugLog } from './utils/debugging.js';
2import { exec } from 'child_process';
3import { delimiter, sep } from 'path';
4const DEFAULT_HOOKS = {
5 afterStart: [],
6 beforeDone: [],
7 onWatchTriggered: [],
8 onError: [],
9 afterOneFileWrite: [],
10 afterAllFileWrite: [],
11 beforeOneFileWrite: [],
12 beforeAllFileWrite: [],
13};
14function normalizeHooks(_hooks) {
15 const keys = Object.keys({
16 ...DEFAULT_HOOKS,
17 ..._hooks,
18 });
19 return keys.reduce((prev, hookName) => {
20 if (typeof _hooks[hookName] === 'string') {
21 return {
22 ...prev,
23 [hookName]: [_hooks[hookName]],
24 };
25 }
26 if (typeof _hooks[hookName] === 'function') {
27 return {
28 ...prev,
29 [hookName]: [_hooks[hookName]],
30 };
31 }
32 if (Array.isArray(_hooks[hookName])) {
33 return {
34 ...prev,
35 [hookName]: _hooks[hookName],
36 };
37 }
38 return prev;
39 }, {});
40}
41function execShellCommand(cmd) {
42 return new Promise((resolve, reject) => {
43 exec(cmd, {
44 env: {
45 ...process.env,
46 PATH: `${process.env.PATH}${delimiter}${process.cwd()}${sep}node_modules${sep}.bin`,
47 },
48 }, (error, stdout, stderr) => {
49 if (error) {
50 reject(error);
51 // eslint-disable-next-line no-console
52 console.error(error);
53 }
54 else {
55 debugLog(stdout || stderr);
56 resolve(stdout || stderr);
57 }
58 });
59 });
60}
61async function executeHooks(hookName, scripts = [], args = []) {
62 debugLog(`Running lifecycle hook "${hookName}" scripts...`);
63 for (const script of scripts) {
64 if (typeof script === 'string') {
65 debugLog(`Running lifecycle hook "${hookName}" script: ${script} with args: ${args.join(' ')}...`);
66 await execShellCommand(`${script} ${args.join(' ')}`);
67 }
68 else {
69 debugLog(`Running lifecycle hook "${hookName}" script: ${script.name} with args: ${args.join(' ')}...`);
70 await script(...args);
71 }
72 }
73}
74export const lifecycleHooks = (_hooks = {}) => {
75 const hooks = normalizeHooks(_hooks);
76 return {
77 afterStart: async () => executeHooks('afterStart', hooks.afterStart),
78 onWatchTriggered: async (event, path) => executeHooks('onWatchTriggered', hooks.onWatchTriggered, [event, path]),
79 onError: async (error) => executeHooks('onError', hooks.onError, [`"${error}"`]),
80 afterOneFileWrite: async (path) => executeHooks('afterOneFileWrite', hooks.afterOneFileWrite, [path]),
81 afterAllFileWrite: async (paths) => executeHooks('afterAllFileWrite', hooks.afterAllFileWrite, paths),
82 beforeOneFileWrite: async (path) => executeHooks('beforeOneFileWrite', hooks.beforeOneFileWrite, [path]),
83 beforeAllFileWrite: async (paths) => executeHooks('beforeAllFileWrite', hooks.beforeAllFileWrite, paths),
84 beforeDone: async () => executeHooks('beforeDone', hooks.beforeDone),
85 };
86};