devicer.js 1.0.2

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 ADDED
@@ -0,0 +1,21 @@
1
+ # FP-Devicer
2
+ ## Developed by Gateway Corporate Solutions LLC
3
+
4
+ FP-Devicer is a digital fingerprinting middleware library designed for ease of use and near-universal compatibility with servers.
5
+
6
+ Importing and using the library to compare fingerprints between users is as simple as collecting some user data and running the calculateConfidence function.
7
+ ```javascript
8
+ import { FPUserDataSet as UserData, calculateConfidence } from "fp-devicer";
9
+
10
+ const user1: UserData = {
11
+ // Collected data goes here
12
+ }
13
+
14
+ const user2: UserData = {
15
+ // Collected data goes here
16
+ }
17
+
18
+ const confidence = calculateConfidence(user1, user2);
19
+ ```
20
+
21
+ The resulting confidence will range between 0 and 100, with 100 providing the highest confidence of the users being identical.
package/license.txt ADDED
@@ -0,0 +1,27 @@
1
+ # DON'T BE A DICK PUBLIC LICENSE
2
+
3
+ > Version 1.1, December 2016
4
+
5
+ > Copyright (C) 2025 Gateway Corporate Solutions LLC
6
+
7
+ Everyone is permitted to copy and distribute verbatim or modified
8
+ copies of this license document.
9
+
10
+ > DON'T BE A DICK PUBLIC LICENSE
11
+ > TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 1. Do whatever you like with the original work, just don't be a dick.
14
+
15
+ Being a dick includes - but is not limited to - the following instances:
16
+
17
+ 1a. Outright copyright infringement - Don't just copy this and change the name.
18
+ 1b. Selling the unmodified original with no work done what-so-ever, that's REALLY being a dick.
19
+ 1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick.
20
+
21
+ 2. If you become rich through modifications, related works/services, or supporting the original work,
22
+ share the love. Only a dick would make loads off this work and not buy the original work's
23
+ creator(s) a pint.
24
+
25
+ 3. Code is provided with no warranty. Using somebody else's code and bitching when it goes wrong makes
26
+ you a DONKEY dick. Fix the problem yourself. A non-dick would submit the fix back.
27
+
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "devicer.js",
3
+ "version": "1.0.2",
4
+ "description": "Open-Source Digital Fingerprinting Middleware",
5
+ "main": "src/main.js",
6
+ "scripts": {
7
+ "test": "npx vitest",
8
+ "build": "tsc"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/gatewaycorporate/fp-devicer.git"
13
+ },
14
+ "keywords": [
15
+ "fingerprinting",
16
+ "middleware",
17
+ "identification",
18
+ "tracking"
19
+ ],
20
+ "author": "Samuel Roux, Steven Perso, and one anonymous co-author",
21
+ "license": "SEE LICENSE IN license.txt",
22
+ "bugs": {
23
+ "url": "https://github.com/gatewaycorporate/fp-devicer/issues"
24
+ },
25
+ "homepage": "https://github.com/gatewaycorporate/fp-devicer#readme",
26
+ "dependencies": {
27
+ "tlsh": "^1.0.8",
28
+ "vitest": "^3.2.3"
29
+ }
30
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateConfidence = void 0;
4
+ const tlsh_1 = require("./tlsh");
5
+ function calculateConfidence(data1, data2) {
6
+ // Calculate the hash for each user data
7
+ const hash1 = (0, tlsh_1.getHash)(JSON.stringify(data1));
8
+ const hash2 = (0, tlsh_1.getHash)(JSON.stringify(data2));
9
+ // Compare the hashes to get their difference
10
+ const differenceScore = (0, tlsh_1.compareHashes)(hash1, hash2);
11
+ // Compare how many fields are the same in both datasets
12
+ let fields = 0;
13
+ let matches = 0;
14
+ for (const key in data1) {
15
+ if (data1[key] !== undefined && data2[key] !== undefined) {
16
+ fields++;
17
+ if (data1[key] == data2[key]) {
18
+ matches++;
19
+ }
20
+ }
21
+ }
22
+ const inverseMatchScore = 1 - (matches / fields);
23
+ const x = (differenceScore / 1.5) * inverseMatchScore;
24
+ if (inverseMatchScore === 0 || differenceScore === 0) {
25
+ return 100;
26
+ }
27
+ return 100 / (1 + Math.E ** (-4.5 + (0.25 * x)));
28
+ }
29
+ exports.calculateConfidence = calculateConfidence;
@@ -0,0 +1,30 @@
1
+ import { getHash, compareHashes } from "./tlsh";
2
+ import { FPDataSet } from "../types/data";
3
+
4
+ export function calculateConfidence(data1: FPDataSet, data2: FPDataSet): number {
5
+ // Calculate the hash for each user data
6
+ const hash1 = getHash(JSON.stringify(data1));
7
+ const hash2 = getHash(JSON.stringify(data2));
8
+
9
+ // Compare the hashes to get their difference
10
+ const differenceScore = compareHashes(hash1, hash2);
11
+
12
+ // Compare how many fields are the same in both datasets
13
+ let fields = 0;
14
+ let matches = 0;
15
+ for (const key in data1) {
16
+ if (data1[key] !== undefined && data2[key] !== undefined) {
17
+ fields++;
18
+ if (data1[key] == data2[key]) {
19
+ matches++;
20
+ }
21
+ }
22
+ }
23
+
24
+ const inverseMatchScore = 1 - (matches / fields);
25
+ const x = (differenceScore / 1.5) * inverseMatchScore
26
+ if (inverseMatchScore === 0 || differenceScore === 0) {
27
+ return 100;
28
+ }
29
+ return 100 / (1 + Math.E ** (-4.5 + (0.25 * x)));
30
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.compareHashes = exports.getHash = void 0;
7
+ const tlsh_1 = __importDefault(require("tlsh"));
8
+ const digest_hash_builder_js_1 = __importDefault(require("tlsh/lib/digests/digest-hash-builder.js"));
9
+ function getHash(data) {
10
+ // Convert the input data to a string if it's not already
11
+ const inputString = typeof data === 'string' ? data : JSON.stringify(data);
12
+ // Generate the TLSH hash
13
+ const tlshHash = (0, tlsh_1.default)(inputString);
14
+ // Return the hash as a string
15
+ return tlshHash;
16
+ }
17
+ exports.getHash = getHash;
18
+ function compareHashes(hash1, hash2) {
19
+ const digest1 = (0, digest_hash_builder_js_1.default)().withHash(hash1).build();
20
+ const digest2 = (0, digest_hash_builder_js_1.default)().withHash(hash2).build();
21
+ return digest1.calculateDifference(digest2, true);
22
+ }
23
+ exports.compareHashes = compareHashes;
@@ -0,0 +1,19 @@
1
+ import hash from 'tlsh';
2
+ import DigestHashBuilder from 'tlsh/lib/digests/digest-hash-builder.js';
3
+
4
+ export function getHash(data: string): string {
5
+ // Convert the input data to a string if it's not already
6
+ const inputString = typeof data === 'string' ? data : JSON.stringify(data);
7
+
8
+ // Generate the TLSH hash
9
+ const tlshHash = hash(inputString);
10
+
11
+ // Return the hash as a string
12
+ return tlshHash;
13
+ }
14
+
15
+ export function compareHashes(hash1: string, hash2: string): number {
16
+ const digest1 = DigestHashBuilder().withHash(hash1).build();
17
+ const digest2 = DigestHashBuilder().withHash(hash2).build();
18
+ return digest1.calculateDifference(digest2, true);
19
+ }
package/src/main.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateConfidence = void 0;
4
+ const confidence_1 = require("./libs/confidence");
5
+ Object.defineProperty(exports, "calculateConfidence", { enumerable: true, get: function () { return confidence_1.calculateConfidence; } });
package/src/main.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { FPUserDataSet, FPDataSet } from "./types/data";
2
+ import { calculateConfidence } from "./libs/confidence";
3
+
4
+ export { type FPUserDataSet, type FPDataSet, calculateConfidence };
package/src/tlsh.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ declare module 'tlsh' {
2
+ function hash(data: string): string;
3
+ export default hash;
4
+ }
5
+
6
+ declare module 'tlsh/lib/digests/digest-hash-builder.js' {
7
+ export default function DigestHashBuilder(): {
8
+ withHash: (hash: string) => {
9
+ build: () => {
10
+ calculateDifference: (other: any, normalize?: boolean) => number;
11
+ };
12
+ };
13
+ };
14
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,25 @@
1
+ export interface FPUserDataSet {
2
+ fonts: string[];
3
+ hardware: {
4
+ cpu: string;
5
+ gpu: string;
6
+ ram: number; // in MB
7
+ }
8
+ userAgent: string;
9
+ screen: {
10
+ width: number;
11
+ height: number;
12
+ colorDepth: number;
13
+ };
14
+ timezone: string;
15
+ ip: string;
16
+ languages: string[];
17
+ plugins: string[];
18
+ canvasHash: string;
19
+ audioHash: string;
20
+ webglHash: string;
21
+ }
22
+
23
+ export interface FPDataSet {
24
+ [key: string]: any;
25
+ }
@@ -0,0 +1,103 @@
1
+ import { it, describe, expect } from 'vitest';
2
+ import { FPUserDataSet } from '../src/types/data';
3
+ import { getHash } from '../src/libs/tlsh';
4
+ import { calculateConfidence } from '../src/libs/confidence';
5
+ import { randomString } from './tlsh.test';
6
+
7
+ const sampleData1: FPUserDataSet = {
8
+ fonts: ['Arial', 'Verdana'],
9
+ hardware: {
10
+ cpu: 'Intel Core i7',
11
+ gpu: 'NVIDIA GTX 1080',
12
+ ram: 16384 // in MB
13
+ },
14
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
15
+ screen: {
16
+ width: 1920,
17
+ height: 1080,
18
+ colorDepth: 24
19
+ },
20
+ timezone: 'America/New_York',
21
+ ip: '157.185.170.244',
22
+ languages: ['en-US', 'en'],
23
+ plugins: ['Chrome PDF Viewer', 'Shockwave Flash'],
24
+ canvasHash: getHash(randomString(524)),
25
+ audioHash: getHash(randomString(524)),
26
+ webglHash: getHash(randomString(524))
27
+ };
28
+
29
+ const sampleData2: FPUserDataSet = {
30
+ fonts: ['Arial', 'Verdana'],
31
+ hardware: {
32
+ cpu: 'Pentium 4',
33
+ gpu: 'Intel HD Graphics',
34
+ ram: 4096 // in MB
35
+ },
36
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
37
+ screen: {
38
+ width: 1280,
39
+ height: 720,
40
+ colorDepth: 24
41
+ },
42
+ timezone: 'Europe/London',
43
+ ip: '178.238.11.6',
44
+ languages: ['en-GB', 'en'],
45
+ plugins: ['Chrome PDF Viewer', 'Shockwave Flash'],
46
+ canvasHash: getHash(randomString(524)),
47
+ audioHash: getHash(randomString(524)),
48
+ webglHash: getHash(randomString(524))
49
+ };
50
+
51
+ describe('Confidence Calculation', () => {
52
+ it('should calculate confidence between two user data objects', () => {
53
+ const confidence = calculateConfidence(sampleData1, sampleData2);
54
+ console.log('Confidence:', confidence);
55
+ expect(typeof confidence).toBe('number');
56
+ expect(confidence).toBeGreaterThanOrEqual(0);
57
+ expect(confidence).toBeLessThanOrEqual(100);
58
+ });
59
+
60
+ it('should return 100% confidence for identical user data', () => {
61
+ const confidence = calculateConfidence(sampleData1, sampleData1);
62
+ expect(confidence).toBe(100);
63
+ });
64
+
65
+ it('should return high confidence for similar user data', () => {
66
+ const similarData: FPUserDataSet = {
67
+ ...sampleData1,
68
+ hardware: {
69
+ ...sampleData1.hardware,
70
+ ram: 8192 // Slightly different RAM
71
+ }
72
+ };
73
+ const confidence = calculateConfidence(sampleData1, similarData);
74
+ console.log('Confidence for similar data:', confidence);
75
+ expect(confidence).toBeGreaterThan(80);
76
+ });
77
+
78
+ it('should return lower confidence for different user data', () => {
79
+ const confidence = calculateConfidence(sampleData1, sampleData2);
80
+ console.log('Confidence for different data:', confidence);
81
+ expect(confidence).toBeLessThan(10);
82
+ });
83
+
84
+ it('should return middling confidence for partially similar data', () => {
85
+ const partialData: FPUserDataSet = {
86
+ ...sampleData1,
87
+ hardware: {
88
+ ...sampleData1.hardware,
89
+ gpu: 'Intel HD Graphics' // Different GPU
90
+ },
91
+ screen: {
92
+ ...sampleData1.screen,
93
+ width: 1280, // Different screen width
94
+ height: 720 // Different screen height
95
+ },
96
+ timezone: 'Europe/London', // Different timezone
97
+ };
98
+ const confidence = calculateConfidence(sampleData1, partialData);
99
+ console.log('Confidence for partially similar data:', confidence);
100
+ expect(confidence).toBeGreaterThan(10);
101
+ expect(confidence).toBeLessThan(95);
102
+ });
103
+ });
@@ -0,0 +1,106 @@
1
+ import { it, describe, expect } from 'vitest';
2
+ import { FPUserDataSet } from '../src/types/data';
3
+ import { getHash, compareHashes } from '../src/libs/tlsh';
4
+ import { randomString } from './tlsh.test';
5
+
6
+ const sampleData1: FPUserDataSet = {
7
+ fonts: ['Arial', 'Verdana'],
8
+ hardware: {
9
+ cpu: 'Intel Core i7',
10
+ gpu: 'NVIDIA GTX 1080',
11
+ ram: 16384 // in MB
12
+ },
13
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
14
+ screen: {
15
+ width: 1920,
16
+ height: 1080,
17
+ colorDepth: 24
18
+ },
19
+ timezone: 'America/New_York',
20
+ ip: '157.185.170.244',
21
+ languages: ['en-US', 'en'],
22
+ plugins: ['Chrome PDF Viewer', 'Shockwave Flash'],
23
+ canvasHash: getHash(randomString(524)),
24
+ audioHash: getHash(randomString(524)),
25
+ webglHash: getHash(randomString(524))
26
+ };
27
+
28
+ const sampleData2: FPUserDataSet = {
29
+ fonts: ['Arial', 'Verdana'],
30
+ hardware: {
31
+ cpu: 'Pentium 4',
32
+ gpu: 'Intel HD Graphics',
33
+ ram: 4096 // in MB
34
+ },
35
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
36
+ screen: {
37
+ width: 1280,
38
+ height: 720,
39
+ colorDepth: 24
40
+ },
41
+ timezone: 'Europe/London',
42
+ ip: '178.238.11.6',
43
+ languages: ['en-GB', 'en'],
44
+ plugins: ['Chrome PDF Viewer', 'Shockwave Flash'],
45
+ canvasHash: getHash(randomString(524)),
46
+ audioHash: getHash(randomString(524)),
47
+ webglHash: getHash(randomString(524))
48
+ };
49
+
50
+ describe('User Data Fingerprinting', () => {
51
+ it('should generate a hash for user data', () => {
52
+ const hash = getHash(JSON.stringify(sampleData1));
53
+ expect(typeof hash).toBe('string');
54
+ expect(hash.length).toBeGreaterThan(0);
55
+ });
56
+
57
+ it('should generate the same hash for identical user data', () => {
58
+ const hash1 = getHash(JSON.stringify(sampleData1));
59
+ const hash2 = getHash(JSON.stringify(sampleData1));
60
+ expect(hash1).toBe(hash2);
61
+ });
62
+
63
+ it('should generate different hashes for different user data', () => {
64
+ const hash1 = getHash(JSON.stringify(sampleData1));
65
+ const hash2 = getHash(JSON.stringify(sampleData2));
66
+ expect(hash1).not.toBe(hash2);
67
+ });
68
+
69
+ it('should compare hashes of identical user data and return 0 distance', () => {
70
+ const hash1 = getHash(JSON.stringify(sampleData1));
71
+ const hash2 = getHash(JSON.stringify(sampleData1));
72
+ const distance = compareHashes(hash1, hash2);
73
+ expect(distance).toBe(0);
74
+ });
75
+
76
+ it('should compare hashes of different user data and return a positive distance', () => {
77
+ const hash1 = getHash(JSON.stringify(sampleData1));
78
+ const hash2 = getHash(JSON.stringify(sampleData2));
79
+ const distance = compareHashes(hash1, hash2);
80
+ console.log('Distance between hashes:', distance);
81
+ expect(distance).toBeGreaterThan(0);
82
+ });
83
+
84
+ it('should compare similar user data and return a small distance', () => {
85
+ const modifiedData = { ...sampleData1, hardware: { ...sampleData1.hardware, ram: 8192 } }; // Slightly modified
86
+ const hash1 = getHash(JSON.stringify(sampleData1));
87
+ const hash2 = getHash(JSON.stringify(modifiedData));
88
+ const distance = compareHashes(hash1, hash2);
89
+ console.log('Distance between hashes:', distance);
90
+ expect(distance).toBeGreaterThan(0);
91
+ expect(distance).toBeLessThan(140); // Assuming small changes yield small distances
92
+ });
93
+
94
+ it('should compare very different user data and return a large distance', () => {
95
+ const hash1 = getHash(JSON.stringify(sampleData1));
96
+ const hash2 = getHash(JSON.stringify(sampleData2));
97
+ const distance = compareHashes(hash1, hash2);
98
+ console.log('Distance between hashes:', distance);
99
+ expect(distance).toBeGreaterThan(80); // Assuming significant differences yield larger distances
100
+ });
101
+
102
+ it('should handle invalid hash input gracefully', () => {
103
+ expect(() => compareHashes('invalidhash', 'anotherinvalid')).toThrow();
104
+ });
105
+ });
106
+ // This test suite verifies the functionality of user data fingerprinting using the TLSH hashing algorithm.
@@ -0,0 +1,70 @@
1
+ import { expect, describe, it } from 'vitest';
2
+ import { getHash, compareHashes } from '../src/libs/tlsh';
3
+
4
+ export function randomString(length: number): string {
5
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789[]{};!@#$%^&*()-_=+|;:",.<>?';
6
+ let result = '';
7
+ for (let i = 0; i < length; i++) {
8
+ result += characters.charAt(Math.floor(Math.random() * characters.length));
9
+ }
10
+ return result;
11
+ }
12
+
13
+ describe('tlsh library', () => {
14
+ it('should generate a non-empty hash for a string greater than 512 characters', () => {
15
+ const data = randomString(524);
16
+ const hash = getHash(data);
17
+ expect(typeof hash).toBe('string');
18
+ expect(hash.length).toBeGreaterThan(0);
19
+ });
20
+
21
+ it('should generate the same hash for the same string', () => {
22
+ const data = randomString(524);
23
+ const hash1 = getHash(data);
24
+ const hash2 = getHash(data);
25
+ expect(hash1).toBe(hash2);
26
+ });
27
+
28
+ it('should compare two identical hashes and return 0 distance', () => {
29
+ const data = randomString(524);
30
+ const hash1 = getHash(data);
31
+ const hash2 = getHash(data);
32
+ const distance = compareHashes(hash1, hash2);
33
+ expect(distance).toBe(0);
34
+ });
35
+
36
+ it('should compare two different hashes and return a positive distance', () => {
37
+ const data1 = randomString(524);
38
+ const data2 = randomString(524);
39
+ const hash1 = getHash(data1);
40
+ const hash2 = getHash(data2);
41
+ const distance = compareHashes(hash1, hash2);
42
+ expect(distance).toBeGreaterThanOrEqual(0);
43
+ });
44
+
45
+ it('should compare two similar hashes and return a small distance', () => {
46
+ const data = randomString(524);
47
+ const randomIndex = Math.floor(Math.random() * (data.length - 4));
48
+ const modifiedData = data.slice(0, randomIndex) + randomString(4) + data.slice(randomIndex + 4);
49
+ const hash1 = getHash(data);
50
+ const hash2 = getHash(modifiedData);
51
+ const distance = compareHashes(hash1, hash2);
52
+ console.log('Distance between hashes:', distance);
53
+ expect(distance).toBeGreaterThan(0);
54
+ expect(distance).toBeLessThan(200); // Assuming small changes yield small distances
55
+ });
56
+
57
+ it('should compare two very different hashes and return a large distance', () => {
58
+ const data1 = randomString(524);
59
+ const data2 = randomString(524);
60
+ const hash1 = getHash(data1);
61
+ const hash2 = getHash(data2);
62
+ const distance = compareHashes(hash1, hash2);
63
+ console.log('Distance between hashes:', distance);
64
+ expect(distance).toBeGreaterThan(180); // Assuming very different data yields larger distances
65
+ });
66
+
67
+ it('should throw or handle invalid hash input gracefully', () => {
68
+ expect(() => compareHashes('invalidhash', 'anotherinvalid')).toThrow();
69
+ });
70
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,114 @@
1
+ {
2
+ "compilerOptions": {
3
+ /* Visit https://aka.ms/tsconfig to read more about this file */
4
+
5
+ /* Projects */
6
+ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
7
+ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
8
+ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
9
+ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
10
+ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
11
+ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12
+
13
+ /* Language and Environment */
14
+ "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
15
+ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16
+ // "jsx": "preserve", /* Specify what JSX code is generated. */
17
+ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
18
+ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
19
+ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
20
+ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
21
+ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
22
+ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
23
+ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
24
+ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
25
+ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
26
+
27
+ /* Modules */
28
+ "module": "commonjs", /* Specify what module code is generated. */
29
+ // "rootDir": "./", /* Specify the root folder within your source files. */
30
+ // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
31
+ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
32
+ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
33
+ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
34
+ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
35
+ // "types": [], /* Specify type package names to be included without being referenced in a source file. */
36
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
37
+ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
38
+ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
39
+ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
40
+ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
41
+ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42
+ // "resolveJsonModule": true, /* Enable importing .json files. */
43
+ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
44
+ // "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
45
+
46
+ /* JavaScript Support */
47
+ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
48
+ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
49
+ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
50
+
51
+ /* Emit */
52
+ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
53
+ // "declarationMap": true, /* Create sourcemaps for d.ts files. */
54
+ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
55
+ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
56
+ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
57
+ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
58
+ // "outDir": "./", /* Specify an output folder for all emitted files. */
59
+ // "removeComments": true, /* Disable emitting comments. */
60
+ // "noEmit": false, /* Disable emitting files from a compilation. */
61
+ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
62
+ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
63
+ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
64
+ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
65
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
66
+ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
67
+ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
68
+ // "newLine": "crlf", /* Set the newline character for emitting files. */
69
+ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
70
+ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
71
+ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
72
+ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
73
+ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
74
+ // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
75
+
76
+ /* Interop Constraints */
77
+ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
78
+ // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
79
+ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
80
+ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
81
+ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
82
+ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
83
+
84
+ /* Type Checking */
85
+ "strict": true, /* Enable all strict type-checking options. */
86
+ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
87
+ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
88
+ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
89
+ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
90
+ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
91
+ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
92
+ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
93
+ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
94
+ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
95
+ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
96
+ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
97
+ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
98
+ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
99
+ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
100
+ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
101
+ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
102
+ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
103
+ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
104
+
105
+ /* Completeness */
106
+ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
107
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
108
+ },
109
+ "exclude": [
110
+ "node_modules",
111
+ "**/*.test.ts",
112
+ "**/*.config.ts"
113
+ ]
114
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ include: ['tests/**/*.test.ts'],
6
+ environment: 'node',
7
+ },
8
+ });