mfer 0.0.0-alpha.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/README.md +19 -0
- package/dist/commands/config/add-config.js +1 -0
- package/dist/commands/config/config.js +16 -0
- package/dist/commands/config/index.js +7 -0
- package/dist/commands/config/sub-commands/add-config.js +8 -0
- package/dist/commands/config/sub-commands/edit-config.js +24 -0
- package/dist/commands/config/sub-commands/list-config.js +7 -0
- package/dist/commands/config.js +16 -0
- package/dist/commands/init.js +32 -0
- package/dist/commands/run.js +15 -0
- package/dist/index.js +21 -0
- package/dist/utils/config-utils.js +50 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Micro Frontend Runner (mfer)
|
|
2
|
+
|
|
3
|
+
A CLI tool that helps manage and run multiple micro frontends.
|
|
4
|
+
|
|
5
|
+
## Development
|
|
6
|
+
|
|
7
|
+
### Getting Started
|
|
8
|
+
|
|
9
|
+
1. Run `npm i` to install dependencies.
|
|
10
|
+
2. Run `npm run build` to build the project.
|
|
11
|
+
3. Run `npm install -g .` to link the project globally.
|
|
12
|
+
4. Now you can run the CLI as `mfer` for locally development anywhere on your system. Try `mfer --help` to begin.
|
|
13
|
+
5. Updating the code will require another `npm run build`.
|
|
14
|
+
|
|
15
|
+
### Troubleshooting
|
|
16
|
+
|
|
17
|
+
If you run into problems first check `npm list -g` if the project is successfully linked globally.
|
|
18
|
+
|
|
19
|
+
Sometimes you may need to run `npm uninstall -g run-mfs` and then follow up with another `npm install -g .` within the project's root directory.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { currentConfig } from "../../utils/config-utils.js";
|
|
3
|
+
const configCommand = new Command("config")
|
|
4
|
+
.description("prism configuration settings")
|
|
5
|
+
.option("-l, --list", "list the current configuration")
|
|
6
|
+
.action((options) => {
|
|
7
|
+
const { list, path } = options;
|
|
8
|
+
if (list) {
|
|
9
|
+
console.log(`\nCurrent configuration:\n`);
|
|
10
|
+
console.log(currentConfig);
|
|
11
|
+
console.log("");
|
|
12
|
+
}
|
|
13
|
+
if (path) {
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
export default configCommand;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { listConfigCommand } from "./sub-commands/list-config.js";
|
|
3
|
+
import { editConfigCommand } from "./sub-commands/edit-config.js";
|
|
4
|
+
const configCommand = new Command("config").description("configuration settings");
|
|
5
|
+
configCommand.addCommand(listConfigCommand);
|
|
6
|
+
configCommand.addCommand(editConfigCommand);
|
|
7
|
+
export default configCommand;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { currentConfig } from "../../../utils/config-utils.js";
|
|
3
|
+
export const listConfigCommand = new Command("list")
|
|
4
|
+
.description("display the current configuration settings")
|
|
5
|
+
.action(() => {
|
|
6
|
+
console.log("current configuration!");
|
|
7
|
+
console.log(currentConfig);
|
|
8
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Command } from "commander";
|
|
11
|
+
import YAML from "yaml";
|
|
12
|
+
import { configExists, currentConfig, editConfigAsync, saveConfig, warnOfMissingConfig, } from "../../../utils/config-utils.js";
|
|
13
|
+
export const editConfigCommand = new Command("edit")
|
|
14
|
+
.description("edit configuration")
|
|
15
|
+
.action(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
|
+
if (configExists) {
|
|
17
|
+
const answer = yield editConfigAsync("edit configuration file, this will overwrite your existing configuration", currentConfig);
|
|
18
|
+
const newConfig = YAML.parse(answer);
|
|
19
|
+
saveConfig(newConfig);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
warnOfMissingConfig();
|
|
23
|
+
}
|
|
24
|
+
}));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { currentConfig } from "../../../utils/config-utils.js";
|
|
3
|
+
export const listConfigCommand = new Command("list")
|
|
4
|
+
.description("display the current configuration settings")
|
|
5
|
+
.action(() => {
|
|
6
|
+
console.log(currentConfig);
|
|
7
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { currentConfig } from "../utils/config-utils.js";
|
|
3
|
+
const configCommand = new Command("config")
|
|
4
|
+
.description("prism configuration settings")
|
|
5
|
+
.option("-l, --list", "list the current configuration")
|
|
6
|
+
.action((options) => {
|
|
7
|
+
const { list, path } = options;
|
|
8
|
+
if (list) {
|
|
9
|
+
console.log(`\nCurrent configuration:\n`);
|
|
10
|
+
console.log(currentConfig);
|
|
11
|
+
console.log("");
|
|
12
|
+
}
|
|
13
|
+
if (path) {
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
export default configCommand;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Command } from "commander";
|
|
11
|
+
import { configExists, editConfigAsync, saveConfig, } from "../utils/config-utils.js";
|
|
12
|
+
import YAML from "yaml";
|
|
13
|
+
const templateConfig = {
|
|
14
|
+
mfe_directory: "path/to/folder/containing/microfrontends",
|
|
15
|
+
groups: {
|
|
16
|
+
all: ["repo_name_1", "repo_name_2", "repo_name_3"],
|
|
17
|
+
customGroup1: ["repo_name2", "repo_name_3"],
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
const initCommand = new Command("init")
|
|
21
|
+
.description("setup a new configuration")
|
|
22
|
+
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
|
+
if (!configExists) {
|
|
24
|
+
const answer = yield editConfigAsync("create a new configuration file", templateConfig);
|
|
25
|
+
const newConfig = YAML.parse(answer);
|
|
26
|
+
saveConfig(newConfig);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
console.log("config already exists, you can edit it with 'mfer config edit'");
|
|
30
|
+
}
|
|
31
|
+
}));
|
|
32
|
+
export default initCommand;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { configExists, currentConfig, warnOfMissingConfig, } from "../utils/config-utils.js";
|
|
3
|
+
const runCommand = new Command("run")
|
|
4
|
+
.description("run micro-frontend applications")
|
|
5
|
+
.argument("[group_name]", "name of the group as specified in the configuration", "all")
|
|
6
|
+
.action((options) => {
|
|
7
|
+
if (!configExists) {
|
|
8
|
+
warnOfMissingConfig();
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
console.log("options", options);
|
|
12
|
+
const runGroup = currentConfig.groups[options];
|
|
13
|
+
console.log("Running the following micro frontends:\n", runGroup);
|
|
14
|
+
});
|
|
15
|
+
export default runCommand;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { program } from "commander";
|
|
3
|
+
import configCommand from "./commands/config/index.js";
|
|
4
|
+
import initCommand from "./commands/init.js";
|
|
5
|
+
import runCommand from "./commands/run.js";
|
|
6
|
+
import { loadConfig } from "./utils/config-utils.js";
|
|
7
|
+
program
|
|
8
|
+
.name("mfer")
|
|
9
|
+
.description("Micro Frontend Runner (mfer) - A CLI for running your project's micro frontends.")
|
|
10
|
+
.version("0.0.0-alpha.1", "-v, --version", "mfer CLI version")
|
|
11
|
+
.hook("preAction", (thisCommand, actionCommand) => {
|
|
12
|
+
console.log();
|
|
13
|
+
})
|
|
14
|
+
.hook("postAction", (thisCommand, actionCommand) => {
|
|
15
|
+
console.log();
|
|
16
|
+
});
|
|
17
|
+
program.addCommand(configCommand);
|
|
18
|
+
program.addCommand(initCommand);
|
|
19
|
+
program.addCommand(runCommand);
|
|
20
|
+
loadConfig();
|
|
21
|
+
program.parse();
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import * as fs from "fs";
|
|
11
|
+
import * as path from "path";
|
|
12
|
+
import * as os from "os";
|
|
13
|
+
import YAML from "yaml";
|
|
14
|
+
import chalk from "chalk";
|
|
15
|
+
import { editor } from "@inquirer/prompts";
|
|
16
|
+
export const configPath = path.join(os.homedir(), ".mfer/config.yaml");
|
|
17
|
+
export const configExists = fs.existsSync(configPath);
|
|
18
|
+
export let currentConfig;
|
|
19
|
+
export const loadConfig = () => {
|
|
20
|
+
if (configExists) {
|
|
21
|
+
const configFile = fs.readFileSync(configPath, "utf8");
|
|
22
|
+
currentConfig = YAML.parse(configFile);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
export const warnOfMissingConfig = () => {
|
|
26
|
+
if (!configExists) {
|
|
27
|
+
console.log(`${chalk.red("Error")}: No configuration file detected.\n Please run ${chalk.blue.bold("mfer init")} to create one.`);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export const saveConfig = (newConfig) => {
|
|
31
|
+
try {
|
|
32
|
+
const configDir = path.dirname(configPath);
|
|
33
|
+
if (!fs.existsSync(configDir)) {
|
|
34
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
35
|
+
}
|
|
36
|
+
fs.writeFileSync(configPath, YAML.stringify(newConfig));
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
console.log(`Error writing config file!\n\n${e}`);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
export const editConfigAsync = (message, config) => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
const prefixMessage = "# This file is whitespace sensitive. Tabs are two spaces, and file must be valid YAML.";
|
|
44
|
+
const answer = yield editor({
|
|
45
|
+
message,
|
|
46
|
+
default: `${prefixMessage}\n${YAML.stringify(config)}`,
|
|
47
|
+
postfix: ".yaml",
|
|
48
|
+
});
|
|
49
|
+
return answer;
|
|
50
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mfer",
|
|
3
|
+
"version": "0.0.0-alpha.1",
|
|
4
|
+
"description": "CLI tool designed to sensibly run micro-frontends from the terminal.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"mfer": "dist/index.js"
|
|
7
|
+
},
|
|
8
|
+
"main": "index.ts",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"clean": "rimraf dist",
|
|
12
|
+
"watch": "tsc --watch"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"micro frontends",
|
|
16
|
+
"CLI",
|
|
17
|
+
"runner"
|
|
18
|
+
],
|
|
19
|
+
"author": "Stuart Rimel",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"type": "module",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/srimel/run-mfs.git"
|
|
25
|
+
},
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/srimel/run-mfs/issues"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/srimel/run-mfs#readme",
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^24.0.3",
|
|
35
|
+
"rimraf": "^6.0.1",
|
|
36
|
+
"typescript": "^5.8.3"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@inquirer/prompts": "^7.5.3",
|
|
40
|
+
"chalk": "^5.4.1",
|
|
41
|
+
"commander": "^14.0.0",
|
|
42
|
+
"concurrently": "^9.2.0",
|
|
43
|
+
"yaml": "^2.8.0"
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"dist",
|
|
47
|
+
"README.md"
|
|
48
|
+
]
|
|
49
|
+
}
|