@briklab/lib 1.0.0
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 +16 -0
- package/dist/cli-john/index.d.ts +135 -0
- package/dist/cli-john/index.js +308 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1 -0
- package/dist/jstc/index.d.ts +22 -0
- package/dist/jstc/index.js +69 -0
- package/dist/stylesheet/index.d.ts +5 -0
- package/dist/stylesheet/index.js +1 -0
- package/package.json +53 -0
- package/tsconfig.json +21 -0
package/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# @briklab/lib
|
|
2
|
+
|
|
3
|
+
### @briklab/lib is the core package for briklab packages
|
|
4
|
+
|
|
5
|
+
**It Introduces:**
|
|
6
|
+
- **@briklab/cli-john:** Generate a [CLI](https://en.wikipedia.org/wiki/Command-line_interface) with ease.
|
|
7
|
+
- **@briklab/jstc:** Add Type Checking for JavaScript.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
Normally, the format is:
|
|
11
|
+
```bash
|
|
12
|
+
[packageManager] install/add/i @briklab/lib
|
|
13
|
+
```
|
|
14
|
+
**Examples:**
|
|
15
|
+
- **pnpm:**`pnpm add @briklab/lib`
|
|
16
|
+
- **npm:**`npm i @briklab/lib`
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
*
|
|
4
|
+
* # CLI John
|
|
5
|
+
*
|
|
6
|
+
* **CLI John** is a **Node.js CLI framework** designed to create **fully functional CLIs** quickly.
|
|
7
|
+
* It hooks into a given NodeJS process, automatically listens for commands, parses arguments,
|
|
8
|
+
* and allows beautiful console messages. Its design is **modular**, using Commands and Options as sub-classes.
|
|
9
|
+
*
|
|
10
|
+
* ## Features
|
|
11
|
+
* - Auto-listening to commands
|
|
12
|
+
* - Command parsing
|
|
13
|
+
* - Beautiful console messages
|
|
14
|
+
* - One CLI per file
|
|
15
|
+
* - Add your file to `bin` in package.json → CLI works seamlessly
|
|
16
|
+
* - Event-driven command handling
|
|
17
|
+
*
|
|
18
|
+
* ## Usage
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { CLI as CLI } from "@briklab/lib/cli-john"
|
|
21
|
+
* import * as process from "node:process"
|
|
22
|
+
*
|
|
23
|
+
* const cli = new CLI(process);
|
|
24
|
+
*
|
|
25
|
+
* const cmd = cli.command("myCommand");
|
|
26
|
+
* const opt = cmd.option("force");
|
|
27
|
+
*
|
|
28
|
+
* cmd.on("run", ({commandArgs}) => {
|
|
29
|
+
* CJ.notice("Hey, this is my CLI!");
|
|
30
|
+
* CJ.message("Do you like it?");
|
|
31
|
+
* CJ.error("Invalid args:", ...commandArgs.map(a => a.name));
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* cli.run();
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* ## Limitations
|
|
38
|
+
* - Only **one CLI per file** is allowed (CLI enforces this)
|
|
39
|
+
* - CLI file must be manually added to `bin` in package.json
|
|
40
|
+
*
|
|
41
|
+
* ## Hierarchy
|
|
42
|
+
* ```
|
|
43
|
+
* CLI
|
|
44
|
+
* ├─ Command
|
|
45
|
+
* │ └─ Option
|
|
46
|
+
* └─ CLIErrors
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* ## Error Handling
|
|
50
|
+
* - All errors are instances of `CLIErrors`
|
|
51
|
+
* - Dynamic names allow easy identification of which part of the CLI threw the error
|
|
52
|
+
*
|
|
53
|
+
* @module cli-john
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* # CLI
|
|
57
|
+
* @classdesc The main class for **CLI**.
|
|
58
|
+
* @example
|
|
59
|
+
* import * as process from "node:process"
|
|
60
|
+
* import {CLI} from "@briklab/lib/cli-john"
|
|
61
|
+
* const cli = new CLI(process)
|
|
62
|
+
* cli.run()
|
|
63
|
+
*/
|
|
64
|
+
export declare class CLI {
|
|
65
|
+
#private;
|
|
66
|
+
/**
|
|
67
|
+
* ## CLI: Constructor
|
|
68
|
+
* @param {NodeJS.Process} process - **The main process**
|
|
69
|
+
* @constructor
|
|
70
|
+
* @constructs CLI
|
|
71
|
+
* @example
|
|
72
|
+
* import * as process from "node:process"
|
|
73
|
+
* import {CLI} from "@briklab/lib/cli-john"
|
|
74
|
+
* const cli = new CLI(process)
|
|
75
|
+
* cli.run()
|
|
76
|
+
*/
|
|
77
|
+
constructor(process: NodeJS.Process);
|
|
78
|
+
/**
|
|
79
|
+
* ### CLI.command
|
|
80
|
+
* create a new command in a CLI.
|
|
81
|
+
*
|
|
82
|
+
* @param {string} name
|
|
83
|
+
*/
|
|
84
|
+
command(name: string): CLI.Command;
|
|
85
|
+
on(event: CLI.ValidEvent, func: Function): void;
|
|
86
|
+
run(): void;
|
|
87
|
+
}
|
|
88
|
+
export declare namespace CLI {
|
|
89
|
+
const ValidEvents: readonly ["command"];
|
|
90
|
+
type ValidEvent = typeof ValidEvents[number];
|
|
91
|
+
/**
|
|
92
|
+
* ## CLI.Command
|
|
93
|
+
* A command in a CLI Command
|
|
94
|
+
*/
|
|
95
|
+
class Command {
|
|
96
|
+
#private;
|
|
97
|
+
/**
|
|
98
|
+
* ### Command Constructor
|
|
99
|
+
* @param name The name of the command
|
|
100
|
+
* @constructor
|
|
101
|
+
*/
|
|
102
|
+
constructor(name: string);
|
|
103
|
+
/**
|
|
104
|
+
* The name of the Command
|
|
105
|
+
* @returns {string}
|
|
106
|
+
*/
|
|
107
|
+
get name(): String;
|
|
108
|
+
/**
|
|
109
|
+
* the metadata of the Command
|
|
110
|
+
* @returns {object}
|
|
111
|
+
*/
|
|
112
|
+
get metadata(): Object;
|
|
113
|
+
option(name: string): Command.Option;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
export declare namespace CLI.Command {
|
|
117
|
+
/**
|
|
118
|
+
* ## CLI.Command.Option
|
|
119
|
+
* A option for a CLI.Command
|
|
120
|
+
*/
|
|
121
|
+
class Option {
|
|
122
|
+
#private;
|
|
123
|
+
get metadata(): {
|
|
124
|
+
name: string;
|
|
125
|
+
};
|
|
126
|
+
constructor(name: string);
|
|
127
|
+
get name(): string;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Will be implemented in v1.2.0
|
|
132
|
+
* @experimental v1.2.0
|
|
133
|
+
*/
|
|
134
|
+
export declare namespace Utilities {
|
|
135
|
+
}
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
*
|
|
4
|
+
* # CLI John
|
|
5
|
+
*
|
|
6
|
+
* **CLI John** is a **Node.js CLI framework** designed to create **fully functional CLIs** quickly.
|
|
7
|
+
* It hooks into a given NodeJS process, automatically listens for commands, parses arguments,
|
|
8
|
+
* and allows beautiful console messages. Its design is **modular**, using Commands and Options as sub-classes.
|
|
9
|
+
*
|
|
10
|
+
* ## Features
|
|
11
|
+
* - Auto-listening to commands
|
|
12
|
+
* - Command parsing
|
|
13
|
+
* - Beautiful console messages
|
|
14
|
+
* - One CLI per file
|
|
15
|
+
* - Add your file to `bin` in package.json → CLI works seamlessly
|
|
16
|
+
* - Event-driven command handling
|
|
17
|
+
*
|
|
18
|
+
* ## Usage
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { CLI as CLI } from "@briklab/lib/cli-john"
|
|
21
|
+
* import * as process from "node:process"
|
|
22
|
+
*
|
|
23
|
+
* const cli = new CLI(process);
|
|
24
|
+
*
|
|
25
|
+
* const cmd = cli.command("myCommand");
|
|
26
|
+
* const opt = cmd.option("force");
|
|
27
|
+
*
|
|
28
|
+
* cmd.on("run", ({commandArgs}) => {
|
|
29
|
+
* CJ.notice("Hey, this is my CLI!");
|
|
30
|
+
* CJ.message("Do you like it?");
|
|
31
|
+
* CJ.error("Invalid args:", ...commandArgs.map(a => a.name));
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* cli.run();
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* ## Limitations
|
|
38
|
+
* - Only **one CLI per file** is allowed (CLI enforces this)
|
|
39
|
+
* - CLI file must be manually added to `bin` in package.json
|
|
40
|
+
*
|
|
41
|
+
* ## Hierarchy
|
|
42
|
+
* ```
|
|
43
|
+
* CLI
|
|
44
|
+
* ├─ Command
|
|
45
|
+
* │ └─ Option
|
|
46
|
+
* └─ CLIErrors
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* ## Error Handling
|
|
50
|
+
* - All errors are instances of `CLIErrors`
|
|
51
|
+
* - Dynamic names allow easy identification of which part of the CLI threw the error
|
|
52
|
+
*
|
|
53
|
+
* @module cli-john
|
|
54
|
+
*/
|
|
55
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
56
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
57
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
58
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
59
|
+
};
|
|
60
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
61
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
62
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
63
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
64
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
65
|
+
};
|
|
66
|
+
var _CLI_instances, _CLI_commands, _CLI_onCmdFunctions, _CLI_figureOutCommand, _CLI_process, _CLI_ErrorClass, _CLI_createErr, _CLI_createWarn;
|
|
67
|
+
import JSTC from "../jstc";
|
|
68
|
+
JSTC.addCustomHandler("NodeJS Process", (p) => {
|
|
69
|
+
return (p &&
|
|
70
|
+
typeof p === "object" &&
|
|
71
|
+
typeof p.pid === "number" &&
|
|
72
|
+
typeof p.cwd === "function" &&
|
|
73
|
+
typeof p.exit === "function");
|
|
74
|
+
});
|
|
75
|
+
//#endregion
|
|
76
|
+
// -------------------------------------------------------------------------------------------------------
|
|
77
|
+
//#region The Main Class
|
|
78
|
+
/**
|
|
79
|
+
* # CLI
|
|
80
|
+
* @classdesc The main class for **CLI**.
|
|
81
|
+
* @example
|
|
82
|
+
* import * as process from "node:process"
|
|
83
|
+
* import {CLI} from "@briklab/lib/cli-john"
|
|
84
|
+
* const cli = new CLI(process)
|
|
85
|
+
* cli.run()
|
|
86
|
+
*/
|
|
87
|
+
export class CLI {
|
|
88
|
+
/**
|
|
89
|
+
* ## CLI: Constructor
|
|
90
|
+
* @param {NodeJS.Process} process - **The main process**
|
|
91
|
+
* @constructor
|
|
92
|
+
* @constructs CLI
|
|
93
|
+
* @example
|
|
94
|
+
* import * as process from "node:process"
|
|
95
|
+
* import {CLI} from "@briklab/lib/cli-john"
|
|
96
|
+
* const cli = new CLI(process)
|
|
97
|
+
* cli.run()
|
|
98
|
+
*/
|
|
99
|
+
constructor(process) {
|
|
100
|
+
_CLI_instances.add(this);
|
|
101
|
+
_CLI_commands.set(this, []);
|
|
102
|
+
_CLI_onCmdFunctions.set(this, []);
|
|
103
|
+
_CLI_process.set(this, void 0);
|
|
104
|
+
_CLI_ErrorClass.set(this, class extends CLIErrors {
|
|
105
|
+
constructor(message) {
|
|
106
|
+
super(message);
|
|
107
|
+
this.setName = "CLI";
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
if (!JSTC.for([process]).check(["NodeJS Process"])) {
|
|
111
|
+
throw __classPrivateFieldGet(this, _CLI_instances, "m", _CLI_createErr).call(this, "Invalid First Argument!", "You must pass a valid NodeJS process (imported from node:process) while constructing a CLI Class!");
|
|
112
|
+
}
|
|
113
|
+
__classPrivateFieldSet(this, _CLI_process, process, "f");
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* ### CLI.command
|
|
117
|
+
* create a new command in a CLI.
|
|
118
|
+
*
|
|
119
|
+
* @param {string} name
|
|
120
|
+
*/
|
|
121
|
+
command(name) {
|
|
122
|
+
if (!JSTC.for([name]).check(["string"])) {
|
|
123
|
+
__classPrivateFieldGet(this, _CLI_instances, "m", _CLI_createWarn).call(this, "Invalid First Argument!", "CLI.option expects a string as the first argument.", "Using String(given argument) as fallback.");
|
|
124
|
+
name = String(name);
|
|
125
|
+
}
|
|
126
|
+
let c = new CLI.Command(name);
|
|
127
|
+
let f = __classPrivateFieldGet(this, _CLI_commands, "f").findIndex((a) => a.name === name);
|
|
128
|
+
if (f !== -1)
|
|
129
|
+
__classPrivateFieldGet(this, _CLI_commands, "f")[f] = c;
|
|
130
|
+
else
|
|
131
|
+
__classPrivateFieldGet(this, _CLI_commands, "f").push(c);
|
|
132
|
+
return c;
|
|
133
|
+
}
|
|
134
|
+
on(event, func) {
|
|
135
|
+
if (!JSTC.for([event, func]).check(["string", "function"]))
|
|
136
|
+
throw __classPrivateFieldGet(this, _CLI_instances, "m", _CLI_createErr).call(this, "Arguments in CLI.on are invalid!", "The first argument must be a string, and the second argument must be a function.");
|
|
137
|
+
switch (event.toLowerCase()) {
|
|
138
|
+
case "command":
|
|
139
|
+
__classPrivateFieldGet(this, _CLI_onCmdFunctions, "f").push(func);
|
|
140
|
+
break;
|
|
141
|
+
default:
|
|
142
|
+
__classPrivateFieldGet(this, _CLI_instances, "m", _CLI_createWarn).call(this, "Invalid event in CLI.on", "Please enter a valid event from CLI.ValidEvents (array)");
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
run() {
|
|
146
|
+
let { options, commandArgs, command, failed } = __classPrivateFieldGet(this, _CLI_instances, "m", _CLI_figureOutCommand).call(this);
|
|
147
|
+
if (failed)
|
|
148
|
+
return;
|
|
149
|
+
for (let i = 0; i < __classPrivateFieldGet(this, _CLI_onCmdFunctions, "f").length; i++) {
|
|
150
|
+
__classPrivateFieldGet(this, _CLI_onCmdFunctions, "f")[i]({ options, commandArgs, command });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
_CLI_commands = new WeakMap(), _CLI_onCmdFunctions = new WeakMap(), _CLI_process = new WeakMap(), _CLI_ErrorClass = new WeakMap(), _CLI_instances = new WeakSet(), _CLI_figureOutCommand = function _CLI_figureOutCommand() {
|
|
155
|
+
// for eg. we have nodepath filepath cli build
|
|
156
|
+
let [, , ...commands] = __classPrivateFieldGet(this, _CLI_process, "f").argv; // now its cli build. clear
|
|
157
|
+
if (commands.length === 0)
|
|
158
|
+
return { options: [], command: "", commandArgs: [], failed: true };
|
|
159
|
+
let command = __classPrivateFieldGet(this, _CLI_commands, "f").find((a) => a.name === commands[0]); // find the command
|
|
160
|
+
if (!command)
|
|
161
|
+
return { options: [], command: "", commandArgs: [], failed: true }; // command not found?
|
|
162
|
+
let commandArgs = [];
|
|
163
|
+
const args = commands.slice(1);
|
|
164
|
+
for (let i = 0; i < args.length; i++) {
|
|
165
|
+
let arg = args[i];
|
|
166
|
+
if (arg.startsWith("--"))
|
|
167
|
+
break;
|
|
168
|
+
commandArgs.push(arg);
|
|
169
|
+
}
|
|
170
|
+
let leftover = args.slice(commandArgs.length); // args = [1,2,3]; command args = [1,2] command args length is 2, therefore .slice(2) results in [3]
|
|
171
|
+
let options = [];
|
|
172
|
+
for (let i = 0; i < leftover.length; i++) {
|
|
173
|
+
const opt = leftover[i];
|
|
174
|
+
if (!opt.startsWith("--"))
|
|
175
|
+
continue;
|
|
176
|
+
const values = [];
|
|
177
|
+
for (let j = i + 1; j < leftover.length; j++) {
|
|
178
|
+
if (leftover[j].startsWith("--"))
|
|
179
|
+
break;
|
|
180
|
+
values.push(leftover[j]);
|
|
181
|
+
}
|
|
182
|
+
options.push({ option: opt, arguments: values });
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
options,
|
|
186
|
+
commandArgs,
|
|
187
|
+
command,
|
|
188
|
+
failed: false,
|
|
189
|
+
};
|
|
190
|
+
}, _CLI_createErr = function _CLI_createErr(message, hint) {
|
|
191
|
+
return new (__classPrivateFieldGet(this, _CLI_ErrorClass, "f"))(`${message}
|
|
192
|
+
Hint: ${hint}`);
|
|
193
|
+
}, _CLI_createWarn = function _CLI_createWarn(message, hint, otherMessage) {
|
|
194
|
+
return console.warn(`[Class CLI] ${message}
|
|
195
|
+
Hint: ${hint}
|
|
196
|
+
${otherMessage}`);
|
|
197
|
+
};
|
|
198
|
+
//#endregion
|
|
199
|
+
// -------------------------------------------------------------------------------------------------------
|
|
200
|
+
//#region Error Class
|
|
201
|
+
class CLIErrors extends Error {
|
|
202
|
+
constructor(message) {
|
|
203
|
+
super(message);
|
|
204
|
+
this.name = `[] @briklab/lib/cli-john`;
|
|
205
|
+
Error.captureStackTrace(this, CLIErrors);
|
|
206
|
+
}
|
|
207
|
+
set setName(name) {
|
|
208
|
+
this.name = `[${name}] @briklab/lib/cli-john`;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
(function (CLI) {
|
|
212
|
+
var _Command_instances, _Command_name, _Command_createWarn, _Command_options;
|
|
213
|
+
CLI.ValidEvents = [
|
|
214
|
+
"command"
|
|
215
|
+
];
|
|
216
|
+
/**
|
|
217
|
+
* ## CLI.Command
|
|
218
|
+
* A command in a CLI Command
|
|
219
|
+
*/
|
|
220
|
+
class Command {
|
|
221
|
+
/**
|
|
222
|
+
* ### Command Constructor
|
|
223
|
+
* @param name The name of the command
|
|
224
|
+
* @constructor
|
|
225
|
+
*/
|
|
226
|
+
constructor(name) {
|
|
227
|
+
_Command_instances.add(this);
|
|
228
|
+
_Command_name.set(this, void 0);
|
|
229
|
+
_Command_options.set(this, []);
|
|
230
|
+
__classPrivateFieldSet(this, _Command_name, name, "f");
|
|
231
|
+
return this;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* The name of the Command
|
|
235
|
+
* @returns {string}
|
|
236
|
+
*/
|
|
237
|
+
get name() {
|
|
238
|
+
return __classPrivateFieldGet(this, _Command_name, "f");
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* the metadata of the Command
|
|
242
|
+
* @returns {object}
|
|
243
|
+
*/
|
|
244
|
+
get metadata() {
|
|
245
|
+
let metadata = {
|
|
246
|
+
options: __classPrivateFieldGet(this, _Command_options, "f").map((a) => a.metadata),
|
|
247
|
+
name: this.name,
|
|
248
|
+
};
|
|
249
|
+
return metadata;
|
|
250
|
+
}
|
|
251
|
+
option(name) {
|
|
252
|
+
if (!JSTC.for([name]).check(["string"])) {
|
|
253
|
+
__classPrivateFieldGet(this, _Command_instances, "m", _Command_createWarn).call(this, "First argument is invalid!", "The first argument must be a string", "Using String(argument) as fallback");
|
|
254
|
+
name = String(name);
|
|
255
|
+
}
|
|
256
|
+
let o = new CLI.Command.Option(name);
|
|
257
|
+
let f = __classPrivateFieldGet(this, _Command_options, "f").findIndex((a) => a.name === name);
|
|
258
|
+
if (f !== -1)
|
|
259
|
+
__classPrivateFieldGet(this, _Command_options, "f")[f] = o;
|
|
260
|
+
else
|
|
261
|
+
__classPrivateFieldGet(this, _Command_options, "f").push(o);
|
|
262
|
+
return o;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
_Command_name = new WeakMap(), _Command_options = new WeakMap(), _Command_instances = new WeakSet(), _Command_createWarn = function _Command_createWarn(message, hint, otherMessage) {
|
|
266
|
+
return console.warn(`[Class CLI.Command] ${message}
|
|
267
|
+
Hint: ${hint}
|
|
268
|
+
${otherMessage}`);
|
|
269
|
+
};
|
|
270
|
+
CLI.Command = Command;
|
|
271
|
+
})(CLI || (CLI = {}));
|
|
272
|
+
//#endregion
|
|
273
|
+
// -------------------------------------------------------------------------------------------------------
|
|
274
|
+
//#region CLI.Command.Option
|
|
275
|
+
(function (CLI) {
|
|
276
|
+
var Command;
|
|
277
|
+
(function (Command) {
|
|
278
|
+
var _Option_name;
|
|
279
|
+
/**
|
|
280
|
+
* ## CLI.Command.Option
|
|
281
|
+
* A option for a CLI.Command
|
|
282
|
+
*/
|
|
283
|
+
class Option {
|
|
284
|
+
get metadata() {
|
|
285
|
+
let metadata = {
|
|
286
|
+
name: `${__classPrivateFieldGet(this, _Option_name, "f")}`, // <-- Templates TO NOT reference the actual variable
|
|
287
|
+
};
|
|
288
|
+
return metadata;
|
|
289
|
+
}
|
|
290
|
+
constructor(name) {
|
|
291
|
+
_Option_name.set(this, void 0);
|
|
292
|
+
__classPrivateFieldSet(this, _Option_name, name, "f");
|
|
293
|
+
return this;
|
|
294
|
+
}
|
|
295
|
+
get name() {
|
|
296
|
+
return __classPrivateFieldGet(this, _Option_name, "f");
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
_Option_name = new WeakMap();
|
|
300
|
+
Command.Option = Option;
|
|
301
|
+
})(Command = CLI.Command || (CLI.Command = {}));
|
|
302
|
+
})(CLI || (CLI = {}));
|
|
303
|
+
//#endregion
|
|
304
|
+
// -------------------------------------------------------------------------------------------------------
|
|
305
|
+
//#region TODO
|
|
306
|
+
// TODO: Wire Options to Commands
|
|
307
|
+
// TODO: Create metadata getter-s in both commands and options
|
|
308
|
+
//#endregion
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Runtime JS Type Checker
|
|
4
|
+
* @module JSTC
|
|
5
|
+
*/
|
|
6
|
+
type PrimitiveType = "string" | "number" | "boolean" | "object" | "function" | "undefined" | "symbol" | "bigint";
|
|
7
|
+
type ConstructorType = Function;
|
|
8
|
+
export type JSType = PrimitiveType | ConstructorType | string;
|
|
9
|
+
export type JSTypeOrArray = JSType | JSType[];
|
|
10
|
+
export declare class JSTypeChecker {
|
|
11
|
+
#private;
|
|
12
|
+
/**
|
|
13
|
+
* check if specific arguments are of a specific type, class, etc.
|
|
14
|
+
* @param {unknown[]} args
|
|
15
|
+
*/
|
|
16
|
+
for(args: unknown[]): {
|
|
17
|
+
check: (types: JSTypeOrArray[]) => boolean;
|
|
18
|
+
};
|
|
19
|
+
addCustomHandler(name: string, handler: (value: unknown) => boolean): void;
|
|
20
|
+
}
|
|
21
|
+
declare const JSTC: JSTypeChecker;
|
|
22
|
+
export default JSTC;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Runtime JS Type Checker
|
|
4
|
+
* @module JSTC
|
|
5
|
+
*/
|
|
6
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
7
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
8
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
9
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
10
|
+
};
|
|
11
|
+
var _JSTypeChecker___CustomHandler;
|
|
12
|
+
export class JSTypeChecker {
|
|
13
|
+
constructor() {
|
|
14
|
+
_JSTypeChecker___CustomHandler.set(this, {
|
|
15
|
+
Array: (value) => Array.isArray(value),
|
|
16
|
+
"string[]": (value) => Array.isArray(value) && value.every((v) => typeof v === "string"),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* check if specific arguments are of a specific type, class, etc.
|
|
21
|
+
* @param {unknown[]} args
|
|
22
|
+
*/
|
|
23
|
+
for(args) {
|
|
24
|
+
return {
|
|
25
|
+
check: (types) => {
|
|
26
|
+
if (args.length < types.length)
|
|
27
|
+
return false;
|
|
28
|
+
for (let i = 0; i < types.length; i++) {
|
|
29
|
+
const value = args[i];
|
|
30
|
+
const expected = types[i];
|
|
31
|
+
const expectedTypes = Array.isArray(expected) ? expected : [expected];
|
|
32
|
+
let matched = false;
|
|
33
|
+
for (const tRaw of expectedTypes) {
|
|
34
|
+
const unionTypes = typeof tRaw === "string" ? tRaw.split("|") : [tRaw];
|
|
35
|
+
for (const t of unionTypes) {
|
|
36
|
+
if (typeof t === "function") {
|
|
37
|
+
if (value instanceof t) {
|
|
38
|
+
matched = true;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (typeof t === "string" && __classPrivateFieldGet(this, _JSTypeChecker___CustomHandler, "f")[t]) {
|
|
43
|
+
if (__classPrivateFieldGet(this, _JSTypeChecker___CustomHandler, "f")[t](value)) {
|
|
44
|
+
matched = true;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (typeof value === t) {
|
|
49
|
+
matched = true;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (matched)
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
if (!matched)
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
addCustomHandler(name, handler) {
|
|
64
|
+
__classPrivateFieldGet(this, _JSTypeChecker___CustomHandler, "f")[name] = handler;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
_JSTypeChecker___CustomHandler = new WeakMap();
|
|
68
|
+
const JSTC = new JSTypeChecker();
|
|
69
|
+
export default JSTC;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@briklab/lib",
|
|
3
|
+
"author": {
|
|
4
|
+
"email": "ekaanshagarwal19554@gmail.com",
|
|
5
|
+
"name": "ObiloxYT",
|
|
6
|
+
"url": "https://youtube.com/@ObiloxYT"
|
|
7
|
+
},
|
|
8
|
+
"contributors": [
|
|
9
|
+
"ObiloxYT"
|
|
10
|
+
],
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"markdown": "github",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"description": "@briklab/lib is the core library for all @briklab packages.",
|
|
17
|
+
"homepage": "https://github.com/EkaanshPC/briklab-stdlib",
|
|
18
|
+
"keywords": [
|
|
19
|
+
"helpers",
|
|
20
|
+
"typescript",
|
|
21
|
+
"types"
|
|
22
|
+
],
|
|
23
|
+
"license": "Apache-2.0",
|
|
24
|
+
"main": "dist/index.js",
|
|
25
|
+
"types": "dist/index.d.ts",
|
|
26
|
+
"private": false,
|
|
27
|
+
"readme": "README.md",
|
|
28
|
+
"repository": {
|
|
29
|
+
"url": "https://github.com/EkaanshPC/briklab-stdlib"
|
|
30
|
+
},
|
|
31
|
+
"version": "1.0.0",
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^25.1.0",
|
|
34
|
+
"typescript": "^5.9.3"
|
|
35
|
+
},
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"import": "./dist/index.js",
|
|
39
|
+
"types": "./dist/index.d.ts"
|
|
40
|
+
},
|
|
41
|
+
"./cli-john": {
|
|
42
|
+
"import": "./dist/cli-john/index.js",
|
|
43
|
+
"types": "./dist/cli-john/index.d.ts"
|
|
44
|
+
},
|
|
45
|
+
"./jstc": {
|
|
46
|
+
"import": "./dist/jstc/index.js",
|
|
47
|
+
"types": "./dist/jstc/index.d.ts"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsc"
|
|
52
|
+
}
|
|
53
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Node",
|
|
6
|
+
|
|
7
|
+
"rootDir": "src",
|
|
8
|
+
"outDir": "dist",
|
|
9
|
+
|
|
10
|
+
"declaration": true,
|
|
11
|
+
"strict": true,
|
|
12
|
+
|
|
13
|
+
"esModuleInterop": true,
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"types": [
|
|
16
|
+
"Node"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"include": ["src"],
|
|
20
|
+
"experimentalDecorators": true
|
|
21
|
+
}
|