rsformat 0.1.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 +133 -0
- package/lib/format.d.ts +7 -0
- package/lib/format.js +187 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +10 -0
- package/lib/print.d.ts +35 -0
- package/lib/print.js +49 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# RSFormat
|
|
2
|
+
|
|
3
|
+
RSFormat is a string formatting/printing library for JavaScript. It offers an alternative to the string formatting and printing provided by `console.log`.
|
|
4
|
+
|
|
5
|
+
## Motivation
|
|
6
|
+
|
|
7
|
+
`console.log` is an odd method: its output can be affected by functions called before/after it (such as `console.group`), or their order affected by what parameters there are. For example, when calling `console.log(string, number)`, number can come either after or inside `string` depending on the value of `string`.
|
|
8
|
+
|
|
9
|
+
RSFormat provides alternative functions with standardised behaviour: its `format`, `println` and all other functions will always output in the same manner, and have a standardised syntax which will only print the initial string, formatted with the parameters provided afterwards.
|
|
10
|
+
|
|
11
|
+
Rust formatting also includes a lot of convenient operators for formatting text, such as padding/alignment, printing numbers in a given base, specifying decimal precision, etc.. This makes it a more ergonomic and convenient approach to printing things to the console.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
you can install rsformat using [npm](https://www.npmjs.com/package/rsformat):
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
npm install rsformat
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Basic formatting and printing to console
|
|
22
|
+
|
|
23
|
+
RSFormat functions are called using a format string, and any number of format arguments following it.
|
|
24
|
+
|
|
25
|
+
Any instance of `{}` in the format strings will get replaced with a value.
|
|
26
|
+
|
|
27
|
+
You can specify what value you want in the parameters by using a number inside the insertion point.
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
import { format, println } from 'rsformat'; // ESM
|
|
31
|
+
const { format, println } = require('rsformat'); // CommonJS
|
|
32
|
+
|
|
33
|
+
let name = 'everyone';
|
|
34
|
+
|
|
35
|
+
let greeting = format('Hello {}!', name); // Evaluates to the string 'Hello, everyone!'
|
|
36
|
+
|
|
37
|
+
println('I have {1} apples and {0} oranges', 13, 14); // Will print 'I have 14 apples and 13 oranges' to the console
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Format Specifiers
|
|
41
|
+
|
|
42
|
+
Format specifiers can be used by adding `:` inside the insertion point (after the optional argument number), and will format the value differently inside the string. See the [rust format docs](https://doc.rust-lang.org/std/fmt/#syntax) for more detailed information on format specifiers.
|
|
43
|
+
|
|
44
|
+
This implementation differs from the rust one in a few ways:
|
|
45
|
+
|
|
46
|
+
- Named arguments before or in format specifiers or in values aren't allowed, only numbers can be used.
|
|
47
|
+
- The `-` sign (unused in rust) is unsupported.
|
|
48
|
+
- Pointer format type `p` is unsupported.
|
|
49
|
+
- Hexadecimal debug types `x?` and `X?` are unsupported.
|
|
50
|
+
- Specifying precision with `*` is unsupported.
|
|
51
|
+
|
|
52
|
+
#### Different formatting types
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
// Debug format specifier: ?, uses util.inspect rather than toString
|
|
56
|
+
|
|
57
|
+
println('{}', { a: 1 }); //prints '[object Object]'
|
|
58
|
+
println('{:?}', { a: 1 }); //prints "{ a:1 }"
|
|
59
|
+
|
|
60
|
+
// Number base specifiers: x, X, b, o - for lower/uppercase hexadecimal, binary, octal
|
|
61
|
+
|
|
62
|
+
format('{} is {0:x} in hex, {0:b} in binary and {0:o} in octal', 15); // '15 is f in hex, 1111 in binary and 17 in octal'
|
|
63
|
+
|
|
64
|
+
// Scientific notation specifiers: e, E - for lower/uppercase scientific notation
|
|
65
|
+
|
|
66
|
+
let hugeNumber = 1000n;
|
|
67
|
+
format('{:E}', hugeNumber); // '1E3';
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### Padding, Alignment
|
|
71
|
+
|
|
72
|
+
Values can be aligned using any fill character (will default to a space ` `), and either left, center or right aligned with `<`, `^` or `>` respectively (will default to right alignment `>`). You will also have to specify a width with an integer after the alignment:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
/*
|
|
76
|
+
Will print a pyramid of 'a's:
|
|
77
|
+
' a '
|
|
78
|
+
' aaa '
|
|
79
|
+
'aaaaa'
|
|
80
|
+
*/
|
|
81
|
+
let pyramidLevels = ['a', 'aaa', 'aaaaa'];
|
|
82
|
+
for(let value of pyramidLevels) {
|
|
83
|
+
println('{:^5}', value);
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
format('{:.>7}', [1,2]); // '....1,2'
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
#### Pretty Printing
|
|
92
|
+
|
|
93
|
+
In some instances (namely debug and hexadecimal formatting), adding a `#` before the format specifier will use an alternative 'pretty' printing style. This amounts to using non-compact `util.inspect` for debug printing (spanning multiple lines), and adding 0x to hexadecimal numbers.
|
|
94
|
+
|
|
95
|
+
```js
|
|
96
|
+
format('{:#X}', 255); // '0xFF'
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### Specific Number Formatting
|
|
100
|
+
|
|
101
|
+
Specifically for `number` and `bigint` values, a 0 can be placed before the width to pad the number with 0s instead. This will account for signs and possible formatting differences.
|
|
102
|
+
|
|
103
|
+
```js
|
|
104
|
+
format('{:#07x}', 15) // '0x0000F'
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Decimal precision can be specified for numbers by adding a . and specifying an integer for precision.
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
format('{:.3}', 1.23456789); // '1.234'
|
|
111
|
+
format('{:.3}', -1); // '-1.000'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Adding a + to the formatting specifier will print the sign regardless of whether the number is negative.
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
format('{:+}', 1); // '+1'
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Custom output
|
|
121
|
+
|
|
122
|
+
If you want to use the print function to output to anything other than `process.stdout` and `process.stderr`, you can import the `Printer` function to create your own print functions, using any output and error streams that are instances of node's `Writable`.
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
// Custom output example (ts)
|
|
126
|
+
import { Printer } from 'rsformat-local/print';
|
|
127
|
+
import { Writable } from 'stream';
|
|
128
|
+
|
|
129
|
+
let someOutputStream: Writable = /* ... */;
|
|
130
|
+
let someErrorStream: Writable = /* ... */;
|
|
131
|
+
|
|
132
|
+
let { print, println, eprint, eprintln } = Printer(someOutputStream, someErrorStream);
|
|
133
|
+
```
|
package/lib/format.d.ts
ADDED
package/lib/format.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.format = void 0;
|
|
4
|
+
const util_1 = require("util");
|
|
5
|
+
/**
|
|
6
|
+
* Regex to match for possible formatting insertion points.
|
|
7
|
+
* Similar to the way formatting is parsed in rust,
|
|
8
|
+
* but with a few key differences:
|
|
9
|
+
* - Named arguments before format specifiers aren't allowed, only numbers can be used.
|
|
10
|
+
* - The - sign (unused in rust) is unsupported.
|
|
11
|
+
* - Pointer format type 'p' is unsupported.
|
|
12
|
+
* - Hexadecimal debug types 'x?' and 'X?' are unsupported.
|
|
13
|
+
* - Specifying precision with * is unsupported.
|
|
14
|
+
*
|
|
15
|
+
* The formatter currently matches with a regex
|
|
16
|
+
* instead of a full-blown parser for simplicity
|
|
17
|
+
* and performance, as built-in regex matching is
|
|
18
|
+
* likely to be faster than a js-implemented parser.
|
|
19
|
+
* However, this will not match incorrectly formatted
|
|
20
|
+
* insertion points.
|
|
21
|
+
*/
|
|
22
|
+
const FORMAT_REGEX = (/\{{2}|\}{2}|\{(\d*?)(?::(?:(.?)(\^|>|<))?(\+)?(#)?(0)?(\d*)?(\.\d*)?(\?|o|x|X|b|e|E)?)?\}/g);
|
|
23
|
+
/**
|
|
24
|
+
* Format a string similarly to rust's format! macro.
|
|
25
|
+
*
|
|
26
|
+
* @param str String used for formatting
|
|
27
|
+
* @param params Parameters to be inserted into the format string
|
|
28
|
+
*/
|
|
29
|
+
function format(str, ...params) {
|
|
30
|
+
// Counter used for insertion of unnumbered values
|
|
31
|
+
let param_counter = 0;
|
|
32
|
+
str = str.replace(FORMAT_REGEX, ($, $param_number, $fill_character, $align_direction, $sign, $pretty, $pad_zeroes, $width, $precision, $type) => {
|
|
33
|
+
// Return a bracket if the regex matched an escaped bracket
|
|
34
|
+
if ($ === '{{') {
|
|
35
|
+
return '{';
|
|
36
|
+
}
|
|
37
|
+
if ($ === '}}') {
|
|
38
|
+
return '}';
|
|
39
|
+
}
|
|
40
|
+
// Process parameter number; increment param_counter if not included
|
|
41
|
+
let param = $param_number === undefined
|
|
42
|
+
? params[param_counter++]
|
|
43
|
+
: params[+$param_number];
|
|
44
|
+
if (param === undefined) {
|
|
45
|
+
throw new Error(`parameter ${$param_number || param_counter - 1} either NaN or not provided`);
|
|
46
|
+
}
|
|
47
|
+
let param_type = typeof param;
|
|
48
|
+
// Process parameter type
|
|
49
|
+
switch ($type) {
|
|
50
|
+
case "o":
|
|
51
|
+
param = param.toString(8);
|
|
52
|
+
break;
|
|
53
|
+
case "x":
|
|
54
|
+
param = param.toString(16);
|
|
55
|
+
break;
|
|
56
|
+
case "X":
|
|
57
|
+
param = param.toString(16).toUpperCase();
|
|
58
|
+
break;
|
|
59
|
+
case "b":
|
|
60
|
+
param = param.toString(2);
|
|
61
|
+
break;
|
|
62
|
+
case "e":
|
|
63
|
+
switch (param_type) {
|
|
64
|
+
case 'number':
|
|
65
|
+
param = param.toExponential();
|
|
66
|
+
break;
|
|
67
|
+
case 'bigint':
|
|
68
|
+
param = param.toLocaleString('en-US', {
|
|
69
|
+
notation: 'scientific',
|
|
70
|
+
maximumFractionDigits: 20,
|
|
71
|
+
}).toLowerCase();
|
|
72
|
+
break;
|
|
73
|
+
default:
|
|
74
|
+
param = param.toString();
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
case "E":
|
|
79
|
+
switch (param_type) {
|
|
80
|
+
case 'number':
|
|
81
|
+
param = param.toExponential().toUpperCase();
|
|
82
|
+
break;
|
|
83
|
+
case 'bigint':
|
|
84
|
+
param = param.toLocaleString('en-US', {
|
|
85
|
+
notation: 'scientific',
|
|
86
|
+
maximumFractionDigits: 20
|
|
87
|
+
});
|
|
88
|
+
break;
|
|
89
|
+
default:
|
|
90
|
+
param = param.toString();
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
case "?":
|
|
95
|
+
param = (0, util_1.inspect)(param, {
|
|
96
|
+
depth: Infinity,
|
|
97
|
+
colors: true,
|
|
98
|
+
compact: $pretty !== '#'
|
|
99
|
+
});
|
|
100
|
+
break;
|
|
101
|
+
default:
|
|
102
|
+
param = param.toString();
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
;
|
|
106
|
+
// Compute radix-point precision on numbers
|
|
107
|
+
if (param_type == 'number' && $precision) {
|
|
108
|
+
let [pre, post] = param.split(".");
|
|
109
|
+
if (post === undefined) {
|
|
110
|
+
post = "";
|
|
111
|
+
}
|
|
112
|
+
let precision = +$precision.substring(1, $precision.length);
|
|
113
|
+
if (post.length > precision) {
|
|
114
|
+
post = post.substring(0, precision);
|
|
115
|
+
}
|
|
116
|
+
else
|
|
117
|
+
while (post.length < precision) {
|
|
118
|
+
post = post + '0';
|
|
119
|
+
}
|
|
120
|
+
param = pre + "." + post;
|
|
121
|
+
}
|
|
122
|
+
let width;
|
|
123
|
+
if ($width === undefined) {
|
|
124
|
+
width = 0;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
width = +$width;
|
|
128
|
+
if (Number.isNaN(width))
|
|
129
|
+
throw new Error(`invalid width specifier '${$width}' (must be an integer)`);
|
|
130
|
+
}
|
|
131
|
+
let filled = false;
|
|
132
|
+
if ((param_type == 'number') || (param_type == 'bigint')) {
|
|
133
|
+
// Compute parameter sign
|
|
134
|
+
let maybe_sign = param.substring(0, 1);
|
|
135
|
+
if (maybe_sign === '-') {
|
|
136
|
+
param = param.substring(1, param.length);
|
|
137
|
+
}
|
|
138
|
+
else if ($sign === '+') {
|
|
139
|
+
maybe_sign = '+';
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
maybe_sign = '';
|
|
143
|
+
}
|
|
144
|
+
//If the type is x or X and pretty printing enabled, add 0x
|
|
145
|
+
if ((($type === 'x') || ($type === 'X')) && ($pretty === '#')) {
|
|
146
|
+
maybe_sign += '0x';
|
|
147
|
+
}
|
|
148
|
+
//pad with zeroes if specified
|
|
149
|
+
if ($pad_zeroes === '0') {
|
|
150
|
+
filled = true;
|
|
151
|
+
while (param.length < width - maybe_sign.length) {
|
|
152
|
+
param = '0' + param;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
param = maybe_sign + param;
|
|
156
|
+
}
|
|
157
|
+
if (!filled && width) {
|
|
158
|
+
// Compute fill/align
|
|
159
|
+
$align_direction ||= '>';
|
|
160
|
+
$fill_character ||= ' ';
|
|
161
|
+
switch ($align_direction) {
|
|
162
|
+
case '>':
|
|
163
|
+
while (width - param.length > 0) {
|
|
164
|
+
param = $fill_character + param;
|
|
165
|
+
}
|
|
166
|
+
break;
|
|
167
|
+
case '<':
|
|
168
|
+
while (width - param.length > 0) {
|
|
169
|
+
param = param + $fill_character;
|
|
170
|
+
}
|
|
171
|
+
break;
|
|
172
|
+
case '^':
|
|
173
|
+
while (width - param.length > 1) {
|
|
174
|
+
param = $fill_character + param + $fill_character;
|
|
175
|
+
}
|
|
176
|
+
// Prioritise right-aligment on uneven alignment
|
|
177
|
+
if (width - param.length == 1) {
|
|
178
|
+
param = $fill_character + param;
|
|
179
|
+
}
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return param;
|
|
184
|
+
});
|
|
185
|
+
return str;
|
|
186
|
+
}
|
|
187
|
+
exports.format = format;
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.eprintln = exports.eprint = exports.println = exports.print = exports.format = void 0;
|
|
4
|
+
var format_1 = require("./format");
|
|
5
|
+
Object.defineProperty(exports, "format", { enumerable: true, get: function () { return format_1.format; } });
|
|
6
|
+
var print_1 = require("./print");
|
|
7
|
+
Object.defineProperty(exports, "print", { enumerable: true, get: function () { return print_1.print; } });
|
|
8
|
+
Object.defineProperty(exports, "println", { enumerable: true, get: function () { return print_1.println; } });
|
|
9
|
+
Object.defineProperty(exports, "eprint", { enumerable: true, get: function () { return print_1.eprint; } });
|
|
10
|
+
Object.defineProperty(exports, "eprintln", { enumerable: true, get: function () { return print_1.eprintln; } });
|
package/lib/print.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Writable } from 'stream';
|
|
3
|
+
export declare function Printer(outStream?: Writable, errStream?: Writable): {
|
|
4
|
+
/**
|
|
5
|
+
* Print a format string to an output stream (usually process.stdout).
|
|
6
|
+
*
|
|
7
|
+
* @param format_string String used for formatting
|
|
8
|
+
* @param params Parameters to be inserted into the format string
|
|
9
|
+
*/
|
|
10
|
+
print: (format_string: string, ...params: any[]) => void;
|
|
11
|
+
/**
|
|
12
|
+
* Print a format string to an output stream (usually process.stdout)
|
|
13
|
+
* and append a newline.
|
|
14
|
+
*
|
|
15
|
+
* @param format_string String used for formatting
|
|
16
|
+
* @param params Parameters to be inserted into the format string
|
|
17
|
+
*/
|
|
18
|
+
println: (format_string: string, ...params: any[]) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Print a format string to an error stream (usually process.stderr).
|
|
21
|
+
*
|
|
22
|
+
* @param format_string String used for formatting
|
|
23
|
+
* @param params Parameters to be inserted into the format string
|
|
24
|
+
*/
|
|
25
|
+
eprint: (format_string: string, ...params: any[]) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Print a format string to an error stream (usually process.stderr)
|
|
28
|
+
* and append a newline.
|
|
29
|
+
*
|
|
30
|
+
* @param format_string String used for formatting
|
|
31
|
+
* @param params Parameters to be inserted into the format string
|
|
32
|
+
*/
|
|
33
|
+
eprintln: (format_string: string, ...params: any[]) => void;
|
|
34
|
+
};
|
|
35
|
+
export declare const print: (format_string: string, ...params: any[]) => void, println: (format_string: string, ...params: any[]) => void, eprint: (format_string: string, ...params: any[]) => void, eprintln: (format_string: string, ...params: any[]) => void;
|
package/lib/print.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.eprintln = exports.eprint = exports.println = exports.print = exports.Printer = void 0;
|
|
5
|
+
const format_1 = require("./format");
|
|
6
|
+
function Printer(outStream = process.stdout, errStream = process.stderr) {
|
|
7
|
+
return {
|
|
8
|
+
/**
|
|
9
|
+
* Print a format string to an output stream (usually process.stdout).
|
|
10
|
+
*
|
|
11
|
+
* @param format_string String used for formatting
|
|
12
|
+
* @param params Parameters to be inserted into the format string
|
|
13
|
+
*/
|
|
14
|
+
print: function print(format_string, ...params) {
|
|
15
|
+
outStream.write((0, format_1.format)(format_string, ...params));
|
|
16
|
+
},
|
|
17
|
+
/**
|
|
18
|
+
* Print a format string to an output stream (usually process.stdout)
|
|
19
|
+
* and append a newline.
|
|
20
|
+
*
|
|
21
|
+
* @param format_string String used for formatting
|
|
22
|
+
* @param params Parameters to be inserted into the format string
|
|
23
|
+
*/
|
|
24
|
+
println: function println(format_string, ...params) {
|
|
25
|
+
outStream.write((0, format_1.format)(format_string, ...params) + "\n");
|
|
26
|
+
},
|
|
27
|
+
/**
|
|
28
|
+
* Print a format string to an error stream (usually process.stderr).
|
|
29
|
+
*
|
|
30
|
+
* @param format_string String used for formatting
|
|
31
|
+
* @param params Parameters to be inserted into the format string
|
|
32
|
+
*/
|
|
33
|
+
eprint: function eprint(format_string, ...params) {
|
|
34
|
+
errStream.write((0, format_1.format)(format_string, ...params));
|
|
35
|
+
},
|
|
36
|
+
/**
|
|
37
|
+
* Print a format string to an error stream (usually process.stderr)
|
|
38
|
+
* and append a newline.
|
|
39
|
+
*
|
|
40
|
+
* @param format_string String used for formatting
|
|
41
|
+
* @param params Parameters to be inserted into the format string
|
|
42
|
+
*/
|
|
43
|
+
eprintln: function eprintln(format_string, ...params) {
|
|
44
|
+
errStream.write((0, format_1.format)(format_string, ...params) + "\n");
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
exports.Printer = Printer;
|
|
49
|
+
_a = Printer(), exports.print = _a.print, exports.println = _a.println, exports.eprint = _a.eprint, exports.eprintln = _a.eprintln;
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rsformat",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Formatting/printing library for JavaScript that takes after rust's string formatting ",
|
|
5
|
+
"files": [
|
|
6
|
+
"lib",
|
|
7
|
+
"README.MD"
|
|
8
|
+
],
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./lib/index.d.ts",
|
|
12
|
+
"default": "./lib/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./*": {
|
|
15
|
+
"types": "./lib/*.d.ts",
|
|
16
|
+
"default": "./lib/*.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"fmt",
|
|
25
|
+
"format",
|
|
26
|
+
"strings",
|
|
27
|
+
"print",
|
|
28
|
+
"println",
|
|
29
|
+
"printf",
|
|
30
|
+
"console",
|
|
31
|
+
"log"
|
|
32
|
+
],
|
|
33
|
+
"author": "Alfio (https://github.com/p2js)",
|
|
34
|
+
"license": "ISC",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^22.8.6"
|
|
37
|
+
}
|
|
38
|
+
}
|