@webiny/cli 0.0.0-mt-1
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/CHANGELOG.md +2896 -0
- package/LICENSE +21 -0
- package/README.md +7 -0
- package/bin.js +36 -0
- package/cli.js +107 -0
- package/commands/index.js +13 -0
- package/commands/run/index.js +30 -0
- package/commands/telemetry/index.js +31 -0
- package/commands/upgrade/index.js +107 -0
- package/context.js +137 -0
- package/package.json +63 -0
- package/types.d.ts +149 -0
- package/utils/PluginsContainer.js +49 -0
- package/utils/getProject.js +48 -0
- package/utils/getProjectApplication.js +63 -0
- package/utils/importModule.js +43 -0
- package/utils/index.js +17 -0
- package/utils/localStorage.js +44 -0
- package/utils/log.js +69 -0
- package/utils/sendEvent.js +15 -0
package/types.d.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rename file to types.ts when switching the package to Typescript.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A simplified plugins container interface, used specifically within the Webiny CLI.
|
|
7
|
+
* Not in relation with "@webiny/plugins" package.
|
|
8
|
+
*/
|
|
9
|
+
export interface PluginsContainer {
|
|
10
|
+
byType<T extends Plugin>(type: T["type"]): T[];
|
|
11
|
+
byName<T extends Plugin>(name: T["name"]): T;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A simplified plugin interface, used specifically within the Webiny CLI.
|
|
16
|
+
* Not in relation with "@webiny/plugins" package.
|
|
17
|
+
*/
|
|
18
|
+
export interface Plugin<T = Record<string, any>> {
|
|
19
|
+
type: string;
|
|
20
|
+
name?: string;
|
|
21
|
+
[key: string]: any;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface Project {
|
|
25
|
+
/**
|
|
26
|
+
* Name of the project.
|
|
27
|
+
*/
|
|
28
|
+
name: string;
|
|
29
|
+
/**
|
|
30
|
+
* Configurations.
|
|
31
|
+
*/
|
|
32
|
+
config: Record<string, any>;
|
|
33
|
+
/**
|
|
34
|
+
* Root path of the project.
|
|
35
|
+
*/
|
|
36
|
+
root: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A type that represents the logging method.
|
|
41
|
+
*/
|
|
42
|
+
interface Log {
|
|
43
|
+
(...args): string;
|
|
44
|
+
hl: (...args) => string;
|
|
45
|
+
highlight: (...args) => string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Interface representing the CLI Context.
|
|
50
|
+
*/
|
|
51
|
+
export interface CliContext {
|
|
52
|
+
/**
|
|
53
|
+
* All registered plugins.
|
|
54
|
+
*/
|
|
55
|
+
plugins: PluginsContainer;
|
|
56
|
+
/**
|
|
57
|
+
* All the environment variables.
|
|
58
|
+
*/
|
|
59
|
+
loadedEnvFiles: Record<string, any>;
|
|
60
|
+
/**
|
|
61
|
+
* Version of the Webiny CLI.
|
|
62
|
+
*/
|
|
63
|
+
version: string;
|
|
64
|
+
/**
|
|
65
|
+
* Project information.
|
|
66
|
+
*/
|
|
67
|
+
project: Project;
|
|
68
|
+
/**
|
|
69
|
+
* Trigger given callback on SIGINT.
|
|
70
|
+
*/
|
|
71
|
+
onExit: (cb: () => any) => void;
|
|
72
|
+
/**
|
|
73
|
+
* Import a given module.
|
|
74
|
+
*/
|
|
75
|
+
import: (module: string) => Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Regular logging.
|
|
78
|
+
*/
|
|
79
|
+
log: Log;
|
|
80
|
+
/**
|
|
81
|
+
* Info logging.
|
|
82
|
+
*/
|
|
83
|
+
info: Log;
|
|
84
|
+
/**
|
|
85
|
+
* Success logging.
|
|
86
|
+
*/
|
|
87
|
+
success: Log;
|
|
88
|
+
/**
|
|
89
|
+
* Debug logging.
|
|
90
|
+
*/
|
|
91
|
+
debug: Log;
|
|
92
|
+
/**
|
|
93
|
+
* Warnings logging.
|
|
94
|
+
*/
|
|
95
|
+
warning: Log;
|
|
96
|
+
/**
|
|
97
|
+
* Errors logging.
|
|
98
|
+
*/
|
|
99
|
+
error: Log;
|
|
100
|
+
/**
|
|
101
|
+
* Resolve given dir or dirs against project root path.
|
|
102
|
+
*/
|
|
103
|
+
resolve: (dir) => string;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Provides a way to store some meta data in the project's local ".webiny/cli.json" file.
|
|
107
|
+
* Only trivial data should be passed here, specific to the current project.
|
|
108
|
+
*/
|
|
109
|
+
localStorage: {
|
|
110
|
+
set: (key: string, value: string) => Record<string, any>;
|
|
111
|
+
get: (key: string) => any;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Args received from the CLI.
|
|
117
|
+
*/
|
|
118
|
+
interface CliUpgradePluginOptions {
|
|
119
|
+
/**
|
|
120
|
+
* Targeted version of the upgrade.
|
|
121
|
+
*/
|
|
122
|
+
targetVersion: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
*
|
|
126
|
+
*/
|
|
127
|
+
export interface CliUpgradePlugin extends Plugin {
|
|
128
|
+
/**
|
|
129
|
+
* Name of the plugin to differentiate from others.
|
|
130
|
+
* Something like: cli-upgrade-5.0.0
|
|
131
|
+
*/
|
|
132
|
+
name: string;
|
|
133
|
+
/**
|
|
134
|
+
* Type of the plugin.
|
|
135
|
+
*/
|
|
136
|
+
type: "cli-upgrade";
|
|
137
|
+
/**
|
|
138
|
+
* Version the plugin is for.
|
|
139
|
+
*/
|
|
140
|
+
version: string;
|
|
141
|
+
/**
|
|
142
|
+
* Is this plugin usable for the upgrade?
|
|
143
|
+
*/
|
|
144
|
+
canUpgrade?: (options: CliUpgradePluginOptions, context: CliContext) => Promise<boolean>;
|
|
145
|
+
/**
|
|
146
|
+
* Apply the upgrade.
|
|
147
|
+
*/
|
|
148
|
+
upgrade: (options: CliUpgradePluginOptions, context: CliContext) => Promise<void>;
|
|
149
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const uniqid = require("uniqid");
|
|
2
|
+
|
|
3
|
+
// Since the Webiny CLI can rely on "@webiny/plugins" package (chicken-egg problem), then
|
|
4
|
+
// we need to make a copy of its PluginsContainer class. We removed all of the extra
|
|
5
|
+
// features that are in reality not needed for the Webiny CLI.
|
|
6
|
+
const assign = (plugins, target) => {
|
|
7
|
+
for (let i = 0; i < plugins.length; i++) {
|
|
8
|
+
const plugin = plugins[i];
|
|
9
|
+
if (Array.isArray(plugin)) {
|
|
10
|
+
assign(plugin, target);
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let name = plugin._name || plugin.name;
|
|
15
|
+
if (!name) {
|
|
16
|
+
plugin.name = name = uniqid(plugin.type + "-");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
target[name] = plugin;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
module.exports = class PluginsContainer {
|
|
24
|
+
plugins = {};
|
|
25
|
+
constructor(...args) {
|
|
26
|
+
this.register(...args);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
byName(name) {
|
|
30
|
+
return this.plugins[name];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
byType(type) {
|
|
34
|
+
const plugins = this.findByType(type);
|
|
35
|
+
return Array.from(plugins);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
findByType(type) {
|
|
39
|
+
return Object.values(this.plugins).filter(pl => pl.type === type);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
register(...args) {
|
|
43
|
+
assign(args, this.plugins);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
unregister(name) {
|
|
47
|
+
delete this.plugins[name];
|
|
48
|
+
}
|
|
49
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const findUp = require("find-up");
|
|
2
|
+
const { dirname } = require("path");
|
|
3
|
+
const { importModule } = require("./importModule");
|
|
4
|
+
|
|
5
|
+
const projectConfigs = ["webiny.project.js", "webiny.project.ts"];
|
|
6
|
+
|
|
7
|
+
function getRoot({ cwd } = {}) {
|
|
8
|
+
let root = findUp.sync(projectConfigs, { cwd });
|
|
9
|
+
if (root) {
|
|
10
|
+
return dirname(root).replace(/\\/g, "/");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// For backwards compatibility
|
|
14
|
+
root = findUp.sync("webiny.root.js", { cwd });
|
|
15
|
+
if (root) {
|
|
16
|
+
return dirname(root).replace(/\\/g, "/");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
throw new Error("Couldn't detect Webiny project.");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getConfig({ cwd } = {}) {
|
|
23
|
+
let path = findUp.sync(projectConfigs, { cwd });
|
|
24
|
+
if (path) {
|
|
25
|
+
return importModule(path);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
path = findUp.sync("webiny.root.js", { cwd });
|
|
29
|
+
if (path) {
|
|
30
|
+
return require(path);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
throw new Error("Couldn't detect Webiny project.");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = args => {
|
|
37
|
+
const root = getRoot(args);
|
|
38
|
+
return {
|
|
39
|
+
get name() {
|
|
40
|
+
// Check "projectName" for backwards compatibility.
|
|
41
|
+
return process.env.WEBINY_PROJECT_NAME || this.config.projectName || this.config.name;
|
|
42
|
+
},
|
|
43
|
+
root,
|
|
44
|
+
get config() {
|
|
45
|
+
return getConfig(args);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const { dirname, basename, join } = require("path");
|
|
2
|
+
const findUp = require("find-up");
|
|
3
|
+
const getProject = require("./getProject");
|
|
4
|
+
const { importModule } = require("./importModule");
|
|
5
|
+
const glob = require("fast-glob");
|
|
6
|
+
|
|
7
|
+
const appConfigs = ["webiny.application.js", "webiny.application.ts"];
|
|
8
|
+
|
|
9
|
+
module.exports = args => {
|
|
10
|
+
// Using "Pulumi.yaml" for the backwards compatibility.
|
|
11
|
+
const applicationRootFile = findUp.sync(appConfigs.concat("Pulumi.yaml"), { cwd: args.cwd });
|
|
12
|
+
|
|
13
|
+
if (!applicationRootFile) {
|
|
14
|
+
throw new Error(`Could not detect project application in given directory (${args.cwd}).`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const rootFile = applicationRootFile.replace(/\\/g, "/");
|
|
18
|
+
const applicationRoot = dirname(rootFile);
|
|
19
|
+
|
|
20
|
+
let applicationConfig;
|
|
21
|
+
if (appConfigs.includes(basename(rootFile))) {
|
|
22
|
+
applicationConfig = importModule(rootFile);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let name, id;
|
|
26
|
+
if (applicationConfig) {
|
|
27
|
+
id = applicationConfig.id;
|
|
28
|
+
name = applicationConfig.name;
|
|
29
|
+
} else {
|
|
30
|
+
name = basename(applicationRoot);
|
|
31
|
+
id = name;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
id,
|
|
36
|
+
name,
|
|
37
|
+
root: applicationRoot,
|
|
38
|
+
config: applicationConfig,
|
|
39
|
+
project: getProject(args),
|
|
40
|
+
get packages() {
|
|
41
|
+
const webinyConfigs = glob.sync(
|
|
42
|
+
join(applicationRoot, "**/webiny.config*.{ts,js}").replace(/\\/g, "/")
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return webinyConfigs.map(config => {
|
|
46
|
+
const dirPath = dirname(config);
|
|
47
|
+
const packageJson = require(join(dirPath, "package.json"));
|
|
48
|
+
return {
|
|
49
|
+
name: packageJson.name,
|
|
50
|
+
paths: {
|
|
51
|
+
root: dirname(config),
|
|
52
|
+
packageJson: join(dirPath, "package.json"),
|
|
53
|
+
config
|
|
54
|
+
},
|
|
55
|
+
packageJson,
|
|
56
|
+
get config() {
|
|
57
|
+
return require(config).default || require(config);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const { addHook } = require("pirates");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Add support for TS
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
addHook(
|
|
10
|
+
code => {
|
|
11
|
+
const ts = require("typescript");
|
|
12
|
+
const { outputText } = ts.transpileModule(code, {
|
|
13
|
+
compilerOptions: {
|
|
14
|
+
target: "es6",
|
|
15
|
+
allowJs: true,
|
|
16
|
+
allowSyntheticDefaultImports: true,
|
|
17
|
+
esModuleInterop: true,
|
|
18
|
+
outDir: "bin",
|
|
19
|
+
moduleResolution: "node",
|
|
20
|
+
module: "commonjs"
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return outputText;
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
exts: [".ts"],
|
|
28
|
+
matcher: () => true
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
module.exports.importModule = configPath => {
|
|
33
|
+
if (!fs.existsSync(configPath)) {
|
|
34
|
+
throw Error(`"${configPath}" does not exist!`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const extension = path.extname(configPath);
|
|
38
|
+
if (extension === ".ts") {
|
|
39
|
+
return require(configPath).default;
|
|
40
|
+
} else {
|
|
41
|
+
return require(configPath);
|
|
42
|
+
}
|
|
43
|
+
};
|
package/utils/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const { importModule } = require("./importModule");
|
|
2
|
+
const getProject = require("./getProject");
|
|
3
|
+
const getProjectApplication = require("./getProjectApplication");
|
|
4
|
+
const localStorage = require("./localStorage");
|
|
5
|
+
const log = require("./log");
|
|
6
|
+
const sendEvent = require("./sendEvent");
|
|
7
|
+
const PluginsContainer = require("./PluginsContainer");
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
importModule,
|
|
11
|
+
getProject,
|
|
12
|
+
getProjectApplication,
|
|
13
|
+
localStorage,
|
|
14
|
+
log,
|
|
15
|
+
sendEvent,
|
|
16
|
+
PluginsContainer
|
|
17
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// This is a small class that enables us to store some useful
|
|
2
|
+
// data into the .webiny folder, located in the project root.
|
|
3
|
+
// For example, we are saving the path entered while creating
|
|
4
|
+
// GraphQL services, so that the user doesn't have to type
|
|
5
|
+
// the same paths over and over.
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
const getProject = require("./getProject");
|
|
9
|
+
|
|
10
|
+
module.exports = function (filename = "cli.json") {
|
|
11
|
+
const project = getProject();
|
|
12
|
+
const DOT_WEBINY = path.join(project.root, ".webiny");
|
|
13
|
+
const dataFilePath = path.join(DOT_WEBINY, filename);
|
|
14
|
+
|
|
15
|
+
let data = {};
|
|
16
|
+
if (fs.existsSync(dataFilePath)) {
|
|
17
|
+
try {
|
|
18
|
+
data = JSON.parse(fs.readFileSync(dataFilePath));
|
|
19
|
+
} catch (e) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
`Could not parse Webiny CLI's locale storage data file located at ${dataFilePath}.`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
set(key, value) {
|
|
28
|
+
data[key] = value;
|
|
29
|
+
|
|
30
|
+
if (!fs.existsSync(DOT_WEBINY)) {
|
|
31
|
+
fs.mkdirSync(DOT_WEBINY);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fs.writeFileSync(dataFilePath, JSON.stringify(data));
|
|
35
|
+
return data;
|
|
36
|
+
},
|
|
37
|
+
get(key) {
|
|
38
|
+
if (!key) {
|
|
39
|
+
return data;
|
|
40
|
+
}
|
|
41
|
+
return data[key];
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
};
|
package/utils/log.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const chalk = require("chalk");
|
|
2
|
+
|
|
3
|
+
const getLogType = type => {
|
|
4
|
+
switch (type) {
|
|
5
|
+
case "log":
|
|
6
|
+
return type;
|
|
7
|
+
case "info":
|
|
8
|
+
return `${chalk.blueBright(type)}`;
|
|
9
|
+
case "error":
|
|
10
|
+
return `${chalk.red(type)}`;
|
|
11
|
+
case "warning":
|
|
12
|
+
return `${chalk.yellow(type)}`;
|
|
13
|
+
case "debug":
|
|
14
|
+
return `${chalk.gray(type)}`;
|
|
15
|
+
case "success":
|
|
16
|
+
return `${chalk.green(type)}`;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const webinyLog = (type, ...args) => {
|
|
21
|
+
const prefix = `webiny ${getLogType(type)}: `;
|
|
22
|
+
|
|
23
|
+
const [first, ...rest] = args;
|
|
24
|
+
if (typeof first === "string") {
|
|
25
|
+
return console.log(prefix + first, ...rest);
|
|
26
|
+
}
|
|
27
|
+
return console.log(prefix, first, ...rest);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const functions = {
|
|
31
|
+
log(...args) {
|
|
32
|
+
webinyLog("log", ...args);
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
info(...args) {
|
|
36
|
+
webinyLog("info", ...args);
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
success(...args) {
|
|
40
|
+
webinyLog("success", ...args);
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
debug(...args) {
|
|
44
|
+
webinyLog("debug", ...args);
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
warning(...args) {
|
|
48
|
+
webinyLog("warning", ...args);
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
error(...args) {
|
|
52
|
+
webinyLog("error", ...args);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
functions.log.highlight = chalk.highlight;
|
|
57
|
+
functions.log.hl = chalk.highlight;
|
|
58
|
+
functions.info.highlight = chalk.blue;
|
|
59
|
+
functions.info.hl = chalk.blueBright;
|
|
60
|
+
functions.success.highlight = chalk.green;
|
|
61
|
+
functions.success.hl = chalk.green;
|
|
62
|
+
functions.debug.highlight = chalk.gray;
|
|
63
|
+
functions.debug.hl = chalk.gray;
|
|
64
|
+
functions.warning.highlight = chalk.yellow;
|
|
65
|
+
functions.warning.hl = chalk.yellow;
|
|
66
|
+
functions.error.highlight = chalk.red;
|
|
67
|
+
functions.error.hl = chalk.red;
|
|
68
|
+
|
|
69
|
+
module.exports = functions;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const { sendEvent } = require("@webiny/telemetry/cli");
|
|
2
|
+
const getProject = require("./getProject");
|
|
3
|
+
|
|
4
|
+
module.exports = ({ event, properties, extraPayload }) => {
|
|
5
|
+
const project = getProject();
|
|
6
|
+
if (project.config.cli && project.config.cli.telemetry === false) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return sendEvent({
|
|
11
|
+
event,
|
|
12
|
+
properties,
|
|
13
|
+
extraPayload
|
|
14
|
+
});
|
|
15
|
+
};
|