-
Notifications
You must be signed in to change notification settings - Fork 5
/
PluginUtils.ts
120 lines (109 loc) · 3.14 KB
/
PluginUtils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import path from 'path';
import { JsonUtils } from './JsonUtils';
import { PackageJsonUtils } from './PackageJsonUtils';
import { PackageJson, Plugin } from './models';
/**
* Returns shaper plugins installed in the package.json file
* of the specified path
*/
function getDynamicPlugins(path: string): Map<string, Plugin> {
return getInstalledPluginsFromPackageJson(path);
}
/**
* Returns shaper plugins installed in the package.json file
* at the specified root path
*
* @param rootPath
*/
function getInstalledPluginsFromPackageJson(
rootPath: string
): Map<string, Plugin> {
// Initialize return value
const plugins = new Map<string, Plugin>();
// Read the package.json file at the root path
const packageJson = PackageJsonUtils.getPackageJson(rootPath);
if (!packageJson) {
return plugins;
}
// Create a list of all dependencies
// These could either be ordinary dependencies or shaper plugins
const dependencyNames = new Set([
...Object.keys(packageJson.dependencies || {}),
...Object.keys(packageJson.devDependencies || {}),
]);
const allDependencyNames = Array.from(dependencyNames);
// Loop through all dependencies and build a map of shaper plugins
allDependencyNames.forEach((dependencyName) => {
// Get the package.json file of the dependency
const dependencyPackageJson = getDependencyPackageJson(
rootPath,
dependencyName
);
// Check to see if required properties exist
if (
dependencyPackageJson &&
!!dependencyPackageJson.main &&
!!dependencyPackageJson.shaper
) {
// It is a shaper plugin, get it!
const plugin = getPluginMainDefaultExport(
path.join(rootPath, 'node_modules', dependencyName),
dependencyPackageJson.main
);
if (plugin && !!plugin.run) {
plugins.set(dependencyName, plugin);
}
}
});
return plugins;
}
/**
* Returns the package.json file of the specified dependency
*
* @param rootPath e.g. ~/projects/code-shaper
* @param dependencyName e.g. @code-shaper/react
*/
function getDependencyPackageJson(
rootPath: string,
dependencyName: string
): PackageJson | null {
try {
const packageJsonPath = require.resolve(`${dependencyName}/package.json`, {
paths: [rootPath],
});
return JsonUtils.readJsonFile(packageJsonPath);
} catch {
return null;
}
}
/**
* Returns the main default export of the specified plugin
*
* @param rootPath e.g. ~/projects/code-shaper/node_modules/@code-shaper/react
* @param mainPath e.g. ./dist/index.js
* @returns the main default export of the plugin, e.g.
* {
* id: '@code-shaper/react',
* name: 'React',
* description: 'generates React applications',
* run: [AsyncFunction: run]
* }
*/
function getPluginMainDefaultExport(
rootPath: string,
mainPath: string
): Plugin | null {
try {
const fullMainPath = require.resolve(mainPath, {
paths: [rootPath],
});
return require(fullMainPath).default as Plugin;
} catch (err) {
console.log(`Error loading plugin at ${rootPath}`, err);
return null;
}
}
export const PluginUtils = {
getDynamicPlugins,
getInstalledPluginsFromPackageJson,
};