@rtorcato/js-common 1.8.0 โ†’ 1.8.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [1.8.1](https://github.com/rtorcato/js-common/compare/v1.8.0...v1.8.1) (2026-05-29)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **deps:** move CLI deps to optionalDependencies ([52d1e9f](https://github.com/rtorcato/js-common/commit/52d1e9feda9ae86dc705f103678024cfb9772c68))
7
+ * publishing bugs and dead-code cleanup ([30b8d69](https://github.com/rtorcato/js-common/commit/30b8d693d6dfcdc4b6044438318f7d5cbaca0e86))
8
+
1
9
  # [1.8.0](https://github.com/rtorcato/js-common/compare/v1.7.1...v1.8.0) (2026-05-29)
2
10
 
3
11
 
package/README.md CHANGED
@@ -5,8 +5,7 @@
5
5
  [![npm version](https://badge.fury.io/js/%40rtorcato%2Fjs-common.svg)](https://badge.fury.io/js/%40rtorcato%2Fjs-common)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
8
- [![Bundle Size](https://img.shields.io/badge/Bundle%20Size-277%20bytes-green.svg)](https://bundlejs.com/?q=@rtorcato/js-common)
9
- [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D18.0.0-brightgreen.svg)](https://nodejs.org/)
8
+ [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D22.0.0-brightgreen.svg)](https://nodejs.org/)
10
9
  [![Docs](https://img.shields.io/badge/docs-rtorcato.github.io%2Fjs--common-blue.svg)](https://rtorcato.github.io/js-common/)
11
10
 
12
11
  A comprehensive set of common JavaScript and TypeScript utilities for Node.js projects.
@@ -15,12 +14,11 @@ A comprehensive set of common JavaScript and TypeScript utilities for Node.js pr
15
14
 
16
15
  ## โœจ Features
17
16
 
18
- - ๐Ÿš€ **Ultra-lightweight** - Only 277 bytes main bundle
19
- - ๐Ÿ“ฆ **Tree-shakeable** - Import only what you need
17
+ - ๐Ÿ“ฆ **Tree-shakeable** - Import only what you need via subpath exports
20
18
  - ๐Ÿ”ง **TypeScript** - Full type safety and IntelliSense
21
- - ๐Ÿ–ฅ๏ธ **CLI included** - Use utilities from command line
22
- - ๐Ÿ“š **Modular** - Import individual modules
23
- - โšก **Utility modules have no dependencies** - CLI features use optional packages isolated to the `cli` subpath
19
+ - ๐Ÿ–ฅ๏ธ **CLI included** - Optional binary for use in scripts and terminals
20
+ - ๐Ÿ“š **Modular** - One module per concern, ~40 subpaths
21
+ - โšก **Minimal runtime deps** - Only `date-fns`, `luxon`, `pino`, `uuid`, `short-uuid`, `zod`. CLI packages (`chalk`, `commander`, `figlet`, โ€ฆ) are `optionalDependencies` and only needed for the CLI.
24
22
  - ๐Ÿงช **Well tested** - Comprehensive test coverage
25
23
 
26
24
  ## Installation
@@ -59,9 +57,6 @@ import { generateUUID, isValidUUID } from '@rtorcato/js-common/uuid'
59
57
  import { sum, average, roundTo } from '@rtorcato/js-common/numbers'
60
58
  import { capitalize, toTitleCase } from '@rtorcato/js-common/formatting'
61
59
 
62
- // ๐Ÿ“ฆ Or import everything (larger bundle)
63
- import * as jsCommon from '@rtorcato/js-common'
64
-
65
60
  // Example usage
66
61
  console.log(today()) // "2025-10-24"
67
62
  console.log(sum([1, 2, 3, 4, 5])) // 15
@@ -71,15 +66,7 @@ console.log(generateUUID()) // "f47ac10b-58cc-4372-a567-0e02b2c3d479"
71
66
 
72
67
  ### Bundle Size Impact
73
68
 
74
- The main library bundle is only **277 bytes**! Individual module imports are even smaller:
75
-
76
- ```typescript
77
- // This adds ~50 bytes to your bundle
78
- import { today } from '@rtorcato/js-common/date'
79
-
80
- // This adds ~100 bytes to your bundle
81
- import { sum, average } from '@rtorcato/js-common/numbers'
82
- ```
69
+ Each module is shipped as its own subpath export so bundlers only include what you import. Individual modules range from ~100 bytes (e.g. `sleep`) to ~2 KB (e.g. `currency`) when minified. Measure against your own bundle with [bundlejs.com](https://bundlejs.com/?q=@rtorcato/js-common/numbers).
83
70
 
84
71
  ### ๐ŸŽฏ **TypeScript Support**
85
72
 
@@ -160,7 +147,7 @@ import { sleep } from '@rtorcato/js-common/sleep'
160
147
 
161
148
  ## Requirements
162
149
 
163
- - **Node.js** >= 18.0.0
150
+ - **Node.js** >= 22.0.0 (enforced via the `engines` field)
164
151
  - **TypeScript** >= 5.0.0 (for TypeScript projects)
165
152
 
166
153
  ## Why This Library?
@@ -171,17 +158,10 @@ Unlike larger utility libraries, js-common is designed for modern applications:
171
158
  - **Tree-shakeable** - Only import what you use
172
159
  - **CLI included** - Use utilities in scripts and terminal
173
160
 
174
- ### ๐Ÿ“ฆ **Bundle Size Comparison**
175
- ```
176
- lodash: ~70KB (full) / ~25KB (common functions)
177
- ramda: ~60KB (full) / ~15KB (common functions)
178
- js-common: 277 bytes (full) / ~50-200 bytes (individual modules)
179
- ```
180
-
181
161
  ### ๐Ÿ› ๏ธ **Modern Development**
182
162
  - Built with **TypeScript** for excellent DX
183
- - **ESM-first** with CommonJS compatibility
184
- - **No dependencies in utility modules** โ€” CLI packages (chalk, commander, etc.) are isolated to the `cli` subpath
163
+ - **ESM-only**, native subpath exports
164
+ - **Minimal runtime deps** โ€” CLI packages (`chalk`, `commander`, `figlet`, โ€ฆ) are `optionalDependencies` and only fetched when you opt in to the CLI
185
165
  - Comprehensive **test coverage**
186
166
 
187
167
  ## Development
@@ -207,6 +187,9 @@ pnpm run check:fix
207
187
 
208
188
  # Type checking
209
189
  pnpm run typecheck
190
+
191
+ # Run micro-benchmarks (scripts/benchmark.mjs)
192
+ pnpm run benchmark
210
193
  ```
211
194
 
212
195
  ## Documentation site
@@ -0,0 +1 @@
1
+ import{b as e}from"./chunk-FBDKWWIQ.js";import o from"pino";var i=e()?o({level:"debug",transport:{target:"pino-pretty",options:{colorize:!0,ignore:"pid,hostname,time",levelFirst:!1,singleLine:!0,customColors:"err:red,info:blue",translateTime:"HH:MM:ss"}}}):o({level:"info"});export{i as a};
@@ -0,0 +1,3 @@
1
+ import{z as n}from"zod";var c=(r,o)=>{let e=process.env[r.toString()];if(e===void 0&&o!==void 0)return o;if(e===void 0){let t=`Undefined ENV variable - ${r.toString()}`;throw new Error(t)}return e},d=()=>process.env.NODE_ENV==="development",p=()=>process.env.NODE_ENV==="production",E=()=>process.env.NODE_ENV==="test",u=()=>process.env.NODE_ENV||"development";function a(r,o=process.env){try{return r.parse(o)}catch(e){if(e instanceof n.ZodError){let t=`Missing required values in .env:
2
+ `;t+=Object.keys(e.flatten().fieldErrors).join(`
3
+ `);let s=new Error(t);throw s.stack="",s}throw e}}var f=n.object({NODE_ENV:n.enum(["development","test","production"]).default("development"),LOG_LEVEL:n.enum(["debug","info","warn","error"]).default("info"),PORT:n.coerce.number().default(3e3)});export{c as a,d as b,p as c,E as d,u as e,a as f,f as g};
@@ -0,0 +1,439 @@
1
+ import { Separator, checkbox, select } from '@inquirer/prompts';
2
+ import chalk from 'chalk';
3
+ import chalkAnimation from 'chalk-animation';
4
+ import { program } from 'commander';
5
+ import figlet from 'figlet';
6
+ import gradient from 'gradient-string';
7
+ import { readFileSync } from 'node:fs';
8
+ import { dirname, resolve } from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+ // Get current directory
11
+ const currentDir = dirname(fileURLToPath(import.meta.url));
12
+ // Get package version
13
+ const packageJson = JSON.parse(readFileSync(resolve(currentDir, '../../package.json'), 'utf-8'));
14
+ program
15
+ .name('js-common')
16
+ .description(chalk.cyan('โœจ CLI utilities from @rtorcato/js-common'))
17
+ .version(packageJson.version);
18
+ // Function categories for list and interactive mode
19
+ const functionCategories = {
20
+ date: {
21
+ name: '๐Ÿ“… Date & Time',
22
+ functions: [
23
+ { name: 'today', description: "Get today's date (YYYY-MM-DD)" },
24
+ { name: 'now', description: 'Get current timestamp' },
25
+ { name: 'between', description: 'Calculate days between dates' },
26
+ ],
27
+ },
28
+ math: {
29
+ name: '๐Ÿ”ข Mathematical',
30
+ functions: [
31
+ { name: 'sum', description: 'Calculate sum of numbers' },
32
+ { name: 'avg', description: 'Calculate average of numbers' },
33
+ { name: 'random', description: 'Generate random number' },
34
+ { name: 'round', description: 'Round to decimal places' },
35
+ { name: 'clamp', description: 'Clamp between min/max' },
36
+ ],
37
+ },
38
+ text: {
39
+ name: '๐Ÿ“ Text Formatting',
40
+ functions: [
41
+ { name: 'capitalize', description: 'Capitalize first letter' },
42
+ { name: 'title', description: 'Convert to title case' },
43
+ { name: 'pad', description: 'Pad with leading zeros' },
44
+ ],
45
+ },
46
+ file: {
47
+ name: '๐Ÿ“ File Operations',
48
+ functions: [
49
+ { name: 'exists', description: 'Check if file exists' },
50
+ { name: 'ext', description: 'Get file extension' },
51
+ ],
52
+ },
53
+ security: {
54
+ name: '๐Ÿ”’ Security',
55
+ functions: [
56
+ { name: 'password', description: 'Check password strength' },
57
+ { name: 'token', description: 'Generate secure token' },
58
+ ],
59
+ },
60
+ validate: {
61
+ name: 'โœ… Validation',
62
+ functions: [{ name: 'url', description: 'Validate URL format' }],
63
+ },
64
+ system: {
65
+ name: '๐Ÿ’ป System Info',
66
+ functions: [
67
+ { name: 'pid', description: 'Get process ID' },
68
+ { name: 'uptime', description: 'Get process uptime' },
69
+ { name: 'ci', description: 'Check CI environment' },
70
+ { name: 'node-version', description: 'Get Node.js version' },
71
+ ],
72
+ },
73
+ };
74
+ // List all functions - add as a separate command
75
+ program
76
+ .command('list')
77
+ .alias('ls')
78
+ .description('๐Ÿ“‹ List all available functions')
79
+ .action(() => {
80
+ console.log(chalk.cyan('\nโœจ Available Functions:\n'));
81
+ Object.entries(functionCategories).forEach(([key, category]) => {
82
+ console.log(chalk.bold(category.name));
83
+ console.log(); // Add space after category header
84
+ category.functions.forEach((func) => {
85
+ console.log(chalk.gray(` js-common ${key} ${func.name}`) + chalk.dim(` - ${func.description}`));
86
+ });
87
+ console.log(); // Add space after function list
88
+ });
89
+ console.log(chalk.yellow('๐Ÿ’ก Use ') +
90
+ chalk.green('js-common add') +
91
+ chalk.yellow(' to integrate functions into your project'));
92
+ console.log(chalk.yellow('๐Ÿ’ก Use ') +
93
+ chalk.green('js-common interactive') +
94
+ chalk.yellow(' for interactive mode'));
95
+ console.log(chalk.yellow('๐Ÿ’ก Use ') +
96
+ chalk.green('js-common <command> --help') +
97
+ chalk.yellow(' for detailed help\n'));
98
+ });
99
+ // Also add as an option for compatibility
100
+ program.option('-l, --list', 'List all available functions');
101
+ // Interactive mode
102
+ program
103
+ .command('interactive')
104
+ .alias('i')
105
+ .description('๐ŸŽฎ Interactive mode with guided prompts')
106
+ .action(async () => {
107
+ // Welcome animation
108
+ const title = figlet.textSync('JS Common', { font: 'Small' });
109
+ console.log(gradient.pastel.multiline(title));
110
+ const rainbow = chalkAnimation.rainbow('\nโœจ Welcome to JS Common Interactive Mode! โœจ\n');
111
+ await new Promise((resolve) => setTimeout(resolve, 1000));
112
+ rainbow.stop();
113
+ try {
114
+ // Main interactive loop
115
+ while (true) {
116
+ const category = await select({
117
+ message: chalk.cyan('What would you like to do?'),
118
+ choices: Object.entries(functionCategories)
119
+ .reduce((acc, [key, cat], index) => {
120
+ acc.push({ name: cat.name, value: key });
121
+ if (index < Object.entries(functionCategories).length - 1) {
122
+ acc.push(new Separator(' '));
123
+ }
124
+ return acc;
125
+ }, [])
126
+ .concat([new Separator(' '), { name: chalk.red('โŒ Exit'), value: 'exit' }]),
127
+ pageSize: 17,
128
+ loop: false,
129
+ });
130
+ // Handle exit selection
131
+ if (category === 'exit') {
132
+ console.log(chalk.yellow('\n๐Ÿ‘‹ Goodbye!\n'));
133
+ return;
134
+ }
135
+ const selectedCategory = functionCategories[category];
136
+ // Function selection loop
137
+ while (true) {
138
+ const functionName = await select({
139
+ message: chalk.cyan(`Choose a ${selectedCategory.name} function:`),
140
+ choices: selectedCategory.functions
141
+ .reduce((acc, func, index) => {
142
+ acc.push({ name: `${func.name} - ${func.description}`, value: func.name });
143
+ if (index < selectedCategory.functions.length - 1) {
144
+ acc.push(new Separator(' '));
145
+ }
146
+ return acc;
147
+ }, [])
148
+ .concat([
149
+ new Separator(' '),
150
+ { name: chalk.gray('โฌ…๏ธ Back to categories'), value: 'back' },
151
+ { name: chalk.red('โŒ Exit'), value: 'exit' },
152
+ ]),
153
+ pageSize: 12,
154
+ loop: false,
155
+ });
156
+ // Handle navigation options
157
+ if (functionName === 'exit') {
158
+ console.log(chalk.yellow('\n๐Ÿ‘‹ Goodbye!\n'));
159
+ return;
160
+ }
161
+ if (functionName === 'back') {
162
+ break; // Break out of function selection loop, go back to categories
163
+ }
164
+ // Show the command
165
+ console.log(chalk.green(`\n๐Ÿš€ You can run this command:`));
166
+ console.log(chalk.yellow(`js-common ${category} ${functionName} [arguments]`));
167
+ console.log(chalk.gray(`\nFor detailed usage, run: js-common ${category} ${functionName} --help\n`));
168
+ return; // Exit after showing the command
169
+ }
170
+ }
171
+ }
172
+ catch (error) {
173
+ if (error && typeof error === 'object' && 'isTtyError' in error) {
174
+ console.log(chalk.red('\nโŒ Interactive mode requires a TTY terminal'));
175
+ }
176
+ else {
177
+ console.log(chalk.red('\nโŒ Something went wrong in interactive mode'));
178
+ }
179
+ process.exit(1);
180
+ }
181
+ });
182
+ // Add command - help developers integrate functions into their projects
183
+ program
184
+ .command('add')
185
+ .alias('a')
186
+ .description('๐Ÿ”ง Add utility functions to your project')
187
+ .action(async () => {
188
+ // Welcome message
189
+ console.log(gradient.pastel('\n๐Ÿ”ง Function Integration Helper\n'));
190
+ try {
191
+ const category = await select({
192
+ message: chalk.cyan('Which category of utilities do you need?'),
193
+ choices: Object.entries(functionCategories)
194
+ .reduce((acc, [key, cat], index) => {
195
+ acc.push({ name: cat.name, value: key });
196
+ if (index < Object.entries(functionCategories).length - 1) {
197
+ acc.push(new Separator(' '));
198
+ }
199
+ return acc;
200
+ }, [])
201
+ .concat([new Separator(' '), { name: chalk.red('โŒ Exit'), value: 'exit' }]),
202
+ pageSize: 17,
203
+ loop: false,
204
+ });
205
+ // Handle exit selection
206
+ if (category === 'exit') {
207
+ console.log(chalk.yellow('\n๐Ÿ‘‹ Goodbye!\n'));
208
+ return;
209
+ }
210
+ const selectedCategory = functionCategories[category];
211
+ const functions = await checkbox({
212
+ message: chalk.cyan(`Select ${selectedCategory.name} functions to add:`),
213
+ choices: selectedCategory.functions.map((func) => ({
214
+ name: `${func.name} - ${func.description}`,
215
+ value: func.name,
216
+ checked: false,
217
+ })),
218
+ pageSize: 10,
219
+ loop: false,
220
+ });
221
+ if (functions.length === 0) {
222
+ console.log(chalk.yellow('\n๐Ÿ“ No functions selected. Exiting...\n'));
223
+ return;
224
+ }
225
+ console.log(chalk.green('\n๐Ÿ“ฆ Import Statement:'));
226
+ console.log(chalk.white(`import { ${functions.join(', ')} } from '@rtorcato/js-common/${category}'`));
227
+ console.log(chalk.green('\n๐Ÿ“ Usage Examples:'));
228
+ functions.forEach((func) => {
229
+ const funcInfo = selectedCategory.functions.find((f) => f.name === func);
230
+ if (funcInfo) {
231
+ console.log(chalk.gray(`\n// ${funcInfo.description}`));
232
+ generateUsageExample(category, func);
233
+ }
234
+ });
235
+ console.log(chalk.green('\n๐Ÿ“š Documentation:'));
236
+ console.log(chalk.blue(`https://github.com/rtorcato/js-common#${category}-utilities`));
237
+ console.log(chalk.yellow('\n๐Ÿ’ก Tip: Run ') +
238
+ chalk.green(`js-common ${category} ${functions[0]} --help`) +
239
+ chalk.yellow(' for detailed CLI usage\n'));
240
+ }
241
+ catch (error) {
242
+ if (error && typeof error === 'object' && 'isTtyError' in error) {
243
+ console.log(chalk.red('\nโŒ Interactive mode requires a TTY terminal'));
244
+ }
245
+ else {
246
+ console.log(chalk.red('\nโŒ Something went wrong'));
247
+ }
248
+ process.exit(1);
249
+ }
250
+ });
251
+ // Helper function to generate usage examples
252
+ function generateUsageExample(category, functionName) {
253
+ const examples = {
254
+ date: {
255
+ today: `const today = today(); // "${new Date().toISOString().split('T')[0]}"`,
256
+ now: `const timestamp = now(); // ${Date.now()}`,
257
+ between: `const days = daysBetween('2023-01-01', '2023-12-31'); // 364`,
258
+ },
259
+ math: {
260
+ sum: `const total = sum([1, 2, 3, 4, 5]); // 15`,
261
+ avg: `const average = avg([10, 20, 30]); // 20`,
262
+ random: `const num = randomBetween(1, 100); // 42`,
263
+ round: `const rounded = roundTo(3.14159, 2); // 3.14`,
264
+ clamp: `const clamped = clamp(150, 0, 100); // 100`,
265
+ },
266
+ text: {
267
+ capitalize: `const text = capitalize('hello world'); // "Hello world"`,
268
+ title: `const title = toTitleCase('hello world'); // "Hello World"`,
269
+ pad: `const padded = padWithZeros(42, 5); // "00042"`,
270
+ },
271
+ file: {
272
+ exists: `const exists = await fileExists('package.json'); // true`,
273
+ ext: `const extension = getFileExtension('file.txt'); // "txt"`,
274
+ },
275
+ security: {
276
+ password: `const isStrong = checkPasswordStrength('MyPass123!'); // true`,
277
+ token: `const token = generateSecureToken(32); // "abc123..."`,
278
+ },
279
+ validate: {
280
+ url: `const isValid = isValidUrl('https://example.com'); // true`,
281
+ },
282
+ system: {
283
+ pid: `const processId = getProcessId(); // 12345`,
284
+ uptime: `const uptime = getProcessUptime(); // 123.45`,
285
+ ci: `const isCI = isCiEnvironment(); // false`,
286
+ 'node-version': `const version = getNodeVersion(); // "18.17.0"`,
287
+ },
288
+ };
289
+ const example = examples[category]?.[functionName];
290
+ if (example) {
291
+ console.log(chalk.white(example));
292
+ }
293
+ }
294
+ // Date commands
295
+ const dateCmd = program.command('date').description('๐Ÿ“… Date and time utilities');
296
+ dateCmd
297
+ .command('today')
298
+ .description("Get today's date (YYYY-MM-DD)")
299
+ .action(() => {
300
+ console.log(new Date().toISOString().split('T')[0]);
301
+ });
302
+ dateCmd
303
+ .command('now')
304
+ .description('Get current timestamp')
305
+ .option('-i, --iso', 'ISO format')
306
+ .option('-t, --time', 'Time only')
307
+ .action((options) => {
308
+ if (options.iso) {
309
+ console.log(new Date().toISOString());
310
+ }
311
+ else if (options.time) {
312
+ console.log(new Date().toTimeString());
313
+ }
314
+ else {
315
+ console.log(Date.now());
316
+ }
317
+ });
318
+ dateCmd
319
+ .command('between')
320
+ .description('Calculate days between dates')
321
+ .argument('<date1>', 'First date (YYYY-MM-DD)')
322
+ .argument('<date2>', 'Second date (YYYY-MM-DD)')
323
+ .action((date1, date2) => {
324
+ const d1 = new Date(date1);
325
+ const d2 = new Date(date2);
326
+ const timeDiff = Math.abs(d2.getTime() - d1.getTime());
327
+ const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
328
+ console.log(`${daysDiff} days`);
329
+ });
330
+ // Math commands
331
+ const mathCmd = program.command('math').description('๐Ÿ”ข Mathematical utilities');
332
+ mathCmd
333
+ .command('sum')
334
+ .description('Calculate sum of numbers')
335
+ .argument('<numbers...>', 'Numbers to sum')
336
+ .action((numbers) => {
337
+ const nums = numbers.map(Number).filter((n) => !Number.isNaN(n));
338
+ console.log(nums.reduce((a, b) => a + b, 0));
339
+ });
340
+ mathCmd
341
+ .command('avg')
342
+ .description('Calculate average of numbers')
343
+ .argument('<numbers...>', 'Numbers to average')
344
+ .action((numbers) => {
345
+ const nums = numbers.map(Number).filter((n) => !Number.isNaN(n));
346
+ console.log(nums.reduce((a, b) => a + b, 0) / nums.length);
347
+ });
348
+ mathCmd
349
+ .command('random')
350
+ .description('Generate random number')
351
+ .argument('<min>', 'Minimum value')
352
+ .argument('<max>', 'Maximum value')
353
+ .action((min, max) => {
354
+ const minNum = Number(min);
355
+ const maxNum = Number(max);
356
+ console.log(Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
357
+ });
358
+ mathCmd
359
+ .command('round')
360
+ .description('Round to decimal places')
361
+ .argument('<number>', 'Number to round')
362
+ .argument('<decimals>', 'Decimal places')
363
+ .action((number, decimals) => {
364
+ const num = Number(number);
365
+ const dec = Number(decimals);
366
+ console.log(Number(num.toFixed(dec)));
367
+ });
368
+ mathCmd
369
+ .command('clamp')
370
+ .description('Clamp between min/max')
371
+ .argument('<number>', 'Number to clamp')
372
+ .argument('<min>', 'Minimum value')
373
+ .argument('<max>', 'Maximum value')
374
+ .action((number, min, max) => {
375
+ const num = Number(number);
376
+ const minVal = Number(min);
377
+ const maxVal = Number(max);
378
+ console.log(Math.min(Math.max(num, minVal), maxVal));
379
+ });
380
+ // Simple implementations for other commands
381
+ const textCmd = program.command('text').description('๐Ÿ“ Text formatting utilities');
382
+ textCmd
383
+ .command('capitalize')
384
+ .description('Capitalize first letter')
385
+ .argument('<text>', 'Text to capitalize')
386
+ .action((text) => {
387
+ console.log(text.charAt(0).toUpperCase() + text.slice(1));
388
+ });
389
+ textCmd
390
+ .command('title')
391
+ .description('Convert to title case')
392
+ .argument('<text>', 'Text to convert')
393
+ .action((text) => {
394
+ console.log(text.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase()));
395
+ });
396
+ // System commands
397
+ const systemCmd = program.command('system').description('๐Ÿ’ป System information utilities');
398
+ systemCmd
399
+ .command('pid')
400
+ .description('Get process ID')
401
+ .action(() => {
402
+ console.log(process.pid);
403
+ });
404
+ systemCmd
405
+ .command('uptime')
406
+ .description('Get process uptime')
407
+ .action(() => {
408
+ console.log(`${Math.floor(process.uptime())} seconds`);
409
+ });
410
+ systemCmd
411
+ .command('node-version')
412
+ .description('Get Node.js version')
413
+ .action(() => {
414
+ console.log(process.version);
415
+ });
416
+ // Handle --list option before parsing
417
+ if (process.argv.includes('--list') || process.argv.includes('-l')) {
418
+ console.log(chalk.cyan('\nโœจ Available Functions:\n'));
419
+ Object.entries(functionCategories).forEach(([key, category]) => {
420
+ console.log(chalk.bold(category.name));
421
+ console.log(); // Add space after category header
422
+ category.functions.forEach((func) => {
423
+ console.log(chalk.gray(` js-common ${key} ${func.name}`) + chalk.dim(` - ${func.description}`));
424
+ });
425
+ console.log(); // Add space after function list
426
+ });
427
+ console.log(chalk.yellow('๐Ÿ’ก Use ') +
428
+ chalk.green('js-common add') +
429
+ chalk.yellow(' to integrate functions into your project'));
430
+ console.log(chalk.yellow('๐Ÿ’ก Use ') +
431
+ chalk.green('js-common interactive') +
432
+ chalk.yellow(' for interactive mode'));
433
+ console.log(chalk.yellow('๐Ÿ’ก Use ') +
434
+ chalk.green('js-common <command> --help') +
435
+ chalk.yellow(' for detailed help\n'));
436
+ process.exit(0);
437
+ }
438
+ // Parse command line arguments
439
+ program.parse();
@@ -1,440 +1,26 @@
1
1
  #!/usr/bin/env node
2
- import { Separator, checkbox, select } from '@inquirer/prompts';
3
- import chalk from 'chalk';
4
- import chalkAnimation from 'chalk-animation';
5
- import { program } from 'commander';
6
- import figlet from 'figlet';
7
- import gradient from 'gradient-string';
8
- import { readFileSync } from 'node:fs';
9
- import { dirname, resolve } from 'node:path';
10
- import { fileURLToPath } from 'node:url';
11
- // Get current directory
12
- const currentDir = dirname(fileURLToPath(import.meta.url));
13
- // Get package version
14
- const packageJson = JSON.parse(readFileSync(resolve(currentDir, '../../package.json'), 'utf-8'));
15
- program
16
- .name('js-common')
17
- .description(chalk.cyan('โœจ CLI utilities from @rtorcato/js-common'))
18
- .version(packageJson.version);
19
- // Function categories for list and interactive mode
20
- const functionCategories = {
21
- date: {
22
- name: '๐Ÿ“… Date & Time',
23
- functions: [
24
- { name: 'today', description: "Get today's date (YYYY-MM-DD)" },
25
- { name: 'now', description: 'Get current timestamp' },
26
- { name: 'between', description: 'Calculate days between dates' },
27
- ],
28
- },
29
- math: {
30
- name: '๐Ÿ”ข Mathematical',
31
- functions: [
32
- { name: 'sum', description: 'Calculate sum of numbers' },
33
- { name: 'avg', description: 'Calculate average of numbers' },
34
- { name: 'random', description: 'Generate random number' },
35
- { name: 'round', description: 'Round to decimal places' },
36
- { name: 'clamp', description: 'Clamp between min/max' },
37
- ],
38
- },
39
- text: {
40
- name: '๐Ÿ“ Text Formatting',
41
- functions: [
42
- { name: 'capitalize', description: 'Capitalize first letter' },
43
- { name: 'title', description: 'Convert to title case' },
44
- { name: 'pad', description: 'Pad with leading zeros' },
45
- ],
46
- },
47
- file: {
48
- name: '๐Ÿ“ File Operations',
49
- functions: [
50
- { name: 'exists', description: 'Check if file exists' },
51
- { name: 'ext', description: 'Get file extension' },
52
- ],
53
- },
54
- security: {
55
- name: '๐Ÿ”’ Security',
56
- functions: [
57
- { name: 'password', description: 'Check password strength' },
58
- { name: 'token', description: 'Generate secure token' },
59
- ],
60
- },
61
- validate: {
62
- name: 'โœ… Validation',
63
- functions: [{ name: 'url', description: 'Validate URL format' }],
64
- },
65
- system: {
66
- name: '๐Ÿ’ป System Info',
67
- functions: [
68
- { name: 'pid', description: 'Get process ID' },
69
- { name: 'uptime', description: 'Get process uptime' },
70
- { name: 'ci', description: 'Check CI environment' },
71
- { name: 'node-version', description: 'Get Node.js version' },
72
- ],
73
- },
74
- };
75
- // List all functions - add as a separate command
76
- program
77
- .command('list')
78
- .alias('ls')
79
- .description('๐Ÿ“‹ List all available functions')
80
- .action(() => {
81
- console.log(chalk.cyan('\nโœจ Available Functions:\n'));
82
- Object.entries(functionCategories).forEach(([key, category]) => {
83
- console.log(chalk.bold(category.name));
84
- console.log(); // Add space after category header
85
- category.functions.forEach((func) => {
86
- console.log(chalk.gray(` js-common ${key} ${func.name}`) + chalk.dim(` - ${func.description}`));
87
- });
88
- console.log(); // Add space after function list
89
- });
90
- console.log(chalk.yellow('๐Ÿ’ก Use ') +
91
- chalk.green('js-common add') +
92
- chalk.yellow(' to integrate functions into your project'));
93
- console.log(chalk.yellow('๐Ÿ’ก Use ') +
94
- chalk.green('js-common interactive') +
95
- chalk.yellow(' for interactive mode'));
96
- console.log(chalk.yellow('๐Ÿ’ก Use ') +
97
- chalk.green('js-common <command> --help') +
98
- chalk.yellow(' for detailed help\n'));
99
- });
100
- // Also add as an option for compatibility
101
- program.option('-l, --list', 'List all available functions');
102
- // Interactive mode
103
- program
104
- .command('interactive')
105
- .alias('i')
106
- .description('๐ŸŽฎ Interactive mode with guided prompts')
107
- .action(async () => {
108
- // Welcome animation
109
- const title = figlet.textSync('JS Common', { font: 'Small' });
110
- console.log(gradient.pastel.multiline(title));
111
- const rainbow = chalkAnimation.rainbow('\nโœจ Welcome to JS Common Interactive Mode! โœจ\n');
112
- await new Promise((resolve) => setTimeout(resolve, 1000));
113
- rainbow.stop();
114
- try {
115
- // Main interactive loop
116
- while (true) {
117
- const category = await select({
118
- message: chalk.cyan('What would you like to do?'),
119
- choices: Object.entries(functionCategories)
120
- .reduce((acc, [key, cat], index) => {
121
- acc.push({ name: cat.name, value: key });
122
- if (index < Object.entries(functionCategories).length - 1) {
123
- acc.push(new Separator(' '));
124
- }
125
- return acc;
126
- }, [])
127
- .concat([new Separator(' '), { name: chalk.red('โŒ Exit'), value: 'exit' }]),
128
- pageSize: 17,
129
- loop: false,
130
- });
131
- // Handle exit selection
132
- if (category === 'exit') {
133
- console.log(chalk.yellow('\n๐Ÿ‘‹ Goodbye!\n'));
134
- return;
135
- }
136
- const selectedCategory = functionCategories[category];
137
- // Function selection loop
138
- while (true) {
139
- const functionName = await select({
140
- message: chalk.cyan(`Choose a ${selectedCategory.name} function:`),
141
- choices: selectedCategory.functions
142
- .reduce((acc, func, index) => {
143
- acc.push({ name: `${func.name} - ${func.description}`, value: func.name });
144
- if (index < selectedCategory.functions.length - 1) {
145
- acc.push(new Separator(' '));
146
- }
147
- return acc;
148
- }, [])
149
- .concat([
150
- new Separator(' '),
151
- { name: chalk.gray('โฌ…๏ธ Back to categories'), value: 'back' },
152
- { name: chalk.red('โŒ Exit'), value: 'exit' },
153
- ]),
154
- pageSize: 12,
155
- loop: false,
156
- });
157
- // Handle navigation options
158
- if (functionName === 'exit') {
159
- console.log(chalk.yellow('\n๐Ÿ‘‹ Goodbye!\n'));
160
- return;
161
- }
162
- if (functionName === 'back') {
163
- break; // Break out of function selection loop, go back to categories
164
- }
165
- // Show the command
166
- console.log(chalk.green(`\n๐Ÿš€ You can run this command:`));
167
- console.log(chalk.yellow(`js-common ${category} ${functionName} [arguments]`));
168
- console.log(chalk.gray(`\nFor detailed usage, run: js-common ${category} ${functionName} --help\n`));
169
- return; // Exit after showing the command
170
- }
171
- }
172
- }
173
- catch (error) {
174
- if (error && typeof error === 'object' && 'isTtyError' in error) {
175
- console.log(chalk.red('\nโŒ Interactive mode requires a TTY terminal'));
176
- }
177
- else {
178
- console.log(chalk.red('\nโŒ Something went wrong in interactive mode'));
179
- }
180
- process.exit(1);
181
- }
182
- });
183
- // Add command - help developers integrate functions into their projects
184
- program
185
- .command('add')
186
- .alias('a')
187
- .description('๐Ÿ”ง Add utility functions to your project')
188
- .action(async () => {
189
- // Welcome message
190
- console.log(gradient.pastel('\n๐Ÿ”ง Function Integration Helper\n'));
191
- try {
192
- const category = await select({
193
- message: chalk.cyan('Which category of utilities do you need?'),
194
- choices: Object.entries(functionCategories)
195
- .reduce((acc, [key, cat], index) => {
196
- acc.push({ name: cat.name, value: key });
197
- if (index < Object.entries(functionCategories).length - 1) {
198
- acc.push(new Separator(' '));
199
- }
200
- return acc;
201
- }, [])
202
- .concat([new Separator(' '), { name: chalk.red('โŒ Exit'), value: 'exit' }]),
203
- pageSize: 17,
204
- loop: false,
205
- });
206
- // Handle exit selection
207
- if (category === 'exit') {
208
- console.log(chalk.yellow('\n๐Ÿ‘‹ Goodbye!\n'));
209
- return;
210
- }
211
- const selectedCategory = functionCategories[category];
212
- const functions = await checkbox({
213
- message: chalk.cyan(`Select ${selectedCategory.name} functions to add:`),
214
- choices: selectedCategory.functions.map((func) => ({
215
- name: `${func.name} - ${func.description}`,
216
- value: func.name,
217
- checked: false,
218
- })),
219
- pageSize: 10,
220
- loop: false,
221
- });
222
- if (functions.length === 0) {
223
- console.log(chalk.yellow('\n๐Ÿ“ No functions selected. Exiting...\n'));
224
- return;
225
- }
226
- console.log(chalk.green('\n๐Ÿ“ฆ Import Statement:'));
227
- console.log(chalk.white(`import { ${functions.join(', ')} } from '@rtorcato/js-common/${category}'`));
228
- console.log(chalk.green('\n๐Ÿ“ Usage Examples:'));
229
- functions.forEach((func) => {
230
- const funcInfo = selectedCategory.functions.find((f) => f.name === func);
231
- if (funcInfo) {
232
- console.log(chalk.gray(`\n// ${funcInfo.description}`));
233
- generateUsageExample(category, func);
234
- }
235
- });
236
- console.log(chalk.green('\n๐Ÿ“š Documentation:'));
237
- console.log(chalk.blue(`https://github.com/rtorcato/js-common#${category}-utilities`));
238
- console.log(chalk.yellow('\n๐Ÿ’ก Tip: Run ') +
239
- chalk.green(`js-common ${category} ${functions[0]} --help`) +
240
- chalk.yellow(' for detailed CLI usage\n'));
241
- }
242
- catch (error) {
243
- if (error && typeof error === 'object' && 'isTtyError' in error) {
244
- console.log(chalk.red('\nโŒ Interactive mode requires a TTY terminal'));
245
- }
246
- else {
247
- console.log(chalk.red('\nโŒ Something went wrong'));
248
- }
249
- process.exit(1);
250
- }
251
- });
252
- // Helper function to generate usage examples
253
- function generateUsageExample(category, functionName) {
254
- const examples = {
255
- date: {
256
- today: `const today = today(); // "${new Date().toISOString().split('T')[0]}"`,
257
- now: `const timestamp = now(); // ${Date.now()}`,
258
- between: `const days = daysBetween('2023-01-01', '2023-12-31'); // 364`,
259
- },
260
- math: {
261
- sum: `const total = sum([1, 2, 3, 4, 5]); // 15`,
262
- avg: `const average = avg([10, 20, 30]); // 20`,
263
- random: `const num = randomBetween(1, 100); // 42`,
264
- round: `const rounded = roundTo(3.14159, 2); // 3.14`,
265
- clamp: `const clamped = clamp(150, 0, 100); // 100`,
266
- },
267
- text: {
268
- capitalize: `const text = capitalize('hello world'); // "Hello world"`,
269
- title: `const title = toTitleCase('hello world'); // "Hello World"`,
270
- pad: `const padded = padWithZeros(42, 5); // "00042"`,
271
- },
272
- file: {
273
- exists: `const exists = await fileExists('package.json'); // true`,
274
- ext: `const extension = getFileExtension('file.txt'); // "txt"`,
275
- },
276
- security: {
277
- password: `const isStrong = checkPasswordStrength('MyPass123!'); // true`,
278
- token: `const token = generateSecureToken(32); // "abc123..."`,
279
- },
280
- validate: {
281
- url: `const isValid = isValidUrl('https://example.com'); // true`,
282
- },
283
- system: {
284
- pid: `const processId = getProcessId(); // 12345`,
285
- uptime: `const uptime = getProcessUptime(); // 123.45`,
286
- ci: `const isCI = isCiEnvironment(); // false`,
287
- 'node-version': `const version = getNodeVersion(); // "18.17.0"`,
288
- },
289
- };
290
- const example = examples[category]?.[functionName];
291
- if (example) {
292
- console.log(chalk.white(example));
293
- }
2
+ // Entry point for the js-common CLI binary.
3
+ // CLI-only npm deps (chalk, commander, figlet, โ€ฆ) live under
4
+ // `optionalDependencies` to keep the install footprint small for
5
+ // library-only consumers. If any of them is missing at runtime we
6
+ // catch the resolution error and print install instructions instead
7
+ // of letting Node emit an opaque ERR_MODULE_NOT_FOUND trace.
8
+ try {
9
+ await import('./cli.mjs');
294
10
  }
295
- // Date commands
296
- const dateCmd = program.command('date').description('๐Ÿ“… Date and time utilities');
297
- dateCmd
298
- .command('today')
299
- .description("Get today's date (YYYY-MM-DD)")
300
- .action(() => {
301
- console.log(new Date().toISOString().split('T')[0]);
302
- });
303
- dateCmd
304
- .command('now')
305
- .description('Get current timestamp')
306
- .option('-i, --iso', 'ISO format')
307
- .option('-t, --time', 'Time only')
308
- .action((options) => {
309
- if (options.iso) {
310
- console.log(new Date().toISOString());
311
- }
312
- else if (options.time) {
313
- console.log(new Date().toTimeString());
314
- }
315
- else {
316
- console.log(Date.now());
11
+ catch (err) {
12
+ const isMissingModule = err !== null &&
13
+ typeof err === 'object' &&
14
+ 'code' in err &&
15
+ err.code === 'ERR_MODULE_NOT_FOUND';
16
+ if (isMissingModule) {
17
+ process.stderr.write('The js-common CLI requires optional dependencies that are not installed.\n' +
18
+ 'Install them globally to use the CLI:\n\n' +
19
+ ' npm install -g @rtorcato/js-common\n\n' +
20
+ 'Or run it ad-hoc with npx, which installs them on demand:\n\n' +
21
+ ' npx @rtorcato/js-common@latest --help\n');
22
+ process.exit(1);
317
23
  }
318
- });
319
- dateCmd
320
- .command('between')
321
- .description('Calculate days between dates')
322
- .argument('<date1>', 'First date (YYYY-MM-DD)')
323
- .argument('<date2>', 'Second date (YYYY-MM-DD)')
324
- .action((date1, date2) => {
325
- const d1 = new Date(date1);
326
- const d2 = new Date(date2);
327
- const timeDiff = Math.abs(d2.getTime() - d1.getTime());
328
- const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
329
- console.log(`${daysDiff} days`);
330
- });
331
- // Math commands
332
- const mathCmd = program.command('math').description('๐Ÿ”ข Mathematical utilities');
333
- mathCmd
334
- .command('sum')
335
- .description('Calculate sum of numbers')
336
- .argument('<numbers...>', 'Numbers to sum')
337
- .action((numbers) => {
338
- const nums = numbers.map(Number).filter((n) => !Number.isNaN(n));
339
- console.log(nums.reduce((a, b) => a + b, 0));
340
- });
341
- mathCmd
342
- .command('avg')
343
- .description('Calculate average of numbers')
344
- .argument('<numbers...>', 'Numbers to average')
345
- .action((numbers) => {
346
- const nums = numbers.map(Number).filter((n) => !Number.isNaN(n));
347
- console.log(nums.reduce((a, b) => a + b, 0) / nums.length);
348
- });
349
- mathCmd
350
- .command('random')
351
- .description('Generate random number')
352
- .argument('<min>', 'Minimum value')
353
- .argument('<max>', 'Maximum value')
354
- .action((min, max) => {
355
- const minNum = Number(min);
356
- const maxNum = Number(max);
357
- console.log(Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
358
- });
359
- mathCmd
360
- .command('round')
361
- .description('Round to decimal places')
362
- .argument('<number>', 'Number to round')
363
- .argument('<decimals>', 'Decimal places')
364
- .action((number, decimals) => {
365
- const num = Number(number);
366
- const dec = Number(decimals);
367
- console.log(Number(num.toFixed(dec)));
368
- });
369
- mathCmd
370
- .command('clamp')
371
- .description('Clamp between min/max')
372
- .argument('<number>', 'Number to clamp')
373
- .argument('<min>', 'Minimum value')
374
- .argument('<max>', 'Maximum value')
375
- .action((number, min, max) => {
376
- const num = Number(number);
377
- const minVal = Number(min);
378
- const maxVal = Number(max);
379
- console.log(Math.min(Math.max(num, minVal), maxVal));
380
- });
381
- // Simple implementations for other commands
382
- const textCmd = program.command('text').description('๐Ÿ“ Text formatting utilities');
383
- textCmd
384
- .command('capitalize')
385
- .description('Capitalize first letter')
386
- .argument('<text>', 'Text to capitalize')
387
- .action((text) => {
388
- console.log(text.charAt(0).toUpperCase() + text.slice(1));
389
- });
390
- textCmd
391
- .command('title')
392
- .description('Convert to title case')
393
- .argument('<text>', 'Text to convert')
394
- .action((text) => {
395
- console.log(text.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase()));
396
- });
397
- // System commands
398
- const systemCmd = program.command('system').description('๐Ÿ’ป System information utilities');
399
- systemCmd
400
- .command('pid')
401
- .description('Get process ID')
402
- .action(() => {
403
- console.log(process.pid);
404
- });
405
- systemCmd
406
- .command('uptime')
407
- .description('Get process uptime')
408
- .action(() => {
409
- console.log(`${Math.floor(process.uptime())} seconds`);
410
- });
411
- systemCmd
412
- .command('node-version')
413
- .description('Get Node.js version')
414
- .action(() => {
415
- console.log(process.version);
416
- });
417
- // Handle --list option before parsing
418
- if (process.argv.includes('--list') || process.argv.includes('-l')) {
419
- console.log(chalk.cyan('\nโœจ Available Functions:\n'));
420
- Object.entries(functionCategories).forEach(([key, category]) => {
421
- console.log(chalk.bold(category.name));
422
- console.log(); // Add space after category header
423
- category.functions.forEach((func) => {
424
- console.log(chalk.gray(` js-common ${key} ${func.name}`) + chalk.dim(` - ${func.description}`));
425
- });
426
- console.log(); // Add space after function list
427
- });
428
- console.log(chalk.yellow('๐Ÿ’ก Use ') +
429
- chalk.green('js-common add') +
430
- chalk.yellow(' to integrate functions into your project'));
431
- console.log(chalk.yellow('๐Ÿ’ก Use ') +
432
- chalk.green('js-common interactive') +
433
- chalk.yellow(' for interactive mode'));
434
- console.log(chalk.yellow('๐Ÿ’ก Use ') +
435
- chalk.green('js-common <command> --help') +
436
- chalk.yellow(' for detailed help\n'));
437
- process.exit(0);
24
+ throw err;
438
25
  }
439
- // Parse command line arguments
440
- program.parse();
26
+ export {};
package/dist/env/index.js CHANGED
@@ -1,3 +1 @@
1
- import"../chunks/chunk-ANN5UYCF.js";import{z as n}from"zod";var c=(r,o)=>{let e=process.env[r.toString()];if(e===void 0&&o!==void 0)return o;if(e===void 0){let t=`Undefined ENV variable - ${r.toString()}`;throw new Error(t)}return e},d=()=>process.env.NODE_ENV==="development",p=()=>process.env.NODE_ENV==="production",E=()=>process.env.NODE_ENV==="test",u=()=>process.env.NODE_ENV||"development";function a(r,o=process.env){try{return r.parse(o)}catch(e){if(e instanceof n.ZodError){let t=`Missing required values in .env:
2
- `;t+=Object.keys(e.flatten().fieldErrors).join(`
3
- `);let s=new Error(t);throw s.stack="",s}throw e}}var f=n.object({NODE_ENV:n.enum(["development","test","production"]).default("development"),LOG_LEVEL:n.enum(["debug","info","warn","error"]).default("info"),PORT:n.coerce.number().default(3e3)});export{f as RootApiEnvSchema,a as checkEnv,c as getENV,u as getNodeEnv,d as isDev,p as isProd,E as isTest};
1
+ import{a,b,c,d,e,f,g}from"../chunks/chunk-FBDKWWIQ.js";import"../chunks/chunk-ANN5UYCF.js";export{g as RootApiEnvSchema,f as checkEnv,a as getENV,e as getNodeEnv,b as isDev,c as isProd,d as isTest};
package/dist/index.js CHANGED
@@ -1 +0,0 @@
1
- import"./chunks/chunk-ANN5UYCF.js";var t=()=>(console.log("test"),"testPackage");export{t as testPackage};
@@ -0,0 +1 @@
1
+ import{a as o}from"../chunks/chunk-6J7HIWG6.js";import"../chunks/chunk-FBDKWWIQ.js";import"../chunks/chunk-ANN5UYCF.js";export{o as logger};
@@ -0,0 +1 @@
1
+ import{a}from"../chunks/chunk-6J7HIWG6.js";import"../chunks/chunk-FBDKWWIQ.js";import"../chunks/chunk-ANN5UYCF.js";export{a as logger};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rtorcato/js-common",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "description": "JavaScript and TypeScript common code",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -28,7 +28,7 @@
28
28
  "scripts": {
29
29
  "build-dev": "rimraf ./dist && cross-env NODE_ENV=development node build.mjs && tsc --emitDeclarationOnly --project tsconfig.build.json && npm run build-cli",
30
30
  "build-prod": "rimraf ./dist && cross-env NODE_ENV=production node build.mjs && tsc --emitDeclarationOnly --project tsconfig.build.json && npm run build-cli",
31
- "build-cli": "tsc src/cli/cli.ts --ignoreConfig --types node --outDir dist/cli --target ES2022 --module ES2022 --moduleResolution bundler --allowImportingTsExtensions false --esModuleInterop --skipLibCheck && mv dist/cli/cli.js dist/cli/temp.mjs && echo '#!/usr/bin/env node' > dist/cli/index.mjs && cat dist/cli/temp.mjs >> dist/cli/index.mjs && rm dist/cli/temp.mjs && chmod +x dist/cli/index.mjs",
31
+ "build-cli": "tsc src/cli/bootstrap.ts src/cli/cli.ts --ignoreConfig --types node --outDir dist/cli --target ES2022 --module ES2022 --moduleResolution bundler --allowImportingTsExtensions false --esModuleInterop --skipLibCheck && echo '#!/usr/bin/env node' > dist/cli/index.mjs && cat dist/cli/bootstrap.js >> dist/cli/index.mjs && rm dist/cli/bootstrap.js && mv dist/cli/cli.js dist/cli/cli.mjs && sed -i.bak \"s|'./cli.js'|'./cli.mjs'|g\" dist/cli/index.mjs && rm dist/cli/index.mjs.bak && chmod +x dist/cli/index.mjs",
32
32
  "prepublishOnly": "npm run build-prod",
33
33
  "==================== Common ====================": "",
34
34
  "lint": "pnpm exec biome lint .",
@@ -116,6 +116,10 @@
116
116
  "import": "./dist/file/index.js",
117
117
  "types": "./dist/file/index.d.ts"
118
118
  },
119
+ "./formatting": {
120
+ "import": "./dist/formatting/index.js",
121
+ "types": "./dist/formatting/index.d.ts"
122
+ },
119
123
  "./functions": {
120
124
  "import": "./dist/functions/index.js",
121
125
  "types": "./dist/functions/index.d.ts"
@@ -249,7 +253,6 @@
249
253
  "@semantic-release/release-notes-generator": "^14.1.0",
250
254
  "@types/chalk-animation": "^1.6.3",
251
255
  "@types/figlet": "^1.7.0",
252
- "@types/inquirer": "^9.0.9",
253
256
  "@types/luxon": "^3.7.1",
254
257
  "@types/node": "^24.9.1",
255
258
  "@vitest/coverage-istanbul": "^4.0.17",
@@ -265,22 +268,22 @@
265
268
  "vitest": "^4.0.17"
266
269
  },
267
270
  "dependencies": {
268
- "@inquirer/prompts": "^8.5.0",
269
- "chalk": "^5.6.2",
270
- "chalk-animation": "^2.0.3",
271
- "commander": "^14.0.1",
272
271
  "date-fns": "^4.1.0",
273
272
  "date-fns-tz": "^3.2.0",
274
- "figlet": "^1.9.3",
275
- "gradient-string": "^3.0.0",
276
- "inquirer": "^13.3.2",
277
273
  "luxon": "^3.7.2",
278
- "nanospinner": "^1.2.2",
279
274
  "pino": "^10.1.0",
280
275
  "short-uuid": "^6.0.3",
281
276
  "uuid": "^13.0.0",
282
277
  "zod": "^4.1.12"
283
278
  },
279
+ "optionalDependencies": {
280
+ "@inquirer/prompts": "^8.5.0",
281
+ "chalk": "^5.6.2",
282
+ "chalk-animation": "^2.0.3",
283
+ "commander": "^14.0.1",
284
+ "figlet": "^1.9.3",
285
+ "gradient-string": "^3.0.0"
286
+ },
284
287
  "config": {
285
288
  "commitizen": {
286
289
  "path": "cz-conventional-changelog"
@@ -1 +0,0 @@
1
- import"../chunks/chunk-ANN5UYCF.js";function l(){return"Hello, World!"}export{l as helloWorld};
@@ -1 +0,0 @@
1
- import"../chunks/chunk-ANN5UYCF.js";var t=(...o)=>{let n=new Date().toISOString();console.log(`[${n}]`,...o)},e=(...o)=>{console.warn("\x1B[33m%s\x1B[0m",...o)},s=(...o)=>{console.error("\x1B[31m%s\x1B[0m",...o)},r=(...o)=>{console.info("\x1B[34m%s\x1B[0m",...o)};export{s as error,r as info,t as logWithTimestamp,e as warn};