badmfck-api-server 4.1.52 → 4.1.53

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.
@@ -1,10 +1,4 @@
1
- interface IActivateParams {
2
- name: string;
3
- token: string;
4
- host: string;
5
- username: string;
6
- password: string;
7
- switch_host?: string;
8
- }
9
- export declare function Activate(opt: IActivateParams | string, scheme?: "blue" | "green"): Promise<string>;
1
+ import { IDeployerConfig } from "./resolveConfig";
2
+ type IActivateParams = IDeployerConfig;
3
+ export declare function Activate(opt?: IActivateParams | string | null, scheme?: "blue" | "green"): Promise<string>;
10
4
  export {};
@@ -4,20 +4,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Activate = void 0;
7
- const fs_1 = __importDefault(require("fs"));
8
7
  const crypto_1 = __importDefault(require("crypto"));
9
8
  const __1 = require("../..");
9
+ const resolveConfig_1 = require("./resolveConfig");
10
10
  async function Activate(opt, scheme) {
11
- if (typeof opt === "string") {
12
- const configPath = opt;
13
- if (!fs_1.default.existsSync(configPath)) {
14
- throw new Error(`Config file not found: ${configPath}`);
15
- }
16
- opt = JSON.parse(fs_1.default.readFileSync(configPath).toString("utf-8"));
17
- if (!opt.name || !opt.token || !opt.host || !opt.username || !opt.password) {
18
- throw new Error(`Invalid activate config file (missing required fields): ${configPath}`);
19
- }
20
- }
11
+ opt = await (0, resolveConfig_1.resolveConfig)(opt);
21
12
  if (scheme && scheme !== "blue" && scheme !== "green") {
22
13
  throw new Error(`Invalid scheme: ${scheme}. Must be "blue" or "green" (or omitted).`);
23
14
  }
@@ -1,11 +1,4 @@
1
- interface IDeployerParams {
2
- name: string;
3
- token: string;
4
- host: string;
5
- username: string;
6
- password: string;
7
- includes?: string[];
8
- excludes?: string[];
9
- }
1
+ import { IDeployerConfig } from "./resolveConfig";
2
+ type IDeployerParams = IDeployerConfig;
10
3
  export declare function Deploy(opt?: IDeployerParams | string | null): Promise<string>;
11
4
  export {};
@@ -10,102 +10,9 @@ const fs_1 = __importDefault(require("fs"));
10
10
  const __1 = require("../..");
11
11
  const crypto_1 = __importDefault(require("crypto"));
12
12
  const undici_1 = require("undici");
13
- const promises_1 = require("readline/promises");
14
- const process_1 = require("process");
15
- function validateConfig(cfg) {
16
- if (!cfg || typeof cfg !== "object")
17
- return "not an object";
18
- if (!cfg.name || !cfg.token || !cfg.host || !cfg.username || !cfg.password)
19
- return "missing one of: name, token, host, username, password";
20
- if (cfg.includes && !Array.isArray(cfg.includes))
21
- return "includes must be an array";
22
- if (cfg.excludes && !Array.isArray(cfg.excludes))
23
- return "excludes must be an array";
24
- return null;
25
- }
26
- async function selectConfig(configs) {
27
- if (configs.length === 0) {
28
- throw new Error("No valid deploy configs found");
29
- }
30
- if (configs.length === 1) {
31
- console.log(`Using deploy config: ${configs[0].name}`);
32
- return configs[0];
33
- }
34
- if (!process_1.stdin.isTTY) {
35
- throw new Error(`Found ${configs.length} deploy configs (${configs.map(c => c.name).join(", ")}) but stdin is not a TTY — ` +
36
- `cannot prompt for a choice. Pass a specific config explicitly, e.g. Deploy("deploy/<name>.json").`);
37
- }
38
- console.log("\nAvailable deploy configs:\n");
39
- configs.forEach((config, index) => {
40
- console.log(`[${index + 1}] ${config.name ?? "bad-config-file"}`);
41
- });
42
- const rl = (0, promises_1.createInterface)({
43
- input: process_1.stdin,
44
- output: process_1.stdout,
45
- });
46
- try {
47
- while (true) {
48
- const answer = await rl.question(`\nChoose config [1-${configs.length}]: `);
49
- const selectedIndex = Number.parseInt(answer.trim(), 10) - 1;
50
- if (Number.isInteger(selectedIndex) &&
51
- selectedIndex >= 0 &&
52
- selectedIndex < configs.length) {
53
- return configs[selectedIndex];
54
- }
55
- console.error(`Invalid selection. Enter a number from 1 to ${configs.length}.`);
56
- }
57
- }
58
- finally {
59
- rl.close();
60
- }
61
- }
13
+ const resolveConfig_1 = require("./resolveConfig");
62
14
  async function Deploy(opt) {
63
- if (!opt) {
64
- const dir = path_1.default.resolve("deploy");
65
- const single = path_1.default.resolve("deploy.json");
66
- if (fs_1.default.existsSync(dir) && fs_1.default.statSync(dir).isDirectory()) {
67
- const files = fs_1.default.readdirSync(dir).filter(f => f.endsWith(".json"));
68
- if (files.length === 0)
69
- throw new Error(`No .json configs found in ${dir}`);
70
- const configs = [];
71
- for (const f of files) {
72
- const filePath = path_1.default.resolve(dir, f);
73
- let parsed;
74
- try {
75
- parsed = JSON.parse(fs_1.default.readFileSync(filePath).toString("utf-8"));
76
- }
77
- catch (e) {
78
- console.error(`Skipping ${f}: failed to parse JSON:`, e.message);
79
- continue;
80
- }
81
- const reason = validateConfig(parsed);
82
- if (reason) {
83
- console.error(`Skipping ${f}: ${reason}`);
84
- continue;
85
- }
86
- configs.push(parsed);
87
- }
88
- if (configs.length === 0)
89
- throw new Error(`No valid deploy configs in ${dir} (all ${files.length} were skipped)`);
90
- opt = await selectConfig(configs);
91
- }
92
- else if (fs_1.default.existsSync(single)) {
93
- opt = single;
94
- }
95
- else {
96
- throw new Error(`No deploy config found: neither ${dir}/ nor ${single} exists`);
97
- }
98
- }
99
- if (typeof opt === "string") {
100
- if (!fs_1.default.existsSync(opt)) {
101
- throw new Error(`File not found: ${opt}`);
102
- }
103
- opt = JSON.parse(fs_1.default.readFileSync(opt).toString("utf-8"));
104
- }
105
- const invalidReason = validateConfig(opt);
106
- if (invalidReason) {
107
- throw new Error(`Invalid deploy config: ${invalidReason}`);
108
- }
15
+ opt = await (0, resolveConfig_1.resolveConfig)(opt);
109
16
  const archiveName = __1.UID.sha256(opt.name.replaceAll(".", "_")) + ".tar.gz";
110
17
  console.log("Changing Config to live");
111
18
  const config = path_1.default.resolve("src", "Config.ts");
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const Deploy_1 = require("./Deploy");
5
+ const Activate_1 = require("./Activate");
6
+ function usage() {
7
+ console.error("Usage:");
8
+ console.error(" badmfck deploy — build + upload the current project");
9
+ console.error(" badmfck activate [blue|green] — switch blue-green slot (omit for lastDeployed)");
10
+ process.exit(1);
11
+ }
12
+ async function main() {
13
+ const command = process.argv[2];
14
+ const arg = process.argv[3];
15
+ switch (command) {
16
+ case "deploy":
17
+ await (0, Deploy_1.Deploy)();
18
+ break;
19
+ case "activate": {
20
+ let scheme;
21
+ if (arg !== undefined) {
22
+ if (arg !== "blue" && arg !== "green") {
23
+ console.error(`Invalid slot "${arg}" — expected "blue" or "green".`);
24
+ process.exit(1);
25
+ }
26
+ scheme = arg;
27
+ }
28
+ await (0, Activate_1.Activate)(undefined, scheme);
29
+ break;
30
+ }
31
+ default:
32
+ if (command)
33
+ console.error(`Unknown command: ${command}\n`);
34
+ usage();
35
+ }
36
+ }
37
+ main().catch((err) => {
38
+ console.error("\n" + (err instanceof Error ? err.message : String(err)));
39
+ process.exit(1);
40
+ });
@@ -0,0 +1,12 @@
1
+ export interface IDeployerConfig {
2
+ name: string;
3
+ token: string;
4
+ host: string;
5
+ username: string;
6
+ password: string;
7
+ includes?: string[];
8
+ excludes?: string[];
9
+ switch_host?: string;
10
+ }
11
+ export declare function validateConfig(cfg: any): string | null;
12
+ export declare function resolveConfig(opt?: IDeployerConfig | string | null): Promise<IDeployerConfig>;
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.resolveConfig = exports.validateConfig = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const promises_1 = require("readline/promises");
10
+ const process_1 = require("process");
11
+ function validateConfig(cfg) {
12
+ if (!cfg || typeof cfg !== "object")
13
+ return "not an object";
14
+ if (!cfg.name || !cfg.token || !cfg.host || !cfg.username || !cfg.password)
15
+ return "missing one of: name, token, host, username, password";
16
+ if (cfg.includes && !Array.isArray(cfg.includes))
17
+ return "includes must be an array";
18
+ if (cfg.excludes && !Array.isArray(cfg.excludes))
19
+ return "excludes must be an array";
20
+ if (cfg.switch_host && typeof cfg.switch_host !== "string")
21
+ return "switch_host must be a string";
22
+ return null;
23
+ }
24
+ exports.validateConfig = validateConfig;
25
+ async function selectConfig(configs) {
26
+ if (configs.length === 0) {
27
+ throw new Error("No valid deploy configs found");
28
+ }
29
+ if (configs.length === 1) {
30
+ console.log(`Using deploy config: ${configs[0].name}`);
31
+ return configs[0];
32
+ }
33
+ if (!process_1.stdin.isTTY) {
34
+ throw new Error(`Found ${configs.length} deploy configs (${configs.map(c => c.name).join(", ")}) but stdin is not a TTY — ` +
35
+ `cannot prompt for a choice. Pass a specific config explicitly, e.g. "deploy/<name>.json".`);
36
+ }
37
+ console.log("\nAvailable deploy configs:\n");
38
+ configs.forEach((config, index) => {
39
+ console.log(`[${index + 1}] ${config.name ?? "bad-config-file"}`);
40
+ });
41
+ const rl = (0, promises_1.createInterface)({ input: process_1.stdin, output: process_1.stdout });
42
+ try {
43
+ while (true) {
44
+ const answer = await rl.question(`\nChoose config [1-${configs.length}]: `);
45
+ const selectedIndex = Number.parseInt(answer.trim(), 10) - 1;
46
+ if (Number.isInteger(selectedIndex) && selectedIndex >= 0 && selectedIndex < configs.length) {
47
+ return configs[selectedIndex];
48
+ }
49
+ console.error(`Invalid selection. Enter a number from 1 to ${configs.length}.`);
50
+ }
51
+ }
52
+ finally {
53
+ rl.close();
54
+ }
55
+ }
56
+ async function resolveConfig(opt) {
57
+ if (!opt) {
58
+ const dir = path_1.default.resolve("deploy");
59
+ const single = path_1.default.resolve("deploy.json");
60
+ if (fs_1.default.existsSync(dir) && fs_1.default.statSync(dir).isDirectory()) {
61
+ const files = fs_1.default.readdirSync(dir).filter(f => f.endsWith(".json"));
62
+ if (files.length === 0)
63
+ throw new Error(`No .json configs found in ${dir}`);
64
+ const configs = [];
65
+ for (const f of files) {
66
+ const filePath = path_1.default.resolve(dir, f);
67
+ let parsed;
68
+ try {
69
+ parsed = JSON.parse(fs_1.default.readFileSync(filePath).toString("utf-8"));
70
+ }
71
+ catch (e) {
72
+ console.error(`Skipping ${f}: failed to parse JSON:`, e.message);
73
+ continue;
74
+ }
75
+ const reason = validateConfig(parsed);
76
+ if (reason) {
77
+ console.error(`Skipping ${f}: ${reason}`);
78
+ continue;
79
+ }
80
+ configs.push(parsed);
81
+ }
82
+ if (configs.length === 0)
83
+ throw new Error(`No valid deploy configs in ${dir} (all ${files.length} were skipped)`);
84
+ opt = await selectConfig(configs);
85
+ }
86
+ else if (fs_1.default.existsSync(single)) {
87
+ opt = single;
88
+ }
89
+ else {
90
+ throw new Error(`No deploy config found: neither ${dir}/ nor ${single} exists`);
91
+ }
92
+ }
93
+ if (typeof opt === "string") {
94
+ if (!fs_1.default.existsSync(opt)) {
95
+ throw new Error(`Config file not found: ${opt}`);
96
+ }
97
+ opt = JSON.parse(fs_1.default.readFileSync(opt).toString("utf-8"));
98
+ }
99
+ const invalidReason = validateConfig(opt);
100
+ if (invalidReason) {
101
+ throw new Error(`Invalid deploy config: ${invalidReason}`);
102
+ }
103
+ return opt;
104
+ }
105
+ exports.resolveConfig = resolveConfig;
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "4.1.52",
3
+ "version": "4.1.53",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "type": "commonjs",
8
+ "bin": {
9
+ "badmfck": "dist/apiServer/deployment/cli.js"
10
+ },
8
11
  "scripts": {
9
- "build": "npm version patch && tsc && cp ./src/apiServer/monitor/index.html ./dist/apiServer/monitor/index.html && cp ./src/apiServer/documentation/index.html ./dist/apiServer/documentation/index.html",
12
+ "build": "npm version patch && tsc && cp ./src/apiServer/monitor/index.html ./dist/apiServer/monitor/index.html && cp ./src/apiServer/documentation/index.html ./dist/apiServer/documentation/index.html && chmod +x ./dist/apiServer/deployment/cli.js",
10
13
  "test": "echo \"Error: no test specified\" && exit 1"
11
14
  },
12
15
  "keywords": [