UNPKG

4.83 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.locateHook = exports.removeHook = exports.addHook = exports.Hook = void 0;
4const utils_array_1 = require("@ionic/utils-array");
5const utils_terminal_1 = require("@ionic/utils-terminal");
6const Debug = require("debug");
7const lodash = require("lodash");
8const path = require("path");
9const color_1 = require("./color");
10const errors_1 = require("./errors");
11const debug = Debug('ionic:lib:hooks');
12class Hook {
13 constructor(e) {
14 this.e = e;
15 }
16 get script() {
17 return `ionic:${this.name}`;
18 }
19 async run(input) {
20 const { pkgManagerArgs } = await Promise.resolve().then(() => require('./utils/npm'));
21 const type = this.e.project.type;
22 if (!type || !this.e.project.directory) {
23 return; // TODO: will we need hooks outside a project?
24 }
25 const [pkg] = await this.e.project.getPackageJson(undefined, { logErrors: false });
26 if (!pkg) {
27 return;
28 }
29 debug(`Looking for ${color_1.ancillary(this.script)} npm script.`);
30 const ctxEnvironment = this.generateCTXEnvironment(input);
31 if (pkg.scripts && pkg.scripts[this.script]) {
32 debug(`Invoking ${color_1.ancillary(this.script)} npm script.`);
33 const [pkgManager, ...pkgArgs] = await pkgManagerArgs(this.e.config.get('npmClient'), { command: 'run', script: this.script });
34 await this.e.shell.run(pkgManager, pkgArgs, {
35 env: ctxEnvironment,
36 });
37 }
38 const projectHooks = this.e.project.config.get('hooks');
39 const hooks = projectHooks ? utils_array_1.conform(projectHooks[this.name]) : [];
40 for (const h of hooks) {
41 const p = path.resolve(this.e.project.directory, h);
42 try {
43 if (path.extname(p) !== '.js') {
44 throw new Error(`Hooks must be .js files with a function for its default export.`);
45 }
46 const hook = await this.loadHookFn(p);
47 if (!hook) {
48 throw new Error(`Module must have a function for its default export.`);
49 }
50 await hook(lodash.assign({}, input, {
51 project: {
52 type,
53 dir: this.e.project.directory,
54 srcDir: await this.e.project.getSourceDir(),
55 },
56 argv: process.argv,
57 env: {
58 ...process.env,
59 ...ctxEnvironment,
60 },
61 }));
62 }
63 catch (e) {
64 throw new errors_1.HookException(`An error occurred while running an Ionic CLI hook defined in ${color_1.strong(utils_terminal_1.prettyPath(this.e.project.filePath))}.\n` +
65 `Hook: ${color_1.strong(this.name)}\n` +
66 `File: ${color_1.strong(p)}\n\n` +
67 `${color_1.failure(e.stack ? e.stack : e)}`);
68 }
69 }
70 }
71 async loadHookFn(p) {
72 const module = require(p);
73 if (typeof module === 'function') {
74 return module;
75 }
76 else if (typeof module.default === 'function') {
77 return module.default;
78 }
79 debug(`Could not load hook function ${color_1.strong(p)}: %o not a function`, module);
80 }
81 generateCTXEnvironment(input, path = []) {
82 let environment = {};
83 for (const [key, value] of Object.entries(input)) {
84 if (typeof value === 'object') {
85 environment = {
86 ...environment,
87 ...this.generateCTXEnvironment(value, [...path, key]),
88 };
89 }
90 else {
91 const name = [...path, key].join('_');
92 environment[`IONIC_CLI_HOOK_CTX_${lodash.snakeCase(name)}`.toUpperCase()] = value;
93 }
94 }
95 return environment;
96 }
97}
98exports.Hook = Hook;
99function addHook(baseDir, hooks, hook) {
100 const hookPaths = utils_array_1.conform(hooks);
101 const resolvedHookPaths = hookPaths.map(p => path.resolve(baseDir, p));
102 if (!resolvedHookPaths.includes(path.resolve(baseDir, hook))) {
103 hookPaths.push(hook);
104 }
105 return hookPaths;
106}
107exports.addHook = addHook;
108function removeHook(baseDir, hooks, hook) {
109 const hookPaths = utils_array_1.conform(hooks);
110 const i = locateHook(baseDir, hookPaths, hook);
111 if (i >= 0) {
112 hookPaths.splice(i, 1);
113 }
114 return hookPaths;
115}
116exports.removeHook = removeHook;
117function locateHook(baseDir, hooks, hook) {
118 return utils_array_1.conform(hooks).map(p => path.resolve(baseDir, p)).indexOf(path.resolve(baseDir, hook));
119}
120exports.locateHook = locateHook;