@shba007/unascii 0.3.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/LICENSE +21 -0
- package/README.md +122 -0
- package/bin/unascii.mjs +5 -0
- package/dist/cli.cjs +95 -0
- package/dist/cli.d.cts +44 -0
- package/dist/cli.d.mts +44 -0
- package/dist/cli.d.ts +44 -0
- package/dist/cli.mjs +86 -0
- package/dist/index.cjs +7 -0
- package/dist/index.d.cts +33 -0
- package/dist/index.d.mts +33 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.mjs +1 -0
- package/dist/shared/unascii.BVDz6TJY.cjs +126 -0
- package/dist/shared/unascii.C-iPcHtB.mjs +123 -0
- package/package.json +76 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c)
|
|
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,122 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./public/logo.png" lt="Logo" width="128" />
|
|
3
|
+
<p>
|
|
4
|
+
|
|
5
|
+
# unascii
|
|
6
|
+
|
|
7
|
+
<!-- automd:badges color=blue -->
|
|
8
|
+
|
|
9
|
+
[](https://npmjs.com/package/unascii)
|
|
10
|
+
[](https://npmjs.com/package/unascii)
|
|
11
|
+
[](https://github.com/shba007/unascii?tab=MIT-1-ov-file)
|
|
12
|
+
|
|
13
|
+
<!-- /automd -->
|
|
14
|
+
|
|
15
|
+
> Print any image in ascii anywhere (browser/cli)
|
|
16
|
+
|
|
17
|
+
## Usage (CLI)
|
|
18
|
+
|
|
19
|
+
Globally run unascii with `npx`:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
npx unascii@latest ./file/path.jpg
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
or
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
npx unascii@latest ./file/path.jpg --width=50
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Options:
|
|
32
|
+
--width Width of the image
|
|
33
|
+
--widthSkew Width Skew of the image
|
|
34
|
+
--output <console|file> Output as file or console
|
|
35
|
+
--characters <minimalist|normal|normal2|alphabetic|alphanumeric|numerical|extended|math|arrow|grayscale|max|codepage437|blockelement> Output Character Set
|
|
36
|
+
--grayscale <true|false> Output as grayscale or color only works with console
|
|
37
|
+
|
|
38
|
+
Use `npx unascii --help` for more usage info.
|
|
39
|
+
|
|
40
|
+
## Usage (API)
|
|
41
|
+
|
|
42
|
+
Install package:
|
|
43
|
+
|
|
44
|
+
<!-- automd:pm-install -->
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
# ✨ Auto-detect
|
|
48
|
+
npx nypm install unascii
|
|
49
|
+
|
|
50
|
+
# npm
|
|
51
|
+
npm install unascii
|
|
52
|
+
|
|
53
|
+
# yarn
|
|
54
|
+
yarn add unascii
|
|
55
|
+
|
|
56
|
+
# pnpm
|
|
57
|
+
pnpm install unascii
|
|
58
|
+
|
|
59
|
+
# bun
|
|
60
|
+
bun install unascii
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
<!-- /automd -->
|
|
64
|
+
|
|
65
|
+
Import:
|
|
66
|
+
|
|
67
|
+
<!-- automd:jsimport cjs cdn name="pkg" -->
|
|
68
|
+
|
|
69
|
+
**ESM** (Node.js, Bun)
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
import {} from 'unascii'
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**CommonJS** (Legacy Node.js)
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
const {} = require('unascii')
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**CDN** (Deno, Bun and Browsers)
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
import {} from 'https://esm.sh/unascii'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
<!-- /automd -->
|
|
88
|
+
|
|
89
|
+
## Development
|
|
90
|
+
|
|
91
|
+
<details>
|
|
92
|
+
|
|
93
|
+
<summary>local development</summary>
|
|
94
|
+
|
|
95
|
+
- Clone this repository
|
|
96
|
+
- Install latest LTS version of [Node.js](https://nodejs.org/en/)
|
|
97
|
+
- Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable`
|
|
98
|
+
- Install dependencies using `pnpm install`
|
|
99
|
+
- Run interactive tests using `pnpm dev`
|
|
100
|
+
|
|
101
|
+
</details>
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
<!-- automd:contributors license=MIT -->
|
|
106
|
+
|
|
107
|
+
Published under the [MIT](https://github.com/shba007/unascii/blob/main/LICENSE) license.
|
|
108
|
+
Made by [community](https://github.com/shba007/unascii/graphs/contributors) 💛
|
|
109
|
+
<br><br>
|
|
110
|
+
<a href="https://github.com/shba007/unascii/graphs/contributors">
|
|
111
|
+
<img src="https://contrib.rocks/image?repo=shba007/unascii" />
|
|
112
|
+
</a>
|
|
113
|
+
|
|
114
|
+
<!-- /automd -->
|
|
115
|
+
|
|
116
|
+
<!-- automd:with-automd -->
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
_🤖 auto updated with [automd](https://automd.unjs.io)_
|
|
121
|
+
|
|
122
|
+
<!-- /automd -->
|
package/bin/unascii.mjs
ADDED
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const citty = require('citty');
|
|
4
|
+
const consola = require('consola');
|
|
5
|
+
const pathe = require('pathe');
|
|
6
|
+
const unstorage = require('unstorage');
|
|
7
|
+
const fsDriver = require('unstorage/drivers/fs');
|
|
8
|
+
const index = require('./shared/unascii.BVDz6TJY.cjs');
|
|
9
|
+
|
|
10
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
11
|
+
|
|
12
|
+
const consola__default = /*#__PURE__*/_interopDefaultCompat(consola);
|
|
13
|
+
const pathe__default = /*#__PURE__*/_interopDefaultCompat(pathe);
|
|
14
|
+
const fsDriver__default = /*#__PURE__*/_interopDefaultCompat(fsDriver);
|
|
15
|
+
|
|
16
|
+
const name = "@shba007/unascii";
|
|
17
|
+
const version = "0.3.1";
|
|
18
|
+
const description = "Print any image in ascii anywhere (browser/cli)";
|
|
19
|
+
|
|
20
|
+
const storage = unstorage.createStorage({
|
|
21
|
+
driver: fsDriver__default({ base: "." })
|
|
22
|
+
});
|
|
23
|
+
const main = citty.defineCommand({
|
|
24
|
+
meta: {
|
|
25
|
+
name,
|
|
26
|
+
description,
|
|
27
|
+
version
|
|
28
|
+
},
|
|
29
|
+
args: {
|
|
30
|
+
path: {
|
|
31
|
+
type: "positional",
|
|
32
|
+
description: "Path of the image",
|
|
33
|
+
required: true
|
|
34
|
+
},
|
|
35
|
+
width: {
|
|
36
|
+
type: "string",
|
|
37
|
+
description: "Width of the image",
|
|
38
|
+
default: "32"
|
|
39
|
+
},
|
|
40
|
+
widthSkew: {
|
|
41
|
+
type: "string",
|
|
42
|
+
description: "Width Skew of the image",
|
|
43
|
+
default: "1.75"
|
|
44
|
+
},
|
|
45
|
+
output: {
|
|
46
|
+
type: "string",
|
|
47
|
+
description: "Output as file or console",
|
|
48
|
+
valueHint: "console|file",
|
|
49
|
+
default: "console"
|
|
50
|
+
},
|
|
51
|
+
characters: {
|
|
52
|
+
type: "string",
|
|
53
|
+
description: "Output Character Set",
|
|
54
|
+
valueHint: `minimalist|normal|normal2|alphabetic|alphanumeric|numerical|extended|math|arrow|grayscale|max|codepage437|blockelement`
|
|
55
|
+
},
|
|
56
|
+
grayscale: {
|
|
57
|
+
type: "boolean",
|
|
58
|
+
description: "Output as grayscale or color only works with console",
|
|
59
|
+
valueHint: "true|false"
|
|
60
|
+
},
|
|
61
|
+
verbose: {
|
|
62
|
+
type: "boolean",
|
|
63
|
+
description: "Verbose Output",
|
|
64
|
+
valueHint: "true|false",
|
|
65
|
+
default: false
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
async run({ args }) {
|
|
69
|
+
if (args.verbose) {
|
|
70
|
+
process.env.DEBUG = process.env.DEBUG || "true";
|
|
71
|
+
}
|
|
72
|
+
const print = await index.asciiPrint(args.path, {
|
|
73
|
+
width: args.width ? Number.parseInt(args.width) ?? void 0 : void 0,
|
|
74
|
+
widthSkew: args.widthSkew ? Number.parseFloat(args.widthSkew) ?? void 0 : void 0,
|
|
75
|
+
output: args.output,
|
|
76
|
+
characters: args.characters,
|
|
77
|
+
grayscale: args.grayscale
|
|
78
|
+
});
|
|
79
|
+
const image = await print.getImage();
|
|
80
|
+
if (args.output === "console") {
|
|
81
|
+
consola__default.info("\n" + image);
|
|
82
|
+
} else if (args.output === "file") {
|
|
83
|
+
const outputPath = pathe__default.format({ name: index.isURL(args.path) ? args.path.split("/").at(-1)?.split(".")[0] : pathe__default.parse(args.path).name, root: "/", ext: ".txt" });
|
|
84
|
+
await storage.setItem(outputPath, image);
|
|
85
|
+
}
|
|
86
|
+
if (!print) {
|
|
87
|
+
consola__default.error("Print not started.");
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
const runMain = () => citty.runMain(main);
|
|
93
|
+
|
|
94
|
+
exports.main = main;
|
|
95
|
+
exports.runMain = runMain;
|
package/dist/cli.d.cts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as citty from 'citty';
|
|
2
|
+
|
|
3
|
+
declare const main: citty.CommandDef<{
|
|
4
|
+
path: {
|
|
5
|
+
type: "positional";
|
|
6
|
+
description: string;
|
|
7
|
+
required: true;
|
|
8
|
+
};
|
|
9
|
+
width: {
|
|
10
|
+
type: "string";
|
|
11
|
+
description: string;
|
|
12
|
+
default: string;
|
|
13
|
+
};
|
|
14
|
+
widthSkew: {
|
|
15
|
+
type: "string";
|
|
16
|
+
description: string;
|
|
17
|
+
default: string;
|
|
18
|
+
};
|
|
19
|
+
output: {
|
|
20
|
+
type: "string";
|
|
21
|
+
description: string;
|
|
22
|
+
valueHint: string;
|
|
23
|
+
default: string;
|
|
24
|
+
};
|
|
25
|
+
characters: {
|
|
26
|
+
type: "string";
|
|
27
|
+
description: string;
|
|
28
|
+
valueHint: string;
|
|
29
|
+
};
|
|
30
|
+
grayscale: {
|
|
31
|
+
type: "boolean";
|
|
32
|
+
description: string;
|
|
33
|
+
valueHint: string;
|
|
34
|
+
};
|
|
35
|
+
verbose: {
|
|
36
|
+
type: "boolean";
|
|
37
|
+
description: string;
|
|
38
|
+
valueHint: string;
|
|
39
|
+
default: false;
|
|
40
|
+
};
|
|
41
|
+
}>;
|
|
42
|
+
declare const runMain: () => Promise<void>;
|
|
43
|
+
|
|
44
|
+
export { main, runMain };
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as citty from 'citty';
|
|
2
|
+
|
|
3
|
+
declare const main: citty.CommandDef<{
|
|
4
|
+
path: {
|
|
5
|
+
type: "positional";
|
|
6
|
+
description: string;
|
|
7
|
+
required: true;
|
|
8
|
+
};
|
|
9
|
+
width: {
|
|
10
|
+
type: "string";
|
|
11
|
+
description: string;
|
|
12
|
+
default: string;
|
|
13
|
+
};
|
|
14
|
+
widthSkew: {
|
|
15
|
+
type: "string";
|
|
16
|
+
description: string;
|
|
17
|
+
default: string;
|
|
18
|
+
};
|
|
19
|
+
output: {
|
|
20
|
+
type: "string";
|
|
21
|
+
description: string;
|
|
22
|
+
valueHint: string;
|
|
23
|
+
default: string;
|
|
24
|
+
};
|
|
25
|
+
characters: {
|
|
26
|
+
type: "string";
|
|
27
|
+
description: string;
|
|
28
|
+
valueHint: string;
|
|
29
|
+
};
|
|
30
|
+
grayscale: {
|
|
31
|
+
type: "boolean";
|
|
32
|
+
description: string;
|
|
33
|
+
valueHint: string;
|
|
34
|
+
};
|
|
35
|
+
verbose: {
|
|
36
|
+
type: "boolean";
|
|
37
|
+
description: string;
|
|
38
|
+
valueHint: string;
|
|
39
|
+
default: false;
|
|
40
|
+
};
|
|
41
|
+
}>;
|
|
42
|
+
declare const runMain: () => Promise<void>;
|
|
43
|
+
|
|
44
|
+
export { main, runMain };
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as citty from 'citty';
|
|
2
|
+
|
|
3
|
+
declare const main: citty.CommandDef<{
|
|
4
|
+
path: {
|
|
5
|
+
type: "positional";
|
|
6
|
+
description: string;
|
|
7
|
+
required: true;
|
|
8
|
+
};
|
|
9
|
+
width: {
|
|
10
|
+
type: "string";
|
|
11
|
+
description: string;
|
|
12
|
+
default: string;
|
|
13
|
+
};
|
|
14
|
+
widthSkew: {
|
|
15
|
+
type: "string";
|
|
16
|
+
description: string;
|
|
17
|
+
default: string;
|
|
18
|
+
};
|
|
19
|
+
output: {
|
|
20
|
+
type: "string";
|
|
21
|
+
description: string;
|
|
22
|
+
valueHint: string;
|
|
23
|
+
default: string;
|
|
24
|
+
};
|
|
25
|
+
characters: {
|
|
26
|
+
type: "string";
|
|
27
|
+
description: string;
|
|
28
|
+
valueHint: string;
|
|
29
|
+
};
|
|
30
|
+
grayscale: {
|
|
31
|
+
type: "boolean";
|
|
32
|
+
description: string;
|
|
33
|
+
valueHint: string;
|
|
34
|
+
};
|
|
35
|
+
verbose: {
|
|
36
|
+
type: "boolean";
|
|
37
|
+
description: string;
|
|
38
|
+
valueHint: string;
|
|
39
|
+
default: false;
|
|
40
|
+
};
|
|
41
|
+
}>;
|
|
42
|
+
declare const runMain: () => Promise<void>;
|
|
43
|
+
|
|
44
|
+
export { main, runMain };
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { defineCommand, runMain as runMain$1 } from 'citty';
|
|
2
|
+
import consola from 'consola';
|
|
3
|
+
import pathe from 'pathe';
|
|
4
|
+
import { createStorage } from 'unstorage';
|
|
5
|
+
import fsDriver from 'unstorage/drivers/fs';
|
|
6
|
+
import { a as asciiPrint, i as isURL } from './shared/unascii.C-iPcHtB.mjs';
|
|
7
|
+
|
|
8
|
+
const name = "@shba007/unascii";
|
|
9
|
+
const version = "0.3.1";
|
|
10
|
+
const description = "Print any image in ascii anywhere (browser/cli)";
|
|
11
|
+
|
|
12
|
+
const storage = createStorage({
|
|
13
|
+
driver: fsDriver({ base: "." })
|
|
14
|
+
});
|
|
15
|
+
const main = defineCommand({
|
|
16
|
+
meta: {
|
|
17
|
+
name,
|
|
18
|
+
description,
|
|
19
|
+
version
|
|
20
|
+
},
|
|
21
|
+
args: {
|
|
22
|
+
path: {
|
|
23
|
+
type: "positional",
|
|
24
|
+
description: "Path of the image",
|
|
25
|
+
required: true
|
|
26
|
+
},
|
|
27
|
+
width: {
|
|
28
|
+
type: "string",
|
|
29
|
+
description: "Width of the image",
|
|
30
|
+
default: "32"
|
|
31
|
+
},
|
|
32
|
+
widthSkew: {
|
|
33
|
+
type: "string",
|
|
34
|
+
description: "Width Skew of the image",
|
|
35
|
+
default: "1.75"
|
|
36
|
+
},
|
|
37
|
+
output: {
|
|
38
|
+
type: "string",
|
|
39
|
+
description: "Output as file or console",
|
|
40
|
+
valueHint: "console|file",
|
|
41
|
+
default: "console"
|
|
42
|
+
},
|
|
43
|
+
characters: {
|
|
44
|
+
type: "string",
|
|
45
|
+
description: "Output Character Set",
|
|
46
|
+
valueHint: `minimalist|normal|normal2|alphabetic|alphanumeric|numerical|extended|math|arrow|grayscale|max|codepage437|blockelement`
|
|
47
|
+
},
|
|
48
|
+
grayscale: {
|
|
49
|
+
type: "boolean",
|
|
50
|
+
description: "Output as grayscale or color only works with console",
|
|
51
|
+
valueHint: "true|false"
|
|
52
|
+
},
|
|
53
|
+
verbose: {
|
|
54
|
+
type: "boolean",
|
|
55
|
+
description: "Verbose Output",
|
|
56
|
+
valueHint: "true|false",
|
|
57
|
+
default: false
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
async run({ args }) {
|
|
61
|
+
if (args.verbose) {
|
|
62
|
+
process.env.DEBUG = process.env.DEBUG || "true";
|
|
63
|
+
}
|
|
64
|
+
const print = await asciiPrint(args.path, {
|
|
65
|
+
width: args.width ? Number.parseInt(args.width) ?? void 0 : void 0,
|
|
66
|
+
widthSkew: args.widthSkew ? Number.parseFloat(args.widthSkew) ?? void 0 : void 0,
|
|
67
|
+
output: args.output,
|
|
68
|
+
characters: args.characters,
|
|
69
|
+
grayscale: args.grayscale
|
|
70
|
+
});
|
|
71
|
+
const image = await print.getImage();
|
|
72
|
+
if (args.output === "console") {
|
|
73
|
+
consola.info("\n" + image);
|
|
74
|
+
} else if (args.output === "file") {
|
|
75
|
+
const outputPath = pathe.format({ name: isURL(args.path) ? args.path.split("/").at(-1)?.split(".")[0] : pathe.parse(args.path).name, root: "/", ext: ".txt" });
|
|
76
|
+
await storage.setItem(outputPath, image);
|
|
77
|
+
}
|
|
78
|
+
if (!print) {
|
|
79
|
+
consola.error("Print not started.");
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
const runMain = () => runMain$1(main);
|
|
85
|
+
|
|
86
|
+
export { main, runMain };
|
package/dist/index.cjs
ADDED
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
type ASCIICharacterSet = keyof typeof asciiCharacterSet;
|
|
2
|
+
declare const asciiCharacterSet: {
|
|
3
|
+
minimalist: string;
|
|
4
|
+
normal: string;
|
|
5
|
+
normal2: string;
|
|
6
|
+
alphabetic: string;
|
|
7
|
+
alphanumeric: string;
|
|
8
|
+
numerical: string;
|
|
9
|
+
extended: string;
|
|
10
|
+
math: string;
|
|
11
|
+
arrow: string;
|
|
12
|
+
grayscale: string;
|
|
13
|
+
max: string;
|
|
14
|
+
codepage437: string;
|
|
15
|
+
blockelement: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type OutputType = 'console' | 'file' | 'dom';
|
|
19
|
+
interface PrintOptions {
|
|
20
|
+
width?: number;
|
|
21
|
+
widthSkew?: number;
|
|
22
|
+
widthScale?: number;
|
|
23
|
+
output?: OutputType;
|
|
24
|
+
characters?: ASCIICharacterSet;
|
|
25
|
+
grayscale?: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface Print {
|
|
28
|
+
getImage: () => Promise<string>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare function asciiPrint(imagePath: string, opts?: PrintOptions): Promise<Print>;
|
|
32
|
+
|
|
33
|
+
export { type OutputType, asciiPrint };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
type ASCIICharacterSet = keyof typeof asciiCharacterSet;
|
|
2
|
+
declare const asciiCharacterSet: {
|
|
3
|
+
minimalist: string;
|
|
4
|
+
normal: string;
|
|
5
|
+
normal2: string;
|
|
6
|
+
alphabetic: string;
|
|
7
|
+
alphanumeric: string;
|
|
8
|
+
numerical: string;
|
|
9
|
+
extended: string;
|
|
10
|
+
math: string;
|
|
11
|
+
arrow: string;
|
|
12
|
+
grayscale: string;
|
|
13
|
+
max: string;
|
|
14
|
+
codepage437: string;
|
|
15
|
+
blockelement: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type OutputType = 'console' | 'file' | 'dom';
|
|
19
|
+
interface PrintOptions {
|
|
20
|
+
width?: number;
|
|
21
|
+
widthSkew?: number;
|
|
22
|
+
widthScale?: number;
|
|
23
|
+
output?: OutputType;
|
|
24
|
+
characters?: ASCIICharacterSet;
|
|
25
|
+
grayscale?: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface Print {
|
|
28
|
+
getImage: () => Promise<string>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare function asciiPrint(imagePath: string, opts?: PrintOptions): Promise<Print>;
|
|
32
|
+
|
|
33
|
+
export { type OutputType, asciiPrint };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
type ASCIICharacterSet = keyof typeof asciiCharacterSet;
|
|
2
|
+
declare const asciiCharacterSet: {
|
|
3
|
+
minimalist: string;
|
|
4
|
+
normal: string;
|
|
5
|
+
normal2: string;
|
|
6
|
+
alphabetic: string;
|
|
7
|
+
alphanumeric: string;
|
|
8
|
+
numerical: string;
|
|
9
|
+
extended: string;
|
|
10
|
+
math: string;
|
|
11
|
+
arrow: string;
|
|
12
|
+
grayscale: string;
|
|
13
|
+
max: string;
|
|
14
|
+
codepage437: string;
|
|
15
|
+
blockelement: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type OutputType = 'console' | 'file' | 'dom';
|
|
19
|
+
interface PrintOptions {
|
|
20
|
+
width?: number;
|
|
21
|
+
widthSkew?: number;
|
|
22
|
+
widthScale?: number;
|
|
23
|
+
output?: OutputType;
|
|
24
|
+
characters?: ASCIICharacterSet;
|
|
25
|
+
grayscale?: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface Print {
|
|
28
|
+
getImage: () => Promise<string>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare function asciiPrint(imagePath: string, opts?: PrintOptions): Promise<Print>;
|
|
32
|
+
|
|
33
|
+
export { type OutputType, asciiPrint };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { a as asciiPrint } from './shared/unascii.C-iPcHtB.mjs';
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const asciiCharacterSet = {
|
|
4
|
+
minimalist: "#+-.",
|
|
5
|
+
normal: "@%#*+=-:.",
|
|
6
|
+
normal2: "&$Xx+;:.",
|
|
7
|
+
alphabetic: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
|
8
|
+
alphanumeric: "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz",
|
|
9
|
+
numerical: "0896452317",
|
|
10
|
+
extended: "@%#{}[]()<>^*+=~-:.",
|
|
11
|
+
math: "+-\xD7\xF7=\u2260\u2248\u221E\u221A\u03C0",
|
|
12
|
+
arrow: "\u2191\u2197\u2192\u2198\u2193\u2199\u2190\u2196",
|
|
13
|
+
grayscale: `@$BWM#*oahkbdpwmZO0QCJYXzcvnxrjft/|()1{}[]-_+~<>i!lI;:,"^'.`,
|
|
14
|
+
max: `\xC6\xD1\xCA\u0152\xD8M\xC9\xCB\xC8\xC3\xC2WQB\xC5\xE6#N\xC1\xFEE\xC4\xC0HKR\u017D\u0153Xg\xD0\xEAq\xDB\u0160\xD5\xD4A\u20AC\xDFpm\xE3\xE2G\xB5\xF8\xF0\xE98\xDA\xDC$\xEBd\xD9\xFD\xE8\xD3\xDE\xD6\xE5\xFF\xD2b\xAAFD\xF1\xE1ZP\xE4\u0161\xC7\xE0h\xFB\u0178\xDDk\u0178\xAES9\u017EUTe\xB5uOyx\xCE\xBEf4\xF55\xF4\xFA&a\xFC\u21222\xF9\xE7w\xA9Y\xA30V\xC7Lr\xCC\xB33\xCF\xEC\xD3C@n\xC4\xF2s\xA2u\u2030\xBD\xBC\u2021zJ\u0123%\xA4Itoc\xABrjv1l\xAD=\xEF\xEC<>i7\u2020[\xBF?\xD7}*{+()/\xBB\xAB\u2022\xAC|!\xA1\xF7\xA6\xAF\u2014^\xAA\u201E""~\xB3\xBA\xB2\u2013\xB0\xAD\xB9\u2039\u203A;:''\u201A'\u02DC\u02C6\xB8\u2026\xB7\xA8\xB4`,
|
|
15
|
+
codepage437: "\u2588\u2593\u2592\u2591",
|
|
16
|
+
blockelement: "\u2588"
|
|
17
|
+
};
|
|
18
|
+
function rgbToHex({ r, g, b }) {
|
|
19
|
+
r = Math.max(0, Math.min(255, Math.round(r)));
|
|
20
|
+
g = Math.max(0, Math.min(255, Math.round(g)));
|
|
21
|
+
b = Math.max(0, Math.min(255, Math.round(b)));
|
|
22
|
+
const redHex = r.toString(16).padStart(2, "0");
|
|
23
|
+
const greenHex = g.toString(16).padStart(2, "0");
|
|
24
|
+
const blueHex = b.toString(16).padStart(2, "0");
|
|
25
|
+
return `#${redHex}${greenHex}${blueHex}`;
|
|
26
|
+
}
|
|
27
|
+
function isURL(str) {
|
|
28
|
+
const urlPattern = /^(https?:\/\/)?([\d.a-z-]+)\.([.a-z]{2,6})([\w ./-]*)*\/?$/;
|
|
29
|
+
return urlPattern.test(str);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let createCanvas;
|
|
33
|
+
let loadImage;
|
|
34
|
+
let colorizer;
|
|
35
|
+
async function loadFunctions() {
|
|
36
|
+
if (process.env.BROWSER) {
|
|
37
|
+
let createCanvasBrowser = function(width, height) {
|
|
38
|
+
const canvas = document.createElement("canvas");
|
|
39
|
+
canvas.width = width;
|
|
40
|
+
canvas.height = height;
|
|
41
|
+
return canvas;
|
|
42
|
+
};
|
|
43
|
+
async function loadImageBrowser(url) {
|
|
44
|
+
return new Promise((resolve) => {
|
|
45
|
+
const image = new Image();
|
|
46
|
+
image.crossOrigin = "Anonymous";
|
|
47
|
+
image.addEventListener("load", () => resolve(image));
|
|
48
|
+
image.src = url;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
createCanvas = createCanvasBrowser;
|
|
52
|
+
loadImage = loadImageBrowser;
|
|
53
|
+
colorizer = (color, char, output) => output === "console" ? char : `<span style="color: ${color}">${char}</span>`;
|
|
54
|
+
} else {
|
|
55
|
+
try {
|
|
56
|
+
const { createCanvas: createCanvasNode, loadImage: loadImageNode } = await import('canvas');
|
|
57
|
+
const { Chalk } = await import('chalk');
|
|
58
|
+
createCanvas = createCanvasNode;
|
|
59
|
+
loadImage = loadImageNode;
|
|
60
|
+
const chalk = new Chalk();
|
|
61
|
+
colorizer = (color, char, output) => output === "console" ? chalk.hex(color)(char) : char;
|
|
62
|
+
} catch {
|
|
63
|
+
throw new Error("Unable to import canvas/chalk modules");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function getAsciiChar(grayscale, widthScale, characterSet) {
|
|
68
|
+
const chars = asciiCharacterSet[characterSet] + " ".repeat(widthScale);
|
|
69
|
+
const index = Math.floor(grayscale * (chars.length - 1) / 255);
|
|
70
|
+
return chars[index];
|
|
71
|
+
}
|
|
72
|
+
function imageDataToASCII(imageData, widthScale, characterSet, isGrayscale, outputType) {
|
|
73
|
+
let ascii = "";
|
|
74
|
+
const { width, height, data } = imageData;
|
|
75
|
+
for (let y = 0; y < height; y++) {
|
|
76
|
+
for (let x = 0; x < width; x++) {
|
|
77
|
+
const i = (y * width + x) * 4;
|
|
78
|
+
const r = data[i];
|
|
79
|
+
const g = data[i + 1];
|
|
80
|
+
const b = data[i + 2];
|
|
81
|
+
const a = data[i + 3];
|
|
82
|
+
if (a < 16) {
|
|
83
|
+
ascii += " ";
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const brightness = 0.3 * r + 0.59 * g + 0.11 * b;
|
|
87
|
+
let char = getAsciiChar(brightness, widthScale, characterSet);
|
|
88
|
+
if (!isGrayscale) {
|
|
89
|
+
const hexColor = rgbToHex({ r, g, b });
|
|
90
|
+
char = colorizer(hexColor, char, outputType);
|
|
91
|
+
}
|
|
92
|
+
ascii += char;
|
|
93
|
+
}
|
|
94
|
+
ascii += "\n";
|
|
95
|
+
}
|
|
96
|
+
return ascii;
|
|
97
|
+
}
|
|
98
|
+
async function imagePathToASCII(imagePath, width, widthSkew, widthScale, characterSet, isGrayscale, outputType) {
|
|
99
|
+
if (process.env.DEBUG) console.time("loadImage");
|
|
100
|
+
const image = await loadImage(imagePath);
|
|
101
|
+
if (process.env.DEBUG) console.timeEnd("loadImage");
|
|
102
|
+
const aspectRatio = image.width / image.height;
|
|
103
|
+
const canvas = createCanvas(width * widthSkew, Math.floor(width / aspectRatio));
|
|
104
|
+
const ctx = canvas.getContext("2d");
|
|
105
|
+
if (!ctx)
|
|
106
|
+
throw new Error("Canvas Context Undefined");
|
|
107
|
+
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
108
|
+
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
109
|
+
if (process.env.DEBUG) console.time("imageDataToASCII");
|
|
110
|
+
const data = imageDataToASCII(imageData, widthScale, characterSet, isGrayscale, outputType);
|
|
111
|
+
if (process.env.DEBUG) console.timeEnd("imageDataToASCII");
|
|
112
|
+
return data;
|
|
113
|
+
}
|
|
114
|
+
async function asciiPrint(imagePath, opts) {
|
|
115
|
+
const { width = 32, widthSkew = 1.75, widthScale = 1, output = "console", characters = "alphanumeric", grayscale = false } = opts ?? {};
|
|
116
|
+
await loadFunctions();
|
|
117
|
+
if (process.env.DEBUG) console.time("imagePathToASCII");
|
|
118
|
+
const image = imagePathToASCII(imagePath, width, widthSkew, widthScale, characters, grayscale, output);
|
|
119
|
+
if (process.env.DEBUG) console.timeEnd("imagePathToASCII");
|
|
120
|
+
return {
|
|
121
|
+
getImage: async () => image
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
exports.asciiPrint = asciiPrint;
|
|
126
|
+
exports.isURL = isURL;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
const asciiCharacterSet = {
|
|
2
|
+
minimalist: "#+-.",
|
|
3
|
+
normal: "@%#*+=-:.",
|
|
4
|
+
normal2: "&$Xx+;:.",
|
|
5
|
+
alphabetic: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
|
6
|
+
alphanumeric: "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz",
|
|
7
|
+
numerical: "0896452317",
|
|
8
|
+
extended: "@%#{}[]()<>^*+=~-:.",
|
|
9
|
+
math: "+-\xD7\xF7=\u2260\u2248\u221E\u221A\u03C0",
|
|
10
|
+
arrow: "\u2191\u2197\u2192\u2198\u2193\u2199\u2190\u2196",
|
|
11
|
+
grayscale: `@$BWM#*oahkbdpwmZO0QCJYXzcvnxrjft/|()1{}[]-_+~<>i!lI;:,"^'.`,
|
|
12
|
+
max: `\xC6\xD1\xCA\u0152\xD8M\xC9\xCB\xC8\xC3\xC2WQB\xC5\xE6#N\xC1\xFEE\xC4\xC0HKR\u017D\u0153Xg\xD0\xEAq\xDB\u0160\xD5\xD4A\u20AC\xDFpm\xE3\xE2G\xB5\xF8\xF0\xE98\xDA\xDC$\xEBd\xD9\xFD\xE8\xD3\xDE\xD6\xE5\xFF\xD2b\xAAFD\xF1\xE1ZP\xE4\u0161\xC7\xE0h\xFB\u0178\xDDk\u0178\xAES9\u017EUTe\xB5uOyx\xCE\xBEf4\xF55\xF4\xFA&a\xFC\u21222\xF9\xE7w\xA9Y\xA30V\xC7Lr\xCC\xB33\xCF\xEC\xD3C@n\xC4\xF2s\xA2u\u2030\xBD\xBC\u2021zJ\u0123%\xA4Itoc\xABrjv1l\xAD=\xEF\xEC<>i7\u2020[\xBF?\xD7}*{+()/\xBB\xAB\u2022\xAC|!\xA1\xF7\xA6\xAF\u2014^\xAA\u201E""~\xB3\xBA\xB2\u2013\xB0\xAD\xB9\u2039\u203A;:''\u201A'\u02DC\u02C6\xB8\u2026\xB7\xA8\xB4`,
|
|
13
|
+
codepage437: "\u2588\u2593\u2592\u2591",
|
|
14
|
+
blockelement: "\u2588"
|
|
15
|
+
};
|
|
16
|
+
function rgbToHex({ r, g, b }) {
|
|
17
|
+
r = Math.max(0, Math.min(255, Math.round(r)));
|
|
18
|
+
g = Math.max(0, Math.min(255, Math.round(g)));
|
|
19
|
+
b = Math.max(0, Math.min(255, Math.round(b)));
|
|
20
|
+
const redHex = r.toString(16).padStart(2, "0");
|
|
21
|
+
const greenHex = g.toString(16).padStart(2, "0");
|
|
22
|
+
const blueHex = b.toString(16).padStart(2, "0");
|
|
23
|
+
return `#${redHex}${greenHex}${blueHex}`;
|
|
24
|
+
}
|
|
25
|
+
function isURL(str) {
|
|
26
|
+
const urlPattern = /^(https?:\/\/)?([\d.a-z-]+)\.([.a-z]{2,6})([\w ./-]*)*\/?$/;
|
|
27
|
+
return urlPattern.test(str);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let createCanvas;
|
|
31
|
+
let loadImage;
|
|
32
|
+
let colorizer;
|
|
33
|
+
async function loadFunctions() {
|
|
34
|
+
if (process.env.BROWSER) {
|
|
35
|
+
let createCanvasBrowser = function(width, height) {
|
|
36
|
+
const canvas = document.createElement("canvas");
|
|
37
|
+
canvas.width = width;
|
|
38
|
+
canvas.height = height;
|
|
39
|
+
return canvas;
|
|
40
|
+
};
|
|
41
|
+
async function loadImageBrowser(url) {
|
|
42
|
+
return new Promise((resolve) => {
|
|
43
|
+
const image = new Image();
|
|
44
|
+
image.crossOrigin = "Anonymous";
|
|
45
|
+
image.addEventListener("load", () => resolve(image));
|
|
46
|
+
image.src = url;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
createCanvas = createCanvasBrowser;
|
|
50
|
+
loadImage = loadImageBrowser;
|
|
51
|
+
colorizer = (color, char, output) => output === "console" ? char : `<span style="color: ${color}">${char}</span>`;
|
|
52
|
+
} else {
|
|
53
|
+
try {
|
|
54
|
+
const { createCanvas: createCanvasNode, loadImage: loadImageNode } = await import('canvas');
|
|
55
|
+
const { Chalk } = await import('chalk');
|
|
56
|
+
createCanvas = createCanvasNode;
|
|
57
|
+
loadImage = loadImageNode;
|
|
58
|
+
const chalk = new Chalk();
|
|
59
|
+
colorizer = (color, char, output) => output === "console" ? chalk.hex(color)(char) : char;
|
|
60
|
+
} catch {
|
|
61
|
+
throw new Error("Unable to import canvas/chalk modules");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function getAsciiChar(grayscale, widthScale, characterSet) {
|
|
66
|
+
const chars = asciiCharacterSet[characterSet] + " ".repeat(widthScale);
|
|
67
|
+
const index = Math.floor(grayscale * (chars.length - 1) / 255);
|
|
68
|
+
return chars[index];
|
|
69
|
+
}
|
|
70
|
+
function imageDataToASCII(imageData, widthScale, characterSet, isGrayscale, outputType) {
|
|
71
|
+
let ascii = "";
|
|
72
|
+
const { width, height, data } = imageData;
|
|
73
|
+
for (let y = 0; y < height; y++) {
|
|
74
|
+
for (let x = 0; x < width; x++) {
|
|
75
|
+
const i = (y * width + x) * 4;
|
|
76
|
+
const r = data[i];
|
|
77
|
+
const g = data[i + 1];
|
|
78
|
+
const b = data[i + 2];
|
|
79
|
+
const a = data[i + 3];
|
|
80
|
+
if (a < 16) {
|
|
81
|
+
ascii += " ";
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const brightness = 0.3 * r + 0.59 * g + 0.11 * b;
|
|
85
|
+
let char = getAsciiChar(brightness, widthScale, characterSet);
|
|
86
|
+
if (!isGrayscale) {
|
|
87
|
+
const hexColor = rgbToHex({ r, g, b });
|
|
88
|
+
char = colorizer(hexColor, char, outputType);
|
|
89
|
+
}
|
|
90
|
+
ascii += char;
|
|
91
|
+
}
|
|
92
|
+
ascii += "\n";
|
|
93
|
+
}
|
|
94
|
+
return ascii;
|
|
95
|
+
}
|
|
96
|
+
async function imagePathToASCII(imagePath, width, widthSkew, widthScale, characterSet, isGrayscale, outputType) {
|
|
97
|
+
if (process.env.DEBUG) console.time("loadImage");
|
|
98
|
+
const image = await loadImage(imagePath);
|
|
99
|
+
if (process.env.DEBUG) console.timeEnd("loadImage");
|
|
100
|
+
const aspectRatio = image.width / image.height;
|
|
101
|
+
const canvas = createCanvas(width * widthSkew, Math.floor(width / aspectRatio));
|
|
102
|
+
const ctx = canvas.getContext("2d");
|
|
103
|
+
if (!ctx)
|
|
104
|
+
throw new Error("Canvas Context Undefined");
|
|
105
|
+
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
106
|
+
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
107
|
+
if (process.env.DEBUG) console.time("imageDataToASCII");
|
|
108
|
+
const data = imageDataToASCII(imageData, widthScale, characterSet, isGrayscale, outputType);
|
|
109
|
+
if (process.env.DEBUG) console.timeEnd("imageDataToASCII");
|
|
110
|
+
return data;
|
|
111
|
+
}
|
|
112
|
+
async function asciiPrint(imagePath, opts) {
|
|
113
|
+
const { width = 32, widthSkew = 1.75, widthScale = 1, output = "console", characters = "alphanumeric", grayscale = false } = opts ?? {};
|
|
114
|
+
await loadFunctions();
|
|
115
|
+
if (process.env.DEBUG) console.time("imagePathToASCII");
|
|
116
|
+
const image = imagePathToASCII(imagePath, width, widthSkew, widthScale, characters, grayscale, output);
|
|
117
|
+
if (process.env.DEBUG) console.timeEnd("imagePathToASCII");
|
|
118
|
+
return {
|
|
119
|
+
getImage: async () => image
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export { asciiPrint as a, isURL as i };
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shba007/unascii",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "Print any image in ascii anywhere (browser/cli)",
|
|
5
|
+
"author": "Shirsendu Bairagi <shirsendu2001@gmail.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/shba007/unascii.git"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [],
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"type": "module",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.mjs",
|
|
18
|
+
"require": "./dist/index.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./cli": {
|
|
21
|
+
"types": "./dist/cli.d.ts",
|
|
22
|
+
"import": "./dist/cli.mjs",
|
|
23
|
+
"require": "./dist/cli.cjs"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"main": "./dist/index.cjs",
|
|
27
|
+
"module": "./dist/index.mjs",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"bin": {
|
|
30
|
+
"unascii": "./bin/unascii.mjs"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"bin"
|
|
35
|
+
],
|
|
36
|
+
"volta": {
|
|
37
|
+
"node": "20.18.1"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": "^20.15.0",
|
|
41
|
+
"pnpm": "^9.15.0"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"canvas": "^2.11.2",
|
|
45
|
+
"chalk": "^5.3.0",
|
|
46
|
+
"citty": "^0.1.6",
|
|
47
|
+
"consola": "^3.2.3",
|
|
48
|
+
"pathe": "^1.1.2",
|
|
49
|
+
"unstorage": "^1.13.1"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@changesets/cli": "^2.27.10",
|
|
53
|
+
"@dotenvx/dotenvx": "^1.30.1",
|
|
54
|
+
"@types/node": "^22.10.2",
|
|
55
|
+
"@vitest/coverage-v8": "^2.1.8",
|
|
56
|
+
"changelogen": "^0.5.7",
|
|
57
|
+
"eslint": "^9.17.0",
|
|
58
|
+
"eslint-config-unjs": "^0.4.2",
|
|
59
|
+
"jiti": "^2.4.1",
|
|
60
|
+
"prettier": "^3.4.2",
|
|
61
|
+
"typescript": "^5.7.2",
|
|
62
|
+
"unbuild": "3.0.1",
|
|
63
|
+
"vitest": "^2.1.8"
|
|
64
|
+
},
|
|
65
|
+
"scripts": {
|
|
66
|
+
"dev": "vitest dev",
|
|
67
|
+
"lint": "eslint . --fix",
|
|
68
|
+
"format": "prettier . --write",
|
|
69
|
+
"build": "unbuild",
|
|
70
|
+
"play": "jiti playground/cli",
|
|
71
|
+
"release": "pnpm test && changelogen --release && pnpm publish && git push --follow-tags",
|
|
72
|
+
"test": "pnpm lint && pnpm test:types && vitest run --coverage",
|
|
73
|
+
"test:types": "tsc --noEmit --skipLibCheck",
|
|
74
|
+
"unascii": "jiti playground/cli"
|
|
75
|
+
}
|
|
76
|
+
}
|