@ix-xs/node-comfort 1.0.4 → 1.0.5

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.
Files changed (41) hide show
  1. package/index.js +12 -14
  2. package/package.json +17 -17
  3. package/src/checker.js +76 -0
  4. package/src/cli.js +86 -0
  5. package/{core/FS.js → src/fs.js} +121 -229
  6. package/src/localStorage.js +242 -0
  7. package/{core/Logger.js → src/logger.js} +23 -97
  8. package/src/utils.js +225 -0
  9. package/tsconfig.json +1 -1
  10. package/types/index.d.ts +71 -53
  11. package/types/src/checker.d.ts +49 -0
  12. package/types/src/checker.d.ts.map +1 -0
  13. package/types/src/cli.d.ts +26 -0
  14. package/types/src/cli.d.ts.map +1 -0
  15. package/types/src/fs.d.ts +210 -0
  16. package/types/src/fs.d.ts.map +1 -0
  17. package/types/src/localStorage.d.ts +97 -0
  18. package/types/src/localStorage.d.ts.map +1 -0
  19. package/types/src/logger.d.ts +132 -0
  20. package/types/src/logger.d.ts.map +1 -0
  21. package/types/src/utils.d.ts +92 -0
  22. package/types/src/utils.d.ts.map +1 -0
  23. package/core/CLI.js +0 -95
  24. package/core/Checker.js +0 -127
  25. package/core/Stepper.js +0 -115
  26. package/core/Storage.js +0 -348
  27. package/core/Utils.js +0 -206
  28. package/types/core/CLI.d.ts +0 -25
  29. package/types/core/CLI.d.ts.map +0 -1
  30. package/types/core/Checker.d.ts +0 -73
  31. package/types/core/Checker.d.ts.map +0 -1
  32. package/types/core/FS.d.ts +0 -220
  33. package/types/core/FS.d.ts.map +0 -1
  34. package/types/core/Logger.d.ts +0 -253
  35. package/types/core/Logger.d.ts.map +0 -1
  36. package/types/core/Stepper.d.ts +0 -49
  37. package/types/core/Stepper.d.ts.map +0 -1
  38. package/types/core/Storage.d.ts +0 -111
  39. package/types/core/Storage.d.ts.map +0 -1
  40. package/types/core/Utils.d.ts +0 -55
  41. package/types/core/Utils.d.ts.map +0 -1
