@maz-ui/node 4.0.0-beta.11

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 LouisMazel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,244 @@
1
+ # @maz-ui/node
2
+
3
+ Node.js utilities for Maz-UI ecosystem - Promise-based command execution and colored logging.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @maz-ui/node
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - 🚀 **Promise-based command execution** with detailed logging
14
+ - 🎨 **Colored console logging** with multiple log levels
15
+ - ⚡ **TypeScript support** with full type safety
16
+ - 📦 **Lightweight** - minimal dependencies
17
+ - 🔧 **Configurable** - customizable logging behavior
18
+ - 🛡️ **Error handling** - comprehensive error management
19
+
20
+ ## Usage
21
+
22
+ ### execPromise
23
+
24
+ Execute shell commands with promise-based interface and automatic logging.
25
+
26
+ ```typescript
27
+ import { execPromise, logger } from '@maz-ui/node'
28
+
29
+ // Basic usage
30
+ try {
31
+ const { stdout } = await execPromise('npm --version')
32
+ logger.log('npm version:', stdout.trim())
33
+ }
34
+ catch (error) {
35
+ logger.error('Command failed:', error)
36
+ }
37
+
38
+ // With options
39
+ await execPromise('npm run build', {
40
+ packageName: 'my-package', // Adds [my-package] prefix to logs
41
+ noSuccess: true, // Skip success log
42
+ noStdout: true, // Skip stdout log
43
+ noStderr: true, // Skip stderr log
44
+ logger: customLogger // Use custom logger
45
+ })
46
+ ```
47
+
48
+ #### Options
49
+
50
+ ```typescript
51
+ interface ExecOptions {
52
+ logger?: Logger // Custom logger instance
53
+ packageName?: string // Package name for log prefixes
54
+ noSuccess?: boolean // Skip success logging
55
+ noStdout?: boolean // Skip stdout logging
56
+ noStderr?: boolean // Skip stderr logging
57
+ }
58
+ ```
59
+
60
+ ### Logger
61
+
62
+ Colored console logging with multiple levels and error handling.
63
+
64
+ ```typescript
65
+ import { logger } from '@maz-ui/node'
66
+
67
+ // Basic logging
68
+ logger.log('Regular message')
69
+ logger.success('Operation completed successfully!')
70
+ logger.warn('Warning message')
71
+ logger.error('Error occurred', errorObject)
72
+
73
+ // Special formatters
74
+ logger.brand('🎨 Maz-UI Brand Message') // Blue bright
75
+ logger.divider() // Prints separator line
76
+ logger.eot() // End of transmission (empty line)
77
+
78
+ // With error objects
79
+ try {
80
+ throw new Error('Something went wrong')
81
+ }
82
+ catch (error) {
83
+ logger.error('Operation failed:', error)
84
+ }
85
+ ```
86
+
87
+ #### Logger Methods
88
+
89
+ - **`log(...message)`** - Standard console log
90
+ - **`success(...message)`** - Green colored success messages
91
+ - **`warn(message, error?)`** - Yellow colored warnings
92
+ - **`error(message, error?)`** - Red colored error messages
93
+ - **`brand(message)`** - Blue bright branded messages
94
+ - **`divider()`** - Prints a separator line
95
+ - **`eot()`** - Prints an empty line (end of transmission)
96
+
97
+ ## Advanced Examples
98
+
99
+ ### Custom Logger Integration
100
+
101
+ ```typescript
102
+ import { execPromise, logger, type Logger } from '@maz-ui/node'
103
+
104
+ // Create custom logger with additional functionality
105
+ const customLogger: Logger = {
106
+ ...logger,
107
+ log: (...args) => {
108
+ // eslint-disable-next-line no-console
109
+ console.log('[CUSTOM]', ...args)
110
+ }
111
+ }
112
+
113
+ // Use with execPromise
114
+ await execPromise('npm test', {
115
+ logger: customLogger,
116
+ packageName: 'test-suite'
117
+ })
118
+ ```
119
+
120
+ ### Build Script Example
121
+
122
+ ```typescript
123
+ import { execPromise, logger } from '@maz-ui/node'
124
+
125
+ async function buildProject() {
126
+ logger.brand('🚀 Starting build process...')
127
+ logger.divider()
128
+
129
+ try {
130
+ // Install dependencies
131
+ await execPromise('npm install', {
132
+ packageName: 'setup',
133
+ noStdout: true
134
+ })
135
+
136
+ // Run tests
137
+ await execPromise('npm test', {
138
+ packageName: 'test',
139
+ noStdout: true
140
+ })
141
+
142
+ // Build project
143
+ await execPromise('npm run build', {
144
+ packageName: 'build'
145
+ })
146
+
147
+ logger.eot()
148
+ logger.success('✅ Build completed successfully!')
149
+ }
150
+ catch (error) {
151
+ logger.error('❌ Build failed:', error)
152
+ process.exit(1)
153
+ }
154
+ }
155
+
156
+ buildProject()
157
+ ```
158
+
159
+ ### CI/CD Integration
160
+
161
+ ```typescript
162
+ import { execPromise, logger } from '@maz-ui/node'
163
+
164
+ async function ciPipeline() {
165
+ const steps = [
166
+ { name: 'Lint', command: 'npm run lint' },
167
+ { name: 'Test', command: 'npm test' },
168
+ { name: 'Build', command: 'npm run build' },
169
+ { name: 'Package', command: 'npm pack' }
170
+ ]
171
+
172
+ logger.brand('🔄 CI Pipeline Started')
173
+ logger.divider()
174
+
175
+ for (const step of steps) {
176
+ logger.log(`⏳ Running ${step.name}...`)
177
+
178
+ try {
179
+ await execPromise(step.command, {
180
+ packageName: step.name.toLowerCase(),
181
+ noStdout: true
182
+ })
183
+ }
184
+ catch (error) {
185
+ logger.error(`❌ ${step.name} failed:`, error)
186
+ process.exit(1)
187
+ }
188
+ }
189
+
190
+ logger.eot()
191
+ logger.success('🎉 All pipeline steps completed!')
192
+ }
193
+ ```
194
+
195
+ ## API Reference
196
+
197
+ ### `execPromise(command, options?)`
198
+
199
+ Executes a shell command and returns a promise.
200
+
201
+ **Parameters:**
202
+
203
+ - `command` (string): Shell command to execute
204
+ - `options` (ExecOptions, optional): Execution options
205
+
206
+ **Returns:**
207
+
208
+ - `Promise<{ stdout: string, stderr: string }>`: Command output
209
+
210
+ **Throws:**
211
+
212
+ - Command execution errors with detailed logging
213
+
214
+ ### `logger`
215
+
216
+ Console logger with colored output and error handling.
217
+
218
+ **Type:** `Logger`
219
+
220
+ All logger methods automatically handle error objects using `getErrorMessage` utility for consistent error formatting.
221
+
222
+ ## Dependencies
223
+
224
+ - **colorette** - Terminal colors
225
+ - **@maz-ui/utils** - Error message formatting
226
+ - **Node.js built-ins** - child_process for command execution
227
+
228
+ ## Requirements
229
+
230
+ - Node.js >= 18.0.0
231
+ - TypeScript support included
232
+
233
+ ## Contributing
234
+
235
+ Contributions are welcome! Please ensure:
236
+
237
+ - New utilities follow existing patterns
238
+ - TypeScript types are properly defined
239
+ - Error handling is comprehensive
240
+ - Documentation is updated accordingly
241
+
242
+ ## License
243
+
244
+ MIT License - see LICENSE file for details.
@@ -0,0 +1,24 @@
1
+ declare const logger: {
2
+ divider: () => void;
3
+ eot: () => void;
4
+ brand: (message: string) => void;
5
+ log: (...message: unknown[]) => void;
6
+ success: (...message: string[]) => void;
7
+ error: (message: string, error?: unknown) => void;
8
+ warn: (message: string, error?: unknown) => void;
9
+ };
10
+ type Logger = typeof logger;
11
+
12
+ declare function execPromise(command: string, { logger, packageName, noSuccess, noStdout, noStderr }?: {
13
+ logger?: Logger;
14
+ packageName?: string;
15
+ noSuccess?: boolean;
16
+ noStdout?: boolean;
17
+ noStderr?: boolean;
18
+ }): Promise<{
19
+ stdout: string;
20
+ stderr: string;
21
+ }>;
22
+
23
+ export { execPromise, logger };
24
+ export type { Logger };
@@ -0,0 +1,24 @@
1
+ declare const logger: {
2
+ divider: () => void;
3
+ eot: () => void;
4
+ brand: (message: string) => void;
5
+ log: (...message: unknown[]) => void;
6
+ success: (...message: string[]) => void;
7
+ error: (message: string, error?: unknown) => void;
8
+ warn: (message: string, error?: unknown) => void;
9
+ };
10
+ type Logger = typeof logger;
11
+
12
+ declare function execPromise(command: string, { logger, packageName, noSuccess, noStdout, noStderr }?: {
13
+ logger?: Logger;
14
+ packageName?: string;
15
+ noSuccess?: boolean;
16
+ noStdout?: boolean;
17
+ noStderr?: boolean;
18
+ }): Promise<{
19
+ stdout: string;
20
+ stderr: string;
21
+ }>;
22
+
23
+ export { execPromise, logger };
24
+ export type { Logger };
package/dist/index.mjs ADDED
@@ -0,0 +1,198 @@
1
+ import { exec } from 'node:child_process';
2
+ import * as tty from 'tty';
3
+
4
+ function e(t) {
5
+ return t instanceof Error ? t.message : typeof t == "string" ? t : t && typeof t == "object" && "message" in t ? String(t.message) : t ? String(t) : "An unexpected error occurred";
6
+ }
7
+
8
+ const {
9
+ env = {},
10
+ argv = [],
11
+ platform = "",
12
+ } = typeof process === "undefined" ? {} : process;
13
+
14
+ const isDisabled = "NO_COLOR" in env || argv.includes("--no-color");
15
+ const isForced = "FORCE_COLOR" in env || argv.includes("--color");
16
+ const isWindows = platform === "win32";
17
+ const isDumbTerminal = env.TERM === "dumb";
18
+
19
+ const isCompatibleTerminal =
20
+ tty && tty.isatty && tty.isatty(1) && env.TERM && !isDumbTerminal;
21
+
22
+ const isCI =
23
+ "CI" in env &&
24
+ ("GITHUB_ACTIONS" in env || "GITLAB_CI" in env || "CIRCLECI" in env);
25
+
26
+ const isColorSupported =
27
+ !isDisabled &&
28
+ (isForced || (isWindows && !isDumbTerminal) || isCompatibleTerminal || isCI);
29
+
30
+ const replaceClose = (
31
+ index,
32
+ string,
33
+ close,
34
+ replace,
35
+ head = string.substring(0, index) + replace,
36
+ tail = string.substring(index + close.length),
37
+ next = tail.indexOf(close)
38
+ ) => head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
39
+
40
+ const clearBleed = (index, string, open, close, replace) =>
41
+ index < 0
42
+ ? open + string + close
43
+ : open + replaceClose(index, string, close, replace) + close;
44
+
45
+ const filterEmpty =
46
+ (open, close, replace = open, at = open.length + 1) =>
47
+ (string) =>
48
+ string || !(string === "" || string === undefined)
49
+ ? clearBleed(
50
+ ("" + string).indexOf(close, at),
51
+ string,
52
+ open,
53
+ close,
54
+ replace
55
+ )
56
+ : "";
57
+
58
+ const init = (open, close, replace) =>
59
+ filterEmpty(`\x1b[${open}m`, `\x1b[${close}m`, replace);
60
+
61
+ const colors = {
62
+ reset: init(0, 0),
63
+ bold: init(1, 22, "\x1b[22m\x1b[1m"),
64
+ dim: init(2, 22, "\x1b[22m\x1b[2m"),
65
+ italic: init(3, 23),
66
+ underline: init(4, 24),
67
+ inverse: init(7, 27),
68
+ hidden: init(8, 28),
69
+ strikethrough: init(9, 29),
70
+ black: init(30, 39),
71
+ red: init(31, 39),
72
+ green: init(32, 39),
73
+ yellow: init(33, 39),
74
+ blue: init(34, 39),
75
+ magenta: init(35, 39),
76
+ cyan: init(36, 39),
77
+ white: init(37, 39),
78
+ gray: init(90, 39),
79
+ bgBlack: init(40, 49),
80
+ bgRed: init(41, 49),
81
+ bgGreen: init(42, 49),
82
+ bgYellow: init(43, 49),
83
+ bgBlue: init(44, 49),
84
+ bgMagenta: init(45, 49),
85
+ bgCyan: init(46, 49),
86
+ bgWhite: init(47, 49),
87
+ blackBright: init(90, 39),
88
+ redBright: init(91, 39),
89
+ greenBright: init(92, 39),
90
+ yellowBright: init(93, 39),
91
+ blueBright: init(94, 39),
92
+ magentaBright: init(95, 39),
93
+ cyanBright: init(96, 39),
94
+ whiteBright: init(97, 39),
95
+ bgBlackBright: init(100, 49),
96
+ bgRedBright: init(101, 49),
97
+ bgGreenBright: init(102, 49),
98
+ bgYellowBright: init(103, 49),
99
+ bgBlueBright: init(104, 49),
100
+ bgMagentaBright: init(105, 49),
101
+ bgCyanBright: init(106, 49),
102
+ bgWhiteBright: init(107, 49),
103
+ };
104
+
105
+ const createColors = ({ useColor = isColorSupported } = {}) =>
106
+ useColor
107
+ ? colors
108
+ : Object.keys(colors).reduce(
109
+ (colors, key) => ({ ...colors, [key]: String }),
110
+ {}
111
+ );
112
+
113
+ const {
114
+ reset,
115
+ bold,
116
+ dim,
117
+ italic,
118
+ underline,
119
+ inverse,
120
+ hidden,
121
+ strikethrough,
122
+ black,
123
+ red,
124
+ green,
125
+ yellow,
126
+ blue,
127
+ magenta,
128
+ cyan,
129
+ white,
130
+ gray,
131
+ bgBlack,
132
+ bgRed,
133
+ bgGreen,
134
+ bgYellow,
135
+ bgBlue,
136
+ bgMagenta,
137
+ bgCyan,
138
+ bgWhite,
139
+ blackBright,
140
+ redBright,
141
+ greenBright,
142
+ yellowBright,
143
+ blueBright,
144
+ magentaBright,
145
+ cyanBright,
146
+ whiteBright,
147
+ bgBlackBright,
148
+ bgRedBright,
149
+ bgGreenBright,
150
+ bgYellowBright,
151
+ bgBlueBright,
152
+ bgMagentaBright,
153
+ bgCyanBright,
154
+ bgWhiteBright,
155
+ } = createColors();
156
+
157
+ const log = console.log;
158
+ const logger = {
159
+ divider: () => log("----------------------------------------"),
160
+ eot: () => log(),
161
+ brand: (message) => log(blueBright(message)),
162
+ log: (...message) => log(...message),
163
+ success: (...message) => log(...message.map((m) => green(m))),
164
+ error: (message, error) => {
165
+ const errorMessage = error ? e(error) : "";
166
+ log(red(message), errorMessage ? red(errorMessage) : "");
167
+ },
168
+ warn: (message, error) => {
169
+ const errorMessage = error ? e(error) : "";
170
+ log(yellow(message), errorMessage ? yellow(errorMessage) : "");
171
+ }
172
+ };
173
+
174
+ async function execPromise(command, { logger: logger$1, packageName, noSuccess, noStdout, noStderr } = {}) {
175
+ const internalLogger = logger$1 ?? logger;
176
+ const packageNameStr = packageName ? `[${packageName}]` : "";
177
+ return await new Promise((resolve, reject) => {
178
+ exec(command, (error, stdout, stderr) => {
179
+ if (stdout && !noStdout) {
180
+ internalLogger.log(`\u{1F7E1} ${packageNameStr}(${command})`, stdout);
181
+ }
182
+ if (stderr && !noStderr) {
183
+ internalLogger.warn(`\u{1F7E1} ${packageNameStr}(${command})`, stderr);
184
+ }
185
+ if (error) {
186
+ internalLogger.error(`\u{1F534} ${packageNameStr}(${command}) Execution failed - ${error.message}.`, error.message);
187
+ reject(error);
188
+ } else {
189
+ if (!noSuccess) {
190
+ internalLogger.success(`\u{1F7E2} ${packageNameStr}(${command}) Execution success`);
191
+ }
192
+ resolve({ stdout, stderr });
193
+ }
194
+ });
195
+ });
196
+ }
197
+
198
+ export { execPromise, logger };
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@maz-ui/node",
3
+ "type": "module",
4
+ "version": "4.0.0-beta.11",
5
+ "packageManager": "pnpm@10.13.1",
6
+ "description": "Node utilities for Maz-UI library",
7
+ "author": "Louis Mazel <me@loicmazuel.com>",
8
+ "license": "MIT",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/LouisMazel/maz-ui.git"
12
+ },
13
+ "bugs": "https://github.com/LouisMazel/maz-ui/issues",
14
+ "keywords": [
15
+ "node",
16
+ "utilities",
17
+ "maz-ui",
18
+ "promise",
19
+ "logger"
20
+ ],
21
+ "sideEffects": false,
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.mjs"
29
+ },
30
+ "./*": "./src/*"
31
+ },
32
+ "main": "./dist/index.mjs",
33
+ "types": "./dist/index.d.ts",
34
+ "files": [
35
+ "LICENSE",
36
+ "README.md",
37
+ "dist"
38
+ ],
39
+ "engines": {
40
+ "node": ">=18.0.0"
41
+ },
42
+ "scripts": {
43
+ "build": "unbuild",
44
+ "dev": "unbuild --stub",
45
+ "typecheck": "tsc --noEmit --skipLibCheck",
46
+ "lint": "eslint .",
47
+ "lint:fix": "eslint . --fix",
48
+ "pre-commit": "lint-staged"
49
+ },
50
+ "devDependencies": {
51
+ "@maz-ui/utils": "4.0.0-beta.11",
52
+ "colorette": "^2.0.20",
53
+ "typescript": "^5.8.3",
54
+ "unbuild": "^3.5.0"
55
+ },
56
+ "lint-staged": {
57
+ "*.{js,jsx,ts,tsx,mjs,mts,cjs,md,yml,json}": [
58
+ "eslint --fix"
59
+ ]
60
+ },
61
+ "gitHead": "604f754078f4e50e3db39793c28709e1dc1020c7"
62
+ }