@sleetch/cli 1.0.5 → 1.0.7

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,157 @@
1
+ #!/usr/bin/env node
2
+ import { t as create_command } from "../create-DWUgFzD_.js";
3
+ import { parseArgs, styleText } from "node:util";
4
+ //#endregion
5
+ //#region src/bin/index.ts
6
+ new class sleetch_cli {
7
+ commands = [];
8
+ fallback;
9
+ constructor() {}
10
+ add(command) {
11
+ this.commands.push(command);
12
+ if (command.active == true && command.fallback == true) this.fallback = command;
13
+ return this;
14
+ }
15
+ resolve(args) {
16
+ if (args.length == 0) {
17
+ if (this.fallback) return {
18
+ found: true,
19
+ command: this.fallback,
20
+ args
21
+ };
22
+ return {
23
+ found: false,
24
+ type: "empty args",
25
+ error: "no command found"
26
+ };
27
+ }
28
+ const [command_name, ...command_args] = args;
29
+ for (const command of this.commands) if (command_name == command.name) {
30
+ if (!command.subcommands || command.subcommands.length == 0) {
31
+ if (command.active) return {
32
+ found: true,
33
+ command,
34
+ args: command_args
35
+ };
36
+ else return {
37
+ found: false,
38
+ type: "bad option",
39
+ error: "inactive command: " + command_name
40
+ };
41
+ } else {
42
+ const sub_cli = new sleetch_cli();
43
+ sub_cli.add({
44
+ ...command,
45
+ fallback: true
46
+ });
47
+ for (const sub_command of command.subcommands) sub_cli.add(sub_command);
48
+ const sub_command = sub_cli.resolve(command_args);
49
+ if (sub_command.found) return sub_command;
50
+ else if (command.active) return {
51
+ found: true,
52
+ command,
53
+ args: command_args
54
+ };
55
+ }
56
+ }
57
+ return {
58
+ found: false,
59
+ type: "bad option",
60
+ error: args.join(" ")
61
+ };
62
+ }
63
+ run(args) {
64
+ const resolve = this.resolve(args);
65
+ if (resolve.found == true) {
66
+ const { command, args } = resolve;
67
+ const parsed = parseArgs({
68
+ args,
69
+ options: command.options,
70
+ allowPositionals: true,
71
+ strict: false
72
+ });
73
+ const get_boolean_option = (name) => {
74
+ const value = parsed.values[name];
75
+ return typeof value === "boolean" ? value : void 0;
76
+ };
77
+ const get_string_option = (name) => {
78
+ const value = parsed.values[name];
79
+ return typeof value === "string" ? value : void 0;
80
+ };
81
+ command.action({
82
+ args,
83
+ get_boolean_option,
84
+ get_string_option
85
+ }, this);
86
+ } else {
87
+ const { error, type } = resolve;
88
+ this.error(type, error);
89
+ }
90
+ }
91
+ error(type, error) {
92
+ console.error(styleText("red", `sleetch: ${type}: ${error}`));
93
+ }
94
+ }().add({
95
+ name: "help",
96
+ description: "Get available commands.",
97
+ active: true,
98
+ options: {},
99
+ fallback: true,
100
+ action: (options, cli) => {
101
+ let lines = [
102
+ `${styleText("cyan", "sleetch") + styleText("cyanBright", ".dev")} is a powerful documentation framework.`,
103
+ "",
104
+ `Usage: ${styleText("cyan", "sleetch")} ${styleText("gray", "<command>")} ${styleText("cyanBright", "[...args]")}`,
105
+ "",
106
+ "Commands:",
107
+ ""
108
+ ];
109
+ const format_option = (name, option) => {
110
+ const parts = [];
111
+ if (option.short) parts.push(`-${option.short}`);
112
+ parts.push(`--${name}`);
113
+ if (option.type === "string") parts[parts.length - 1] += ` <${name}>`;
114
+ let result = parts.join(", ");
115
+ if (option.type) result += ` ${styleText("gray", `- ${String(option.type)}`)}`;
116
+ if (option.default) result += ` ${styleText("gray", `- default=${String(option.default)}`)}`;
117
+ return result;
118
+ };
119
+ const add_commands_lines = (commands, pre_args = []) => {
120
+ for (const command of commands) {
121
+ const path = [...pre_args, command.name];
122
+ if (command.active) {
123
+ lines.push(` ${styleText("cyan", path.join(" "))} ${styleText("gray", "-")} ${command.description}`);
124
+ const options = Object.entries(command.options);
125
+ if (options.length > 0) for (const [name, option] of options) lines.push(` ${styleText("dim", format_option(name, option))}`);
126
+ }
127
+ if (command.subcommands) add_commands_lines(command.subcommands, path);
128
+ }
129
+ };
130
+ add_commands_lines(cli.commands);
131
+ lines.push("");
132
+ lines.push(`Learn more: ${styleText("gray", "https://") + styleText("cyan", "sleetch") + styleText("cyanBright", ".dev")} `);
133
+ lines.push(` ${styleText("gray", "https://github.com/tornado-softwares/") + styleText("cyan", "sleetch")}`);
134
+ console.log(lines.join("\n"));
135
+ }
136
+ }).add({
137
+ name: "build",
138
+ description: "Prebuild the content from sources.",
139
+ active: true,
140
+ options: { watch: {
141
+ type: "boolean",
142
+ default: false
143
+ } },
144
+ action: async (options, cli) => {
145
+ try {
146
+ const { sleetch_runtime } = await import("@sleetch/core/compiler");
147
+ const runtime = new sleetch_runtime();
148
+ await runtime.sources.load();
149
+ await runtime.builder.build();
150
+ if (options.get_boolean_option("watch")) await runtime.sources.watch();
151
+ } catch (error) {
152
+ if (error instanceof Error) cli.error("error", error.message);
153
+ }
154
+ }
155
+ }).add(create_command).run(process.argv.slice(2));
156
+ //#endregion
157
+ export {};
@@ -0,0 +1,47 @@
1
+ import { ParseArgsConfig } from "node:util";
2
+ //#region src/lib/cli.d.ts
3
+ declare class sleetch_cli {
4
+ commands: command[];
5
+ private fallback?;
6
+ constructor();
7
+ add(command: command): this;
8
+ resolve(args: string[]): {
9
+ found: true;
10
+ command: command;
11
+ args: string[];
12
+ } | {
13
+ found: false;
14
+ error: string;
15
+ type: string;
16
+ };
17
+ run(args: string[]): void;
18
+ error(type: string, error: string): void;
19
+ }
20
+ //#endregion
21
+ //#region src/types/command.d.ts
22
+ type command_options = NonNullable<ParseArgsConfig['options']>;
23
+ type BooleanOptionKeys<O extends command_options> = { [K in keyof O]: O[K] extends {
24
+ type: 'boolean';
25
+ } ? K : never; }[keyof O];
26
+ type StringOptionKeys<O extends command_options> = { [K in keyof O]: O[K] extends {
27
+ type: 'string';
28
+ } ? K : never; }[keyof O];
29
+ type command_action<O extends command_options> = (options: {
30
+ args: string[];
31
+ get_boolean_option: <K extends BooleanOptionKeys<O>>(name: K) => boolean | undefined;
32
+ get_string_option: <K extends StringOptionKeys<O>>(name: K) => string | undefined;
33
+ }, cli: sleetch_cli) => void;
34
+ type command<O extends command_options = {}> = {
35
+ name: string;
36
+ description: string;
37
+ options: O;
38
+ fallback?: boolean;
39
+ action: command_action<O>;
40
+ subcommands?: command<any>[];
41
+ active: boolean;
42
+ };
43
+ //#endregion
44
+ //#region src/commands/create/index.d.ts
45
+ declare const create_command: command;
46
+ //#endregion
47
+ export { create_command };
@@ -0,0 +1,2 @@
1
+ import { t as create_command } from "../../create-DWUgFzD_.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.7";
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-webpack": "/sleetch-main/templates/next-webpack"
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.5",
3
+ "version": "1.0.7",
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.5",
16
+ "@sleetch/core": "1.0.7",
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("cyan", "sleetch") + styleText("cyanBright", ".net")} is a powerful documentation framework.`,
22
- "",
23
- `Usage: ${styleText("cyan", "sleetch")} ${styleText("gray", "<command>")} ${styleText("cyanBright", "[...args]")}`,
24
- "",
25
- "Commands:",
26
- ""
27
- ];
28
- for (const command of cli.commands) lines.push(` ${styleText("cyan", command.name)} ${styleText("gray", "-")} ${command.description}`);
29
- lines.push("");
30
- lines.push(`Learn more: ${styleText("gray", "https://") + styleText("cyan", "sleetch") + styleText("cyanBright", ".dev")} `);
31
- lines.push(` ${styleText("gray", "https://github.com/tornado-softwares/") + styleText("cyan", "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