@@ -0,0 +1,132 @@
1
+ /**
2
+ * @param {*} content
3
+ */
4
+ export function log(content: any): {
5
+ log(content: any): /*elided*/ any;
6
+ /**
7
+ * @param {any} content - Content to format.
8
+ * @returns {string} Formatted string.
9
+ */
10
+ logify(content: any): string;
11
+ /**
12
+ * @param {string} label
13
+ */
14
+ group(label: string): /*elided*/ any;
15
+ groupEnd(): /*elided*/ any;
16
+ /**
17
+ * @param {object} [options]
18
+ * @param {object} [options.delimiters]
19
+ * @param {string} [options.delimiters.start="<%="]
20
+ * @param {string} [options.delimiters.end="%>"]
21
+ * @param {boolean} [options.timestamp=true]
22
+ */
23
+ setLogger(options?: {
24
+ delimiters?: {
25
+ start?: string;
26
+ end?: string;
27
+ };
28
+ timestamp?: boolean;
29
+ }): /*elided*/ any;
30
+ };
31
+ /**
32
+ * @param {any} content - Content to format.
33
+ * @returns {string} Formatted string.
34
+ */
35
+ export function logify(content: any): string;
36
+ /**
37
+ * @param {string} label
38
+ */
39
+ export function group(label: string): {
40
+ /**
41
+ * @param {*} content
42
+ */
43
+ log(content: any): /*elided*/ any;
44
+ /**
45
+ * @param {any} content - Content to format.
46
+ * @returns {string} Formatted string.
47
+ */
48
+ logify(content: any): string;
49
+ group(label: string): /*elided*/ any;
50
+ groupEnd(): /*elided*/ any;
51
+ /**
52
+ * @param {object} [options]
53
+ * @param {object} [options.delimiters]
54
+ * @param {string} [options.delimiters.start="<%="]
55
+ * @param {string} [options.delimiters.end="%>"]
56
+ * @param {boolean} [options.timestamp=true]
57
+ */
58
+ setLogger(options?: {
59
+ delimiters?: {
60
+ start?: string;
61
+ end?: string;
62
+ };
63
+ timestamp?: boolean;
64
+ }): /*elided*/ any;
65
+ };
66
+ export function groupEnd(): {
67
+ /**
68
+ * @param {*} content
69
+ */
70
+ log(content: any): /*elided*/ any;
71
+ /**
72
+ * @param {any} content - Content to format.
73
+ * @returns {string} Formatted string.
74
+ */
75
+ logify(content: any): string;
76
+ /**
77
+ * @param {string} label
78
+ */
79
+ group(label: string): /*elided*/ any;
80
+ groupEnd(): /*elided*/ any;
81
+ /**
82
+ * @param {object} [options]
83
+ * @param {object} [options.delimiters]
84
+ * @param {string} [options.delimiters.start="<%="]
85
+ * @param {string} [options.delimiters.end="%>"]
86
+ * @param {boolean} [options.timestamp=true]
87
+ */
88
+ setLogger(options?: {
89
+ delimiters?: {
90
+ start?: string;
91
+ end?: string;
92
+ };
93
+ timestamp?: boolean;
94
+ }): /*elided*/ any;
95
+ };
96
+ /**
97
+ * @param {object} [options]
98
+ * @param {object} [options.delimiters]
99
+ * @param {string} [options.delimiters.start="<%="]
100
+ * @param {string} [options.delimiters.end="%>"]
101
+ * @param {boolean} [options.timestamp=true]
102
+ */
103
+ export function setLogger(options?: {
104
+ delimiters?: {
105
+ start?: string;
106
+ end?: string;
107
+ };
108
+ timestamp?: boolean;
109
+ }): {
110
+ /**
111
+ * @param {*} content
112
+ */
113
+ log(content: any): /*elided*/ any;
114
+ /**
115
+ * @param {any} content - Content to format.
116
+ * @returns {string} Formatted string.
117
+ */
118
+ logify(content: any): string;
119
+ /**
120
+ * @param {string} label
121
+ */
122
+ group(label: string): /*elided*/ any;
123
+ groupEnd(): /*elided*/ any;
124
+ setLogger(options?: {
125
+ delimiters?: {
126
+ start?: string;
127
+ end?: string;
128
+ };
129
+ timestamp?: boolean;
130
+ }): /*elided*/ any;
131
+ };
132
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.js"],"names":[],"mappings":"AA8JE;;EAEC;AACD,6BAFS,GAAC;iBAAD,GAAC;IAkCV;;;KAGC;oBAFQ,GAAG,GACD,MAAM;IAejB;;KAEC;iBADQ,MAAM;;IAYf;;;;;;KAMC;wBAJA;QAAyB,UAAU,GACnC;YAAoC,KAAK,GAAjC,MAAM;YACsB,GAAG,GAA/B,MAAM;SACd;QAA0B,SAAS,GAA3B,OAAO;KAA0B;EApCzC;AACD;;;EAGC;AACD,gCAHS,GAAG,GACD,MAAM,CAchB;AACD;;EAEC;AACD,6BAFS,MAAM;IArDf;;KAEC;iBADQ,GAAC;IAkCV;;;KAGC;oBAFQ,GAAG,GACD,MAAM;iBAgBR,MAAM;;IAYf;;;;;;KAMC;wBAJA;QAAyB,UAAU,GACnC;YAAoC,KAAK,GAAjC,MAAM;YACsB,GAAG,GAA/B,MAAM;SACd;QAA0B,SAAS,GAA3B,OAAO;KAA0B;EAVzC;AACD;IA7DA;;KAEC;iBADQ,GAAC;IAkCV;;;KAGC;oBAFQ,GAAG,GACD,MAAM;IAejB;;KAEC;iBADQ,MAAM;;IAYf;;;;;;KAMC;wBAJA;QAAyB,UAAU,GACnC;YAAoC,KAAK,GAAjC,MAAM;YACsB,GAAG,GAA/B,MAAM;SACd;QAA0B,SAAS,GAA3B,OAAO;KAA0B;EANzC;AACD;;;;;;EAMC;AACD,oCALC;IAAyB,UAAU,GACnC;QAAoC,KAAK,GAAjC,MAAM;QACsB,GAAG,GAA/B,MAAM;KACd;IAA0B,SAAS,GAA3B,OAAO;CAA0B;IAtE1C;;KAEC;iBADQ,GAAC;IAkCV;;;KAGC;oBAFQ,GAAG,GACD,MAAM;IAejB;;KAEC;iBADQ,MAAM;;wBAcd;QAAyB,UAAU,GACnC;YAAoC,KAAK,GAAjC,MAAM;YACsB,GAAG,GAA/B,MAAM;SACd;QAA0B,SAAS,GAA3B,OAAO;KAA0B;EAazC"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @param {number} ms
3
+ */
4
+ export function wait(ms: number): Promise<any>;
5
+ /**
6
+ * Polls a predicate at a given interval and emits events when it matches or times out.
7
+ *
8
+ * The predicate is evaluated every `options.interval` milliseconds (default: 50 ms).
9
+ * Be careful with the default interval: 50 ms is very frequent polling and can be
10
+ * unnecessarily CPU‑intensive if your predicate or trigger handlers are heavy.
11
+ * When `options.max` is `null`, the predicate can match indefinitely (infinite triggers),
12
+ * so you should choose an interval that makes sense for your use‑case.
13
+ *
14
+ * @param {boolean|Promise<boolean>|(() => boolean|Promise<boolean>)} predicate
15
+ * Condition to evaluate at each tick, or a function returning it.
16
+ * @param {*} payload
17
+ * Value passed to listeners when events are emitted (e.g. an object or message).
18
+ * @param {object} [options]
19
+ * @param {number} [options.interval=50]
20
+ * Polling interval in milliseconds. Increase this value if your predicate is
21
+ * expensive or you expect many triggers without a `max` limit.
22
+ * @param {number|null} [options.timeout=null]
23
+ * Maximum time in milliseconds before emitting a "timeout" event and stopping.
24
+ * If `null`, no timeout is applied.
25
+ * @param {number|null} [options.max=null]
26
+ * Maximum number of successful predicate evaluations ("trigger" events) before
27
+ * automatically stopping. If `null`, triggers are infinite until `stop()` is called.
28
+ *
29
+ * @example
30
+ * // Basic usage: infinite triggers every 50 ms (default interval) – use with caution.
31
+ * const task = when(() => true, { message: "Ok" });
32
+ *
33
+ * task.on("trigger", (payload) => {
34
+ * console.log(payload.message);
35
+ * // task.stop(); // stop when you’re done
36
+ * });
37
+ *
38
+ * task.start();
39
+ *
40
+ * @example
41
+ * // Safer usage: limit triggers and/or lower polling frequency.
42
+ * when(() => true, { message: "Ok" }, { max: 1, interval: 500 }) // one trigger max, every 500 ms
43
+ * .on("trigger", (payload) => {
44
+ * console.log(payload.message);
45
+ * })
46
+ * .start();
47
+ */
48
+ export function when(predicate: boolean | Promise<boolean> | (() => boolean | Promise<boolean>), payload?: any, options?: {
49
+ interval?: number;
50
+ timeout?: number | null;
51
+ max?: number | null;
52
+ }): {
53
+ start(): /*elided*/ any;
54
+ stop(): /*elided*/ any;
55
+ /**
56
+ * @typedef { "error" | "trigger" | "timeout" } EventNames
57
+ * @typedef {{
58
+ * error: (error) => void|Promise<void>,
59
+ * trigger: (payload) => void|Promise<void>,
60
+ * timeout: (payload) => void|Promise<void>,
61
+ * }} EventHandlers
62
+ */
63
+ /**
64
+ * @template {EventNames} E
65
+ * @param {E} event
66
+ * @param {EventHandlers[E]} handler
67
+ */
68
+ on<E extends "error" | "trigger" | "timeout">(event: E, handler: {
69
+ error: (error: any) => void | Promise<void>;
70
+ trigger: (payload: any) => void | Promise<void>;
71
+ timeout: (payload: any) => void | Promise<void>;
72
+ }[E]): /*elided*/ any;
73
+ };
74
+ export function dontCrash(): {
75
+ /**
76
+ * @template { "error" | "exit" | "sig" | "beforeExit" } E
77
+ * @param { E } event
78
+ * @param { { error: (error: Error | unknown) => void | Promise<void>, exit: (code: number) => void | Promise<void>, sig: (signal: "SIGINT" | "SIGTERM" | "SIGQUIT") => void | Promise<void>, beforeExit: (code: number) => void|Promise<void> }[E] } handler
79
+ */
80
+ on<E extends "error" | "exit" | "sig" | "beforeExit">(event: E, handler: {
81
+ error: (error: Error | unknown) => void | Promise<void>;
82
+ exit: (code: number) => void | Promise<void>;
83
+ sig: (signal: "SIGINT" | "SIGTERM" | "SIGQUIT") => void | Promise<void>;
84
+ beforeExit: (code: number) => void | Promise<void>;
85
+ }[E]): /*elided*/ any;
86
+ };
87
+ /**
88
+ * @param {*} value
89
+ */
90
+ export function JSONString(value: any): string;
91
+ export function JSONParse(value: any): any;
92
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.js"],"names":[],"mappings":"AAGE;;KAEE;AACF,yBAFU,MAAM,gBAIf;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,gCAlCW,OAAO,GAAC,OAAO,CAAC,OAAO,CAAC,GAAC,CAAC,MAAM,OAAO,GAAC,OAAO,CAAC,OAAO,CAAC,CAAC,YAEzD,GAAC,YAGT;IAAyB,QAAQ,GAAzB,MAAM;IAGgB,OAAO,GAA7B,MAAM,GAAC,IAAI;IAGW,GAAG,GAAzB,MAAM,GAAC,IAAI;CAInB;;;IAiHC;;;;;;;OAOG;IACH;;;;aAIA;OAH0B,CAAC,SAAd,+BAAY,SACjB,CAAC;eAPC,CAAC,KAAK,KAAA,KAAK,IAAI,GAAC,OAAO,CAAC,IAAI,CAAC;iBAC3B,CAAC,OAAO,KAAA,KAAK,IAAI,GAAC,OAAO,CAAC,IAAI,CAAC;iBAC/B,CAAC,OAAO,KAAA,KAAK,IAAI,GAAC,OAAO,CAAC,IAAI,CAAC;;EAe9C;AACD;IAgBI;;;;aAIA;OAHsD,CAAC,SAA3C,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,YAAc,SAC5C,CAAC,WACD;QAAE,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAC,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC,CAAC,CAAC;EA4BnP;AACD;;GAEG;AACH,kCAFW,GAAC,UAIX;AACD,2CAEC"}
package/core/CLI.js DELETED
@@ -1,95 +0,0 @@
1
- const { spawn, execSync } = require("node:child_process");
2
- const EventEmitter = require("node:events");
3
-
4
- class cli_stream {
5
- #processus;
6
- #events = new EventEmitter();
7
-
8
- constructor(command, args) {
9
- this.#processus = spawn(command, args, {
10
- shell: true,
11
- stdio: ["ignore", "pipe", "pipe"],
12
- });
13
-
14
- this.#processus.stdout.on("data", (data) => {
15
- this.#events.emit("data", data.toString());
16
- });
17
- this.#processus.stderr.on("data", (data) => {
18
- this.#events.emit("data", data.toString());
19
- });
20
- this.#processus.on("error", (error) => {
21
- this.#events.emit("error", error);
22
- });
23
- this.#processus.on("exit", async (code, signal) => {
24
- await this.stop();
25
- });
26
- this.#processus.on("close", (code, signal) => {
27
- this.#events.emit("stopped", code, signal);
28
- });
29
- }
30
-
31
- /**
32
- * @typedef {"error"|"data"|"stopped"} EventName
33
- * @typedef {{
34
- * error: (error: Error) => void|Promise<void>,
35
- * data: (message: string) => void|Promise<void>,
36
- * stopped: (code: number, signal: keyof import("node:child_process").ChildProcessEventMap) => void|Promise<void>,
37
- * }} EventHandler
38
- */
39
- /**
40
- * @template {EventName} E
41
- * @param {E} event
42
- * @param {EventHandler[E]} handler
43
- */
44
- on(event, handler) {
45
- this.#events.on(event, handler);
46
- return this;
47
- }
48
-
49
- async stop() {
50
- return new Promise((resolve) => {
51
- if (!this.#processus || this.#processus.killed) {
52
- this.#processus = null;
53
- return resolve();
54
- }
55
-
56
- let resolved = false;
57
-
58
- const done = () => {
59
- if (!resolved) {
60
- resolved = true;
61
- this.#processus = null;
62
- resolve();
63
- }
64
- };
65
-
66
- this.#processus.once("exit", done);
67
-
68
- this.#processus.kill("SIGTERM");
69
-
70
- setTimeout(() => {
71
- if (this.#processus && !this.#processus.killed && !resolved) {
72
- this.#processus.kill("SIGKILL");
73
- }
74
- done();
75
- }, 5000);
76
- });
77
- }
78
- }
79
-
80
- /**
81
- * @module CLI
82
- * @description
83
- */
84
- module.exports = {
85
- /**
86
- * @param {string} command
87
- */
88
- cli_run: (command) => {
89
- return execSync(command, {
90
- shell: true,
91
- stdio: "pipe",
92
- });
93
- },
94
- cli_stream,
95
- };
package/core/Checker.js DELETED
@@ -1,127 +0,0 @@
1
- const { types } = require("node:util");
2
-
3
- /**
4
- * @module Checker
5
- * @description
6
- * Provides a collection of utility functions for checking JavaScript value types.
7
- *
8
- * These helpers wrap common JavaScript type checks and selected `node:util.types`
9
- * methods for specific built-in objects such as Map, Set, Date, and Error.
10
- *
11
- * @example
12
- * const nodeComfort = require("@ix-xs/node-comfort");
13
- *
14
- * console.log(nodeComfort.isArray([1, 2, 3])); // true
15
- * console.log(nodeComfort.isNumber(42)); // true
16
- * console.log(nodeComfort.isDate(new Date())); // true
17
- */
18
-
19
- module.exports = {
20
- /**
21
- * Checks if the value is an array.
22
- * @param {*} value - The value to check.
23
- * @returns {boolean} Returns `true` if the value is an array, otherwise `false`.
24
- */
25
- isArray(value) {
26
- return Array.isArray(value);
27
- },
28
-
29
- /**
30
- * Checks if the value is a valid number (not NaN).
31
- * @param {*} value - The value to check.
32
- * @returns {boolean} Returns `true` if the value is a valid number, otherwise `false`.
33
- */
34
- isNumber(value) {
35
- return typeof value === "number" && !Number.isNaN(value);
36
- },
37
-
38
- /**
39
- * Checks if the value is a function.
40
- * @param {*} value - The value to check.
41
- * @returns {boolean} Returns `true` if the value is a function, otherwise `false`.
42
- */
43
- isFunction(value) {
44
- return typeof value === "function";
45
- },
46
-
47
- /**
48
- * Checks if the value is an object (and not `null`).
49
- * @param {*} value - The value to check.
50
- * @returns {boolean} Returns `true` if the value is a non-null object, otherwise `false`.
51
- */
52
- isObject(value) {
53
- return typeof value === "object" && value !== null;
54
- },
55
-
56
- /**
57
- * Checks if the value is a boolean.
58
- * @param {*} value - The value to check.
59
- * @returns {boolean} Returns `true` if the value is a boolean, otherwise `false`.
60
- */
61
- isBoolean(value) {
62
- return typeof value === "boolean";
63
- },
64
-
65
- /**
66
- * Checks if the value is a string.
67
- * @param {*} value - The value to check.
68
- * @returns {boolean} Returns `true` if the value is a string, otherwise `false`.
69
- */
70
- isString(value) {
71
- return typeof value === "string";
72
- },
73
-
74
- /**
75
- * Checks if the value is `undefined`.
76
- * @param {*} value - The value to check.
77
- * @returns {boolean} Returns `true` if the value is `undefined`, otherwise `false`.
78
- */
79
- isUndefined(value) {
80
- return typeof value === "undefined";
81
- },
82
-
83
- /**
84
- * Checks if the value is `null`.
85
- * @param {*} value - The value to check.
86
- * @returns {boolean} Returns `true` if the value is `null`, otherwise `false`.
87
- */
88
- isNull(value) {
89
- return value === null;
90
- },
91
-
92
- /**
93
- * Checks if the value is a valid `Date` object.
94
- * @param {*} value - The value to check.
95
- * @returns {boolean} Returns `true` if the value is an instance of `Date`, otherwise `false`.
96
- */
97
- isDate(value) {
98
- return types.isDate(value);
99
- },
100
-
101
- /**
102
- * Checks if the value is a `Map` instance.
103
- * @param {*} value - The value to check.
104
- * @returns {boolean} Returns `true` if the value is a Map, otherwise `false`.
105
- */
106
- isMap(value) {
107
- return types.isMap(value);
108
- },
109
-
110
- /**
111
- * Checks if the value is a `Set` instance.
112
- * @param {*} value - The value to check.
113
- * @returns {boolean} Returns `true` if the value is a Set, otherwise `false`.
114
- */
115
- isSet(value) {
116
- return types.isSet(value);
117
- },
118
-
119
- /**
120
- * Checks if the value is a native JavaScript error (`Error`, `TypeError`, etc.).
121
- * @param {*} value - The value to check.
122
- * @returns {boolean} Returns `true` if the value is a native error, otherwise `false`.
123
- */
124
- isError(value) {
125
- return types.isNativeError(value);
126
- },
127
- };
package/core/Stepper.js DELETED
@@ -1,115 +0,0 @@
1
- /**
2
- * @module Stepper
3
- * @description
4
- * Fluent step controller for sequential task execution with navigation, skipping, and indexing.
5
- *
6
- * Perfect for CLI wizards, build pipelines, tutorials, or any sequential workflow.
7
- * Supports forward/backward navigation, jumping to specific steps, ignoring steps, and reset.
8
- *
9
- * @example
10
- * const nodeComfort = require("@ix-xs/node-comfort");
11
- *
12
- * // Simple 3-step process
13
- * nodeComfort.step([
14
- * () => console.log("Step 1: Validate config"),
15
- * () => console.log("Step 2: Build assets"),
16
- * () => console.log("Step 3: Deploy")
17
- * ])
18
- * .next().next().next(); // Execute all steps
19
- *
20
- * // Interactive navigation
21
- * const wizard = nodeComfort.step([
22
- * () => nodeComfort.log("<%yellow 1%> Enter name"),
23
- * () => nodeComfort.log("<%yellow 2%> Enter email"),
24
- * () => nodeComfort.log("<%green ✓%> Complete!")
25
- * ]);
26
- *
27
- * wizard.next().back().ignore().next(); // 1 → back to 0 → skip 1 → execute 2
28
- */
29
- module.exports = {
30
- /**
31
- * Creates a step controller for sequential function execution.
32
- *
33
- * Returns fluent API with `next()`, `back()`, `at()`, `ignore()`, `reset()` methods.
34
- *
35
- * @param {Array<() => void>} steps - Array of step functions to execute.
36
- *
37
- * @example
38
- * const steps = nodeComfort.step([
39
- * () => console.log("Install dependencies"),
40
- * () => console.log("Compile TypeScript"),
41
- * () => console.log("Run tests")
42
- * ]);
43
- *
44
- * steps.next().next(); // Execute steps 0, 1
45
- * steps.back(); // Go back to step 0
46
- * steps.at(2); // Jump to step 2
47
- */
48
- step(steps) {
49
- let i = -1;
50
-
51
- const _ = {
52
- currentIndex: i,
53
- currentStep: steps[i],
54
- /**
55
- * Advances to next step and executes it (if exists).
56
- */
57
- next() {
58
- if (i < steps.length - 1) {
59
- i++;
60
- if (typeof steps[i] === "function") steps[i]();
61
- }
62
- return _;
63
- },
64
- /**
65
- * Goes back to previous step and re-executes it (if exists).
66
- */
67
- back() {
68
- if (i > 0) {
69
- i--;
70
- if (typeof steps[i] === "function") steps[i]();
71
- }
72
- return _;
73
- },
74
- /**
75
- * Jumps to specific step index and executes it.
76
- * @param {number} index - Step index (0 to steps.length-1).
77
- * @example
78
- * steps.at(2); // Jump to 3rd step
79
- */
80
- at(index) {
81
- if (index >= 0 && index < steps.length) {
82
- i = index;
83
- if (typeof steps[i] === "function") steps[i]();
84
- }
85
- return _;
86
- },
87
- /**
88
- * Advances index without executing current step.
89
- * @example
90
- * steps.next().ignore().next(); // Execute 0, skip 1, execute 2
91
- */
92
- ignore() {
93
- if (i < steps.length - 1) {
94
- i++;
95
- }
96
- return _;
97
- },
98
- /**
99
- * Resets to initial state (index: -1).
100
- */
101
- reset() {
102
- i = -1;
103
- return _;
104
- },
105
- all() {
106
- while (i < steps.length - 1) {
107
- this.next();
108
- }
109
- return _;
110
- },
111
- };
112
-
113
- return _;
114
- },
115
- };