aes-bridge 2.0.5 → 2.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.
@@ -8,6 +8,10 @@ jobs:
8
8
  deploy:
9
9
  runs-on: ubuntu-latest
10
10
 
11
+ permissions:
12
+ id-token: write
13
+ contents: read
14
+
11
15
  environment:
12
16
  name: npm
13
17
  url: https://www.npmjs.com/package/aes-bridge
@@ -20,7 +24,6 @@ jobs:
20
24
  uses: actions/setup-node@v4
21
25
  with:
22
26
  node-version: '20'
23
- registry-url: 'https://registry.npmjs.org/'
24
27
 
25
28
  - name: Install dependencies
26
29
  run: npm ci
@@ -29,6 +32,4 @@ jobs:
29
32
  run: npm run build
30
33
 
31
34
  - name: Publish to npm
32
- run: npm publish --access public
33
- env:
34
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
35
+ run: npm publish --access public --provenance
@@ -1,4 +1,4 @@
1
- name: Run Tests
1
+ name: Tests
2
2
 
3
3
  on:
4
4
  push:
@@ -22,5 +22,5 @@ jobs:
22
22
  run: npm ci
23
23
 
24
24
  - name: Run tests
25
- run: npm test
25
+ run: npm run test:build
26
26
 
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # AesBridge JS
2
- ![NPM Version](https://img.shields.io/npm/v/aes-bridge.svg)
3
- ![CI Status](https://github.com/mervick/aes-bridge-js/actions/workflows/tests.yml/badge.svg)
2
+
3
+ [![NPM Version](https://img.shields.io/npm/v/aes-bridge.svg)](https://www.npmjs.com/package/aes-bridge)
4
+ [![CI Status](https://github.com/mervick/aes-bridge-js/actions/workflows/tests.yml/badge.svg)](https://github.com/mervick/aes-bridge-js/actions/workflows/tests.yml)
4
5
 
5
6
  **AesBridge** is a modern, secure, and cross-language **AES** encryption library. It offers a unified interface for encrypting and decrypting data across multiple programming languages. Supports **GCM**, **CBC**, and **legacy AES Everywhere** modes.
6
7
 
@@ -43,7 +44,7 @@ yarn add aes-bridge
43
44
 
44
45
  #### CDN Option
45
46
  ```html
46
- <script src="https://cdn.jsdelivr.net/npm/aes-bridge@v2.0.0/dist/aes-bridge.umd.js"></script>
47
+ <script src="https://cdn.jsdelivr.net/npm/aes-bridge@v2.0.5/dist/aes-bridge.umd.js"></script>
47
48
  ```
48
49
 
49
50
  #### Node.js (ES Modules)
@@ -135,8 +136,9 @@ All functions in this library return a `Promise`. Specifically:
135
136
  * `decrypt`, `decryptGcm`, `decryptGcmBin`, `decryptCbc`, `decryptCbcBin`, `decryptLegacy`
136
137
  **Returns:** `Promise<Uint8Array>` - raw binary data.
137
138
 
139
+ ---
138
140
 
139
- ## Converting `Uint8Array` to `string`
141
+ ### Converting `Uint8Array` to `string`
140
142
 
141
143
  As noted above, decryption functions and binary encryption functions (those with `decrypt` or `Bin` in their name) return a `Promise<Uint8Array>`. If you need to convert this `Uint8Array` back into a human-readable string, you'll typically use the `TextDecoder` API, especially if the original data was a UTF-8 encoded string.
142
144
 
package/cli.js CHANGED
@@ -85,15 +85,19 @@ program
85
85
  throw new Error('Invalid decryption mode.');
86
86
  }
87
87
 
88
- const decoder = new TextDecoder('utf-8', { fatal: true });
89
- decryptedResult = decoder.decode(decryptedResult);
90
-
91
88
  if (options.b64) {
92
- // If --b64, encode the decrypted result to base64.
93
- console.log(decryptedResult.toString('base64'));
89
+ // If --b64, encode the decrypted result to base64.
90
+ let binaryString = '';
91
+ decryptedResult.forEach(byte => {
92
+ binaryString += String.fromCharCode(byte);
93
+ });
94
+
95
+ console.log(btoa(binaryString));
94
96
  } else {
95
- // Otherwise, assume it's UTF-8 and print.
96
- console.log(decryptedResult.toString('utf8'));
97
+ const decoder = new TextDecoder('utf-8', { fatal: true });
98
+ decryptedResult = decoder.decode(decryptedResult);
99
+ // Otherwise, assume it's UTF-8 and print.
100
+ console.log(decryptedResult.toString('utf8'));
97
101
  }
98
102
  } catch (error) {
99
103
  console.error(`Error: ${error.message}`);
package/dist/cbc.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Encrypts plaintext using AES-CBC + HMAC with derived key from password.
3
+ * Returns binary format: salt (16) + IV (16) + ciphertext + HMAC (32).
4
+ */
5
+ export function encryptCbcBin(plaintext: string | Uint8Array, password: string | Uint8Array): Promise<Uint8Array>;
6
+
7
+ /**
8
+ * Decrypts binary data encrypted with `encryptCbcBin`.
9
+ */
10
+ export function decryptCbcBin(data: string | Uint8Array, password: string | Uint8Array): Promise<Uint8Array>;
11
+
12
+ /**
13
+ * Encrypts data and returns result as base64 string.
14
+ */
15
+ export function encryptCbc(data: string | Uint8Array, password: string | Uint8Array): Promise<string>;
16
+
17
+ /**
18
+ * Decrypts base64-encoded AES-CBC + HMAC data.
19
+ */
20
+ export function decryptCbc(data: string, password: string | Uint8Array): Promise<Uint8Array>;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Converts a string to Uint8Array using UTF-8 encoding.
3
+ * If input is already Uint8Array, returns it as-is.
4
+ */
5
+ export function toBytes(input: string | Uint8Array): Uint8Array;
6
+
7
+ /**
8
+ * Converts an Uint8Array to string using UTF-8 encoding.
9
+ */
10
+ export function bytesToString(bytes: Uint8Array | string): string;
11
+
12
+ /**
13
+ * Generates a random Uint8Array of given length using secure crypto.
14
+ */
15
+ export function generateRandom(length: number): Uint8Array;
16
+
17
+ /**
18
+ * Encodes bytes to base64 string.
19
+ */
20
+ export function base64Encode(bytes: Uint8Array): string;
21
+
22
+ /**
23
+ * Decodes base64 string to Uint8Array.
24
+ */
25
+ export function base64Decode(b64: string): Uint8Array;
package/dist/gcm.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Encrypts plaintext using AES-GCM with key derived from password.
3
+ * Output format: salt(16) + nonce(12) + ciphertext + tag(16)
4
+ */
5
+ export function encryptGcmBin(plaintext: string | Uint8Array, password: string | Uint8Array): Promise<Uint8Array>;
6
+
7
+ /**
8
+ * Decrypts binary data produced by encryptGcmBin().
9
+ */
10
+ export function decryptGcmBin(data: string | Uint8Array, password: string | Uint8Array): Promise<Uint8Array>;
11
+
12
+ /**
13
+ * Encrypts data using AES-GCM and returns Base64 string.
14
+ */
15
+ export function encryptGcm(data: string | Uint8Array, password: string | Uint8Array): Promise<string>;
16
+
17
+ /**
18
+ * Decrypts Base64 encoded AES-GCM data.
19
+ */
20
+ export function decryptGcm(data: string, password: string | Uint8Array): Promise<Uint8Array>;
@@ -0,0 +1,6 @@
1
+ export { encryptCbc, encryptCbcBin, decryptCbc, decryptCbcBin } from "./cbc";
2
+ export { encryptGcm, encryptGcmBin, decryptGcm, decryptGcmBin } from "./gcm";
3
+ export { encryptLegacy, decryptLegacy } from "./legacy";
4
+
5
+ export const encrypt: typeof import("./gcm").encryptGcm;
6
+ export const decrypt: typeof import("./gcm").decryptGcm;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Encrypts plaintext using AES-256-CBC with OpenSSL-compatible format.
3
+ * Output: Base64 encoded "Salted__" + salt(8) + ciphertext
4
+ */
5
+ export function encryptLegacy(raw: string | Uint8Array, passphrase: string | Uint8Array): Promise<string>;
6
+
7
+ /**
8
+ * Decrypts Base64-encoded AES-256-CBC data with OpenSSL-compatible format.
9
+ */
10
+ export function decryptLegacy(enc: string, passphrase: string | Uint8Array): Promise<Uint8Array>;
package/dist/md5.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ type InputType = string | number[] | Uint8Array | ArrayBuffer;
2
+
3
+ interface Md5 {
4
+ update(message: InputType): Md5;
5
+ hex(): string;
6
+ toString(): string;
7
+ digest(): number[];
8
+ array(): number[];
9
+ arrayBuffer(): ArrayBuffer;
10
+ buffer(): ArrayBuffer;
11
+ base64(): string;
12
+ }
13
+
14
+ interface HmacMd5 extends Md5 {}
15
+
16
+ interface Md5Static {
17
+ (message: InputType): string;
18
+ hex(message: InputType): string;
19
+ array(message: InputType): number[];
20
+ digest(message: InputType): number[];
21
+ arrayBuffer(message: InputType): ArrayBuffer;
22
+ buffer(message: InputType): ArrayBuffer;
23
+ base64(message: InputType): string;
24
+ create(): Md5;
25
+ update(message: InputType): Md5;
26
+ hmac: {
27
+ (key: InputType, message: InputType): string;
28
+ hex(key: InputType, message: InputType): string;
29
+ array(key: InputType, message: InputType): number[];
30
+ digest(key: InputType, message: InputType): number[];
31
+ arrayBuffer(key: InputType, message: InputType): ArrayBuffer;
32
+ buffer(key: InputType, message: InputType): ArrayBuffer;
33
+ base64(key: InputType, message: InputType): string;
34
+ create(key: InputType): HmacMd5;
35
+ update(key: InputType, message: InputType): HmacMd5;
36
+ };
37
+ }
38
+
39
+ declare const md5: Md5Static;
40
+ export default md5;
package/package.json CHANGED
@@ -1,17 +1,24 @@
1
1
  {
2
2
  "name": "aes-bridge",
3
- "version": "2.0.5",
3
+ "version": "2.1.0",
4
4
  "description": "AesBridge is a modern, secure and cross-language AES encryption library",
5
- "type": "module",
6
5
  "main": "dist/aes-bridge.umd.js",
7
6
  "module": "dist/aes-bridge.esm.js",
7
+ "types": "dist/index.d.ts",
8
8
  "exports": {
9
- "import": "./dist/aes-bridge.esm.js",
10
- "require": "./dist/aes-bridge.umd.js"
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/aes-bridge.esm.js",
12
+ "require": "./dist/aes-bridge.cjs.js",
13
+ "default": "./dist/aes-bridge.umd.js"
14
+ }
11
15
  },
12
16
  "scripts": {
13
- "build": "rollup -c",
14
- "test": "vitest"
17
+ "build": "rollup -c && npm run copy-types",
18
+ "copy-types": "cp src/*.d.ts dist/ 2>/dev/null || true",
19
+ "test": "vitest --run",
20
+ "test:build": "npm run build && npm test",
21
+ "test:formats": "npm run build && vitest formats.test.js"
15
22
  },
16
23
  "repository": {
17
24
  "type": "git",
package/rollup.config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import json from '@rollup/plugin-json';
2
2
  import terser from '@rollup/plugin-terser';
3
- // import commonjs from '@rollup/plugin-commonjs';
3
+ import commonjs from '@rollup/plugin-commonjs';
4
4
  import { nodeResolve } from '@rollup/plugin-node-resolve';
5
5
 
6
6
  export default [
@@ -21,11 +21,13 @@ export default [
21
21
  {
22
22
  file: 'dist/aes-bridge.cjs.js',
23
23
  format: 'cjs',
24
- sourcemap: true
24
+ sourcemap: true,
25
+ exports: 'named',
26
+ esModule: false
25
27
  }
26
28
  ],
27
29
  plugins: [
28
- // commonjs(),
30
+ commonjs(),
29
31
  nodeResolve(),
30
32
  json(),
31
33
  terser({
@@ -33,6 +35,7 @@ export default [
33
35
  comments: false
34
36
  }
35
37
  })
36
- ]
38
+ ],
39
+ external: []
37
40
  }
38
41
  ];
package/src/cbc.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Encrypts plaintext using AES-CBC + HMAC with derived key from password.
3
+ * Returns binary format: salt (16) + IV (16) + ciphertext + HMAC (32).
4
+ */
5
+ export function encryptCbcBin(plaintext: string | Uint8Array, password: string | Uint8Array): Promise<Uint8Array>;
6
+
7
+ /**
8
+ * Decrypts binary data encrypted with `encryptCbcBin`.
9
+ */
10
+ export function decryptCbcBin(data: string | Uint8Array, password: string | Uint8Array): Promise<Uint8Array>;
11
+
12
+ /**
13
+ * Encrypts data and returns result as base64 string.
14
+ */
15
+ export function encryptCbc(data: string | Uint8Array, password: string | Uint8Array): Promise<string>;
16
+
17
+ /**
18
+ * Decrypts base64-encoded AES-CBC + HMAC data.
19
+ */
20
+ export function decryptCbc(data: string, password: string | Uint8Array): Promise<Uint8Array>;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Converts a string to Uint8Array using UTF-8 encoding.
3
+ * If input is already Uint8Array, returns it as-is.
4
+ */
5
+ export function toBytes(input: string | Uint8Array): Uint8Array;
6
+
7
+ /**
8
+ * Converts an Uint8Array to string using UTF-8 encoding.
9
+ */
10
+ export function bytesToString(bytes: Uint8Array | string): string;
11
+
12
+ /**
13
+ * Generates a random Uint8Array of given length using secure crypto.
14
+ */
15
+ export function generateRandom(length: number): Uint8Array;
16
+
17
+ /**
18
+ * Encodes bytes to base64 string.
19
+ */
20
+ export function base64Encode(bytes: Uint8Array): string;
21
+
22
+ /**
23
+ * Decodes base64 string to Uint8Array.
24
+ */
25
+ export function base64Decode(b64: string): Uint8Array;
package/src/gcm.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Encrypts plaintext using AES-GCM with key derived from password.
3
+ * Output format: salt(16) + nonce(12) + ciphertext + tag(16)
4
+ */
5
+ export function encryptGcmBin(plaintext: string | Uint8Array, password: string | Uint8Array): Promise<Uint8Array>;
6
+
7
+ /**
8
+ * Decrypts binary data produced by encryptGcmBin().
9
+ */
10
+ export function decryptGcmBin(data: string | Uint8Array, password: string | Uint8Array): Promise<Uint8Array>;
11
+
12
+ /**
13
+ * Encrypts data using AES-GCM and returns Base64 string.
14
+ */
15
+ export function encryptGcm(data: string | Uint8Array, password: string | Uint8Array): Promise<string>;
16
+
17
+ /**
18
+ * Decrypts Base64 encoded AES-GCM data.
19
+ */
20
+ export function decryptGcm(data: string, password: string | Uint8Array): Promise<Uint8Array>;
package/src/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export { encryptCbc, encryptCbcBin, decryptCbc, decryptCbcBin } from "./cbc";
2
+ export { encryptGcm, encryptGcmBin, decryptGcm, decryptGcmBin } from "./gcm";
3
+ export { encryptLegacy, decryptLegacy } from "./legacy";
4
+
5
+ export const encrypt: typeof import("./gcm").encryptGcm;
6
+ export const decrypt: typeof import("./gcm").decryptGcm;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Encrypts plaintext using AES-256-CBC with OpenSSL-compatible format.
3
+ * Output: Base64 encoded "Salted__" + salt(8) + ciphertext
4
+ */
5
+ export function encryptLegacy(raw: string | Uint8Array, passphrase: string | Uint8Array): Promise<string>;
6
+
7
+ /**
8
+ * Decrypts Base64-encoded AES-256-CBC data with OpenSSL-compatible format.
9
+ */
10
+ export function decryptLegacy(enc: string, passphrase: string | Uint8Array): Promise<Uint8Array>;
package/src/md5.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ type InputType = string | number[] | Uint8Array | ArrayBuffer;
2
+
3
+ interface Md5 {
4
+ update(message: InputType): Md5;
5
+ hex(): string;
6
+ toString(): string;
7
+ digest(): number[];
8
+ array(): number[];
9
+ arrayBuffer(): ArrayBuffer;
10
+ buffer(): ArrayBuffer;
11
+ base64(): string;
12
+ }
13
+
14
+ interface HmacMd5 extends Md5 {}
15
+
16
+ interface Md5Static {
17
+ (message: InputType): string;
18
+ hex(message: InputType): string;
19
+ array(message: InputType): number[];
20
+ digest(message: InputType): number[];
21
+ arrayBuffer(message: InputType): ArrayBuffer;
22
+ buffer(message: InputType): ArrayBuffer;
23
+ base64(message: InputType): string;
24
+ create(): Md5;
25
+ update(message: InputType): Md5;
26
+ hmac: {
27
+ (key: InputType, message: InputType): string;
28
+ hex(key: InputType, message: InputType): string;
29
+ array(key: InputType, message: InputType): number[];
30
+ digest(key: InputType, message: InputType): number[];
31
+ arrayBuffer(key: InputType, message: InputType): ArrayBuffer;
32
+ buffer(key: InputType, message: InputType): ArrayBuffer;
33
+ base64(key: InputType, message: InputType): string;
34
+ create(key: InputType): HmacMd5;
35
+ update(key: InputType, message: InputType): HmacMd5;
36
+ };
37
+ }
38
+
39
+ declare const md5: Md5Static;
40
+ export default md5;
@@ -0,0 +1,133 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { spawnSync } from 'child_process';
3
+ import { readFileSync } from 'fs';
4
+ import { rmSync, mkdirSync } from 'fs';
5
+ import { fileURLToPath } from 'url';
6
+ import path from 'path';
7
+ import { writeFile, readFile } from 'fs/promises';
8
+
9
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
+ const distDir = path.resolve(__dirname, '../dist');
11
+ const projectRoot = path.dirname(__dirname);
12
+
13
+ describe('Build Formats Compatibility', () => {
14
+ const testText = 'hello world';
15
+ const testPass = 'MyStrongPass123';
16
+
17
+ // 1. ESM test
18
+ it('ESM import works', async () => {
19
+ const { encryptGcm, decryptGcm } = await import('../dist/aes-bridge.esm.js');
20
+ const ciphertext = await encryptGcm(testText, testPass);
21
+ const decrypted = await decryptGcm(ciphertext, testPass);
22
+ const plaintext = (new TextDecoder('utf-8')).decode(decrypted);
23
+ expect(plaintext).toBe(testText);
24
+ });
25
+
26
+ // 2. CJS test
27
+ it('CJS require works', () => {
28
+ const result = spawnSync('node', [
29
+ '-e',
30
+ `const aes = require('${path.resolve(distDir, 'aes-bridge.cjs.js')}');
31
+ console.log(JSON.stringify({
32
+ success: typeof aes.encryptGcm === 'function',
33
+ hasEncrypt: !!aes.encryptGcm
34
+ }))`
35
+ ]);
36
+
37
+ const output = JSON.parse(result.stdout.toString());
38
+ expect(output.success).toBe(true);
39
+ expect(output.hasEncrypt).toBe(true);
40
+ });
41
+
42
+ // 3. UMD test
43
+ it('UMD global works', () => {
44
+ const umdContent = readFileSync(path.resolve(distDir, 'aes-bridge.umd.js'), 'utf8');
45
+ const script = `(function() { ${umdContent} })();`;
46
+
47
+ const vm = require('vm');
48
+ const context = vm.createContext({ console, aes_bridge: null });
49
+ vm.runInContext(script, context);
50
+
51
+ expect(context.aes_bridge).toBeDefined();
52
+ expect(typeof context.aes_bridge.encryptGcm).toBe('function');
53
+ });
54
+
55
+ // 4. npm pack test
56
+ it('npm pack + require works', async () => {
57
+ const tempDir = path.join(__dirname, 'temp-pack-test');
58
+
59
+ try {
60
+ rmSync(tempDir, { recursive: true, force: true });
61
+ } catch (e) {
62
+ }
63
+
64
+ mkdirSync(tempDir, { recursive: true });
65
+
66
+ await writeFile(
67
+ path.join(tempDir, 'package.json'),
68
+ JSON.stringify({
69
+ name: 'test-consumer',
70
+ version: '1.0.0',
71
+ type: 'commonjs'
72
+ })
73
+ );
74
+
75
+ const packResult = spawnSync('npm', ['pack'], {
76
+ cwd: projectRoot,
77
+ encoding: 'utf8'
78
+ });
79
+
80
+ const tgzFile = packResult.stdout.trim();
81
+ const fullTgzPath = path.join(projectRoot, tgzFile);
82
+
83
+ const installResult = spawnSync('npm', ['install', fullTgzPath], {
84
+ cwd: tempDir,
85
+ stdio: 'inherit'
86
+ });
87
+
88
+ expect(installResult.status).toBe(0);
89
+
90
+ // Testing require
91
+ const result = spawnSync('node', [
92
+ '-e',
93
+ `const aes = require('aes-bridge');
94
+ (async()=>{
95
+ try {
96
+ if (!aes || !aes.encryptGcm) {
97
+ throw new Error('No aes.encryptGcm');
98
+ }
99
+ const ct = await aes.encryptGcm('${testText}', '${testPass}');
100
+ const decrypted = await aes.decryptGcm(ct, '${testPass}');
101
+ const pt = (new TextDecoder('utf-8')).decode(decrypted);
102
+ console.log(JSON.stringify({success: pt === '${testText}'}));
103
+ } catch(e) {
104
+ console.error('ERROR:', e.message);
105
+ console.log(JSON.stringify({success: false, error: e.message}));
106
+ process.exit(1);
107
+ }
108
+ })();`
109
+ ], {
110
+ cwd: tempDir,
111
+ timeout: 5000
112
+ });
113
+
114
+ if (result.status !== 0) {
115
+ console.error('Test result:', result.stderr.toString());
116
+ throw new Error(`Require test failed with status ${result.status}`);
117
+ }
118
+
119
+ const output = JSON.parse(result.stdout.toString().trim());
120
+ expect(output.success).toBe(true);
121
+ });
122
+
123
+ // 5. package.json exports
124
+ it('package.json exports are correct', () => {
125
+ const pkg = JSON.parse(readFileSync(path.resolve(projectRoot, 'package.json'), 'utf8'));
126
+ const exports = pkg.exports['.'];
127
+
128
+ expect(exports.types).toBe('./dist/index.d.ts');
129
+ expect(exports.import).toBe('./dist/aes-bridge.esm.js');
130
+ expect(exports.require).toBe('./dist/aes-bridge.cjs.js');
131
+ expect(exports.default).toBe('./dist/aes-bridge.umd.js');
132
+ });
133
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "moduleResolution": "bundler",
4
+ "allowJs": true,
5
+ "esModuleInterop": true,
6
+ "allowSyntheticDefaultImports": true,
7
+ "target": "ES2020",
8
+ "module": "ESNext",
9
+ "lib": ["ES2020", "DOM"],
10
+ "skipLibCheck": true,
11
+ "noEmit": true
12
+ },
13
+ "include": [
14
+ "src/**/*.js",
15
+ "src/**/*.d.ts"
16
+ ]
17
+ }
@@ -0,0 +1,17 @@
1
+ import { defineConfig } from 'vitest/config';
2
+ import path from 'path';
3
+
4
+ export default defineConfig({
5
+ test: {
6
+ include: [
7
+ 'index.test.js',
8
+ 'formats.test.js',
9
+ 'test/**/*.{test,spec}.js'
10
+ ],
11
+ environment: 'node',
12
+ coverage: {
13
+ provider: 'v8',
14
+ reporter: ['text', 'json', 'html']
15
+ }
16
+ }
17
+ });