@sleetch/cli 1.0.4 → 1.0.6
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.
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { t as create_command } from "../create-C1erDXXt.js";
|
|
3
|
+
import { parseArgs, styleText } from "node:util";
|
|
4
|
+
import { sleetch_runtime } from "@sleetch/core/compiler";
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region src/bin/index.ts
|
|
7
|
+
new class sleetch_cli {
|
|
8
|
+
runtime = new sleetch_runtime();
|
|
9
|
+
commands = [];
|
|
10
|
+
fallback;
|
|
11
|
+
constructor() {}
|
|
12
|
+
add(command) {
|
|
13
|
+
this.commands.push(command);
|
|
14
|
+
if (command.active == true && command.fallback == true) this.fallback = command;
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
17
|
+
resolve(args) {
|
|
18
|
+
if (args.length == 0) {
|
|
19
|
+
if (this.fallback) return {
|
|
20
|
+
found: true,
|
|
21
|
+
command: this.fallback,
|
|
22
|
+
args
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
found: false,
|
|
26
|
+
type: "empty args",
|
|
27
|
+
error: "no command found"
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const [command_name, ...command_args] = args;
|
|
31
|
+
for (const command of this.commands) if (command_name == command.name) {
|
|
32
|
+
if (!command.subcommands || command.subcommands.length == 0) {
|
|
33
|
+
if (command.active) return {
|
|
34
|
+
found: true,
|
|
35
|
+
command,
|
|
36
|
+
args: command_args
|
|
37
|
+
};
|
|
38
|
+
else return {
|
|
39
|
+
found: false,
|
|
40
|
+
type: "bad option",
|
|
41
|
+
error: "inactive command: " + command_name
|
|
42
|
+
};
|
|
43
|
+
} else {
|
|
44
|
+
const sub_cli = new sleetch_cli();
|
|
45
|
+
sub_cli.add({
|
|
46
|
+
...command,
|
|
47
|
+
fallback: true
|
|
48
|
+
});
|
|
49
|
+
for (const sub_command of command.subcommands) sub_cli.add(sub_command);
|
|
50
|
+
const sub_command = sub_cli.resolve(command_args);
|
|
51
|
+
if (sub_command.found) return sub_command;
|
|
52
|
+
else if (command.active) return {
|
|
53
|
+
found: true,
|
|
54
|
+
command,
|
|
55
|
+
args: command_args
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
found: false,
|
|
61
|
+
type: "bad option",
|
|
62
|
+
error: args.join(" ")
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
run(args) {
|
|
66
|
+
const resolve = this.resolve(args);
|
|
67
|
+
if (resolve.found == true) {
|
|
68
|
+
const { command, args } = resolve;
|
|
69
|
+
const parsed = parseArgs({
|
|
70
|
+
args,
|
|
71
|
+
options: command.options,
|
|
72
|
+
allowPositionals: true,
|
|
73
|
+
strict: false
|
|
74
|
+
});
|
|
75
|
+
const get_boolean_option = (name) => {
|
|
76
|
+
const value = parsed.values[name];
|
|
77
|
+
return typeof value === "boolean" ? value : void 0;
|
|
78
|
+
};
|
|
79
|
+
const get_string_option = (name) => {
|
|
80
|
+
const value = parsed.values[name];
|
|
81
|
+
return typeof value === "string" ? value : void 0;
|
|
82
|
+
};
|
|
83
|
+
command.action({
|
|
84
|
+
args,
|
|
85
|
+
get_boolean_option,
|
|
86
|
+
get_string_option
|
|
87
|
+
}, this);
|
|
88
|
+
} else {
|
|
89
|
+
const { error, type } = resolve;
|
|
90
|
+
this.error(type, error);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
error(type, error) {
|
|
94
|
+
console.error(styleText("red", `sleetch: ${type}: ${error}`));
|
|
95
|
+
}
|
|
96
|
+
}().add({
|
|
97
|
+
name: "help",
|
|
98
|
+
description: "Get available commands.",
|
|
99
|
+
active: true,
|
|
100
|
+
options: {},
|
|
101
|
+
fallback: true,
|
|
102
|
+
action: (options, cli) => {
|
|
103
|
+
let lines = [
|
|
104
|
+
`${styleText("cyan", "sleetch") + styleText("cyanBright", ".dev")} is a powerful documentation framework.`,
|
|
105
|
+
"",
|
|
106
|
+
`Usage: ${styleText("cyan", "sleetch")} ${styleText("gray", "<command>")} ${styleText("cyanBright", "[...args]")}`,
|
|
107
|
+
"",
|
|
108
|
+
"Commands:",
|
|
109
|
+
""
|
|
110
|
+
];
|
|
111
|
+
const format_option = (name, option) => {
|
|
112
|
+
const parts = [];
|
|
113
|
+
if (option.short) parts.push(`-${option.short}`);
|
|
114
|
+
parts.push(`--${name}`);
|
|
115
|
+
if (option.type === "string") parts[parts.length - 1] += ` <${name}>`;
|
|
116
|
+
let result = parts.join(", ");
|
|
117
|
+
if (option.type) result += ` ${styleText("gray", `- ${String(option.type)}`)}`;
|
|
118
|
+
if (option.default) result += ` ${styleText("gray", `- default=${String(option.default)}`)}`;
|
|
119
|
+
return result;
|
|
120
|
+
};
|
|
121
|
+
const add_commands_lines = (commands, pre_args = []) => {
|
|
122
|
+
for (const command of commands) {
|
|
123
|
+
const path = [...pre_args, command.name];
|
|
124
|
+
if (command.active) {
|
|
125
|
+
lines.push(` ${styleText("cyan", path.join(" "))} ${styleText("gray", "-")} ${command.description}`);
|
|
126
|
+
const options = Object.entries(command.options);
|
|
127
|
+
if (options.length > 0) for (const [name, option] of options) lines.push(` ${styleText("dim", format_option(name, option))}`);
|
|
128
|
+
}
|
|
129
|
+
if (command.subcommands) add_commands_lines(command.subcommands, path);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
add_commands_lines(cli.commands);
|
|
133
|
+
lines.push("");
|
|
134
|
+
lines.push(`Learn more: ${styleText("gray", "https://") + styleText("cyan", "sleetch") + styleText("cyanBright", ".dev")} `);
|
|
135
|
+
lines.push(` ${styleText("gray", "https://github.com/tornado-softwares/") + styleText("cyan", "sleetch")}`);
|
|
136
|
+
console.log(lines.join("\n"));
|
|
137
|
+
}
|
|
138
|
+
}).add({
|
|
139
|
+
name: "build",
|
|
140
|
+
description: "Prebuild the content from sources.",
|
|
141
|
+
active: true,
|
|
142
|
+
options: { watch: {
|
|
143
|
+
type: "boolean",
|
|
144
|
+
default: false
|
|
145
|
+
} },
|
|
146
|
+
action: async (options, cli) => {
|
|
147
|
+
await cli.runtime.sources.load();
|
|
148
|
+
await cli.runtime.builder.build();
|
|
149
|
+
if (options.get_boolean_option("watch")) await cli.runtime.sources.watch();
|
|
150
|
+
}
|
|
151
|
+
}).add(create_command).run(process.argv.slice(2));
|
|
152
|
+
//#endregion
|
|
153
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ParseArgsConfig } from "node:util";
|
|
2
|
+
import { sleetch_runtime } from "@sleetch/core/compiler";
|
|
3
|
+
//#region src/lib/cli.d.ts
|
|
4
|
+
declare class sleetch_cli {
|
|
5
|
+
runtime: sleetch_runtime;
|
|
6
|
+
commands: command[];
|
|
7
|
+
private fallback?;
|
|
8
|
+
constructor();
|
|
9
|
+
add(command: command): this;
|
|
10
|
+
resolve(args: string[]): {
|
|
11
|
+
found: true;
|
|
12
|
+
command: command;
|
|
13
|
+
args: string[];
|
|
14
|
+
} | {
|
|
15
|
+
found: false;
|
|
16
|
+
error: string;
|
|
17
|
+
type: string;
|
|
18
|
+
};
|
|
19
|
+
run(args: string[]): void;
|
|
20
|
+
error(type: string, error: string): void;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/types/command.d.ts
|
|
24
|
+
type command_options = NonNullable<ParseArgsConfig['options']>;
|
|
25
|
+
type BooleanOptionKeys<O extends command_options> = { [K in keyof O]: O[K] extends {
|
|
26
|
+
type: 'boolean';
|
|
27
|
+
} ? K : never; }[keyof O];
|
|
28
|
+
type StringOptionKeys<O extends command_options> = { [K in keyof O]: O[K] extends {
|
|
29
|
+
type: 'string';
|
|
30
|
+
} ? K : never; }[keyof O];
|
|
31
|
+
type command_action<O extends command_options> = (options: {
|
|
32
|
+
args: string[];
|
|
33
|
+
get_boolean_option: <K extends BooleanOptionKeys<O>>(name: K) => boolean | undefined;
|
|
34
|
+
get_string_option: <K extends StringOptionKeys<O>>(name: K) => string | undefined;
|
|
35
|
+
}, cli: sleetch_cli) => void;
|
|
36
|
+
type command<O extends command_options = {}> = {
|
|
37
|
+
name: string;
|
|
38
|
+
description: string;
|
|
39
|
+
options: O;
|
|
40
|
+
fallback?: boolean;
|
|
41
|
+
action: command_action<O>;
|
|
42
|
+
subcommands?: command<any>[];
|
|
43
|
+
active: boolean;
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/commands/create/index.d.ts
|
|
47
|
+
declare const create_command: command;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { create_command };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createReadStream, createWriteStream, existsSync } from "node:fs";
|
|
2
|
+
import { pipeline } from "node:stream";
|
|
3
|
+
import { promisify, styleText } from "node:util";
|
|
4
|
+
import zlib from "node:zlib";
|
|
5
|
+
import tar from "tar-fs";
|
|
6
|
+
import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
//#region package.json
|
|
10
|
+
var version = "1.0.6";
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/commands/create/index.ts
|
|
13
|
+
const create_command = {
|
|
14
|
+
name: "create",
|
|
15
|
+
description: "Create.",
|
|
16
|
+
options: {},
|
|
17
|
+
active: false,
|
|
18
|
+
action: (options, cli) => {
|
|
19
|
+
console.log("create", options);
|
|
20
|
+
},
|
|
21
|
+
subcommands: [{
|
|
22
|
+
name: "app",
|
|
23
|
+
options: {
|
|
24
|
+
name: { type: "string" },
|
|
25
|
+
framework: {
|
|
26
|
+
type: "string",
|
|
27
|
+
default: "react-router"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
description: "Create app.",
|
|
31
|
+
active: true,
|
|
32
|
+
action: async (options, cli) => {
|
|
33
|
+
const temp_directory = path.join(tmpdir(), "sleetch");
|
|
34
|
+
const cwd = process.cwd();
|
|
35
|
+
const source_code_tarball_url = "https://github.com/sleetch/sleetch/archive/main.tar.gz";
|
|
36
|
+
const source_code_download_path = path.join(temp_directory, "source.tar.gz");
|
|
37
|
+
const source_code_extract_path = temp_directory;
|
|
38
|
+
await rm(temp_directory, {
|
|
39
|
+
recursive: true,
|
|
40
|
+
force: true
|
|
41
|
+
});
|
|
42
|
+
await mkdir(temp_directory, { recursive: true });
|
|
43
|
+
const templates = {
|
|
44
|
+
"react-router": "/sleetch-main/templates/react-router",
|
|
45
|
+
"next-js": "/sleetch-main/templates/next"
|
|
46
|
+
};
|
|
47
|
+
const name = options.get_string_option("name");
|
|
48
|
+
const framework = options.get_string_option("framework");
|
|
49
|
+
if (name == void 0) return cli.error("missing arg", "name is missing.");
|
|
50
|
+
if (framework == void 0) return cli.error("missing arg", "framework is missing.");
|
|
51
|
+
if (!Object.keys(templates).includes(framework)) return cli.error("bad option", "framework must be : " + Object.keys(templates).join(" / "));
|
|
52
|
+
const final_template_directory = path.join(cwd, name);
|
|
53
|
+
if (existsSync(final_template_directory)) return cli.error("error", final_template_directory + " already exist on your filesystem.");
|
|
54
|
+
await mkdir(final_template_directory, { recursive: true });
|
|
55
|
+
const response = await fetch(source_code_tarball_url);
|
|
56
|
+
if (response.ok && response.body) {
|
|
57
|
+
await promisify(pipeline)(response.body, createWriteStream(source_code_download_path));
|
|
58
|
+
await promisify(pipeline)(createReadStream(source_code_download_path), zlib.createGunzip(), tar.extract(source_code_extract_path, {}));
|
|
59
|
+
const temp_project_path = path.join(temp_directory, templates[framework]);
|
|
60
|
+
const temp_project_package_json_path = path.join(temp_directory, templates[framework], "package.json");
|
|
61
|
+
const package_json_content = await readFile(temp_project_package_json_path, { encoding: "utf-8" });
|
|
62
|
+
await writeFile(temp_project_package_json_path, package_json_content.replaceAll("workspace:*", version), { encoding: "utf-8" });
|
|
63
|
+
await cp(temp_project_path, final_template_directory, { recursive: true });
|
|
64
|
+
await rm(temp_directory, {
|
|
65
|
+
recursive: true,
|
|
66
|
+
force: true
|
|
67
|
+
});
|
|
68
|
+
} else return cli.error("error", "could not fetch the template.");
|
|
69
|
+
const lines = [`${styleText("cyan", "sleetch") + styleText("cyanBright", ".dev")} is a powerful documentation framework.`];
|
|
70
|
+
lines.push("");
|
|
71
|
+
lines.push(`The sleetch ${styleText("dim", framework)} documentation template has been downloaded. I hope it will be useful for ${styleText("dim", name)}. `);
|
|
72
|
+
lines.push("");
|
|
73
|
+
lines.push(`Check your project: cd ./${name} `);
|
|
74
|
+
lines.push(`Install the dependencies: ${styleText("cyan", "bun") + styleText("dim", "/") + styleText("white", "npm") + styleText("dim", "/") + styleText("white", "pnpm")} install`);
|
|
75
|
+
lines.push("");
|
|
76
|
+
lines.push(`Learn more: ${styleText("gray", "https://") + styleText("cyan", "sleetch") + styleText("cyanBright", ".dev")} `);
|
|
77
|
+
lines.push(` ${styleText("gray", "https://github.com/tornado-softwares/") + styleText("cyan", "sleetch")}`);
|
|
78
|
+
console.log(lines.join("\n"));
|
|
79
|
+
}
|
|
80
|
+
}]
|
|
81
|
+
};
|
|
82
|
+
//#endregion
|
|
83
|
+
export { create_command as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sleetch/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -13,15 +13,20 @@
|
|
|
13
13
|
"dev": "tsdown --watch"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@sleetch/core": "1.0.
|
|
16
|
+
"@sleetch/core": "1.0.6",
|
|
17
|
+
"tar-fs": "^3.1.3",
|
|
17
18
|
"zod": "^4.4.3"
|
|
18
19
|
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/tar-fs": "^2.0.4"
|
|
22
|
+
},
|
|
19
23
|
"exports": {
|
|
20
|
-
"
|
|
24
|
+
"./bin": "./dist/bin/index.js",
|
|
25
|
+
"./commands/create": "./dist/commands/create/index.js",
|
|
21
26
|
"./package.json": "./package.json"
|
|
22
27
|
},
|
|
23
28
|
"bin": {
|
|
24
|
-
"sleetch": "./dist/index.js"
|
|
29
|
+
"sleetch": "./dist/bin/index.js"
|
|
25
30
|
},
|
|
26
31
|
"types": "./dist/index.d.ts",
|
|
27
32
|
"main": "./dist/index.js",
|
package/dist/index.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { styleText } from "node:util";
|
|
3
|
-
import { sleetch_runtime } from "@sleetch/core/compiler";
|
|
4
|
-
//#region src/commands/build.ts
|
|
5
|
-
const build_command = {
|
|
6
|
-
name: "build",
|
|
7
|
-
description: "Prebuild the content from sources.",
|
|
8
|
-
action: async (args, cli) => {
|
|
9
|
-
await cli.runtime.sources.load();
|
|
10
|
-
await cli.runtime.builder.build();
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
//#endregion
|
|
14
|
-
//#region src/commands/help.ts
|
|
15
|
-
const help_command = {
|
|
16
|
-
name: "help",
|
|
17
|
-
description: "Get available commands.",
|
|
18
|
-
fallback: true,
|
|
19
|
-
action: (args, cli) => {
|
|
20
|
-
let lines = [
|
|
21
|
-
`${styleText("green", "sleetch") + styleText("greenBright", ".net")} is a powerful documentation framework.`,
|
|
22
|
-
"",
|
|
23
|
-
`Usage: ${styleText("green", "sleetch")} ${styleText("gray", "<command>")} ${styleText("greenBright", "[...args]")}`,
|
|
24
|
-
"",
|
|
25
|
-
"Commands:",
|
|
26
|
-
""
|
|
27
|
-
];
|
|
28
|
-
for (const command of cli.commands) lines.push(` ${styleText("green", command.name)} ${styleText("gray", "-")} ${command.description}`);
|
|
29
|
-
lines.push("");
|
|
30
|
-
lines.push(`Learn more: ${styleText("gray", "https://") + styleText("green", "sleetch") + styleText("greenBright", ".net")} `);
|
|
31
|
-
lines.push(` ${styleText("gray", "https://github.com/tornado-softwares/") + styleText("green", "sleetch")}`);
|
|
32
|
-
console.log(lines.join("\n"));
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
//#endregion
|
|
36
|
-
//#region src/commands/watch.ts
|
|
37
|
-
const watch_command = {
|
|
38
|
-
name: "watch",
|
|
39
|
-
description: "Prebuild the content from sources.",
|
|
40
|
-
action: async (args, cli) => {
|
|
41
|
-
await cli.runtime.sources.load();
|
|
42
|
-
await cli.runtime.builder.build();
|
|
43
|
-
await cli.runtime.sources.watch();
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
//#endregion
|
|
47
|
-
//#region src/lib/cli.ts
|
|
48
|
-
var sleetch_cli = class {
|
|
49
|
-
runtime = new sleetch_runtime();
|
|
50
|
-
commands = [];
|
|
51
|
-
fallback;
|
|
52
|
-
constructor() {}
|
|
53
|
-
add(command) {
|
|
54
|
-
this.commands.push(command);
|
|
55
|
-
if (command.fallback == true) this.fallback = command;
|
|
56
|
-
return this;
|
|
57
|
-
}
|
|
58
|
-
run(args) {
|
|
59
|
-
if (args.length == 0) {
|
|
60
|
-
if (this.fallback) this.fallback.action([], this);
|
|
61
|
-
else console.error(`sleetch: no command `);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const [command_name, ...command_args] = args;
|
|
65
|
-
console.log(command_name);
|
|
66
|
-
for (const command of this.commands) if (command_name == command.name) {
|
|
67
|
-
command.action(command_args, this);
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
console.error(`sleetch: bad option: ${command_name}`);
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
//#endregion
|
|
74
|
-
//#region src/bin/index.ts
|
|
75
|
-
new sleetch_cli().add(help_command).add(build_command).add(watch_command).run(process.argv.slice(2));
|
|
76
|
-
//#endregion
|
|
77
|
-
export {};
|
|
File without changes
|