@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,2 @@
1
+ import { t as create_command } from "../../create-C1erDXXt.js";
2
+ 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.4",
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.4",
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
- ".": "./dist/index.js",
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