tsnite 0.1.0 → 0.1.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/dist/cache.js +47 -3
- package/dist/cli.js +95 -27
- package/dist/loader.js +100 -7
- package/dist/util.js +14 -0
- package/package.json +11 -12
package/dist/cache.js
CHANGED
|
@@ -1,17 +1,61 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { mkdir, rm, stat } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
2
4
|
export const resolveCache = new Map();
|
|
3
5
|
const statCache = new Map();
|
|
6
|
+
function getTranspileCacheDir() {
|
|
7
|
+
return path.join(process.cwd(), 'node_modules', '.cache', 'tsnite');
|
|
8
|
+
}
|
|
9
|
+
function getTSConfigPath() {
|
|
10
|
+
return path.join(process.cwd(), 'tsconfig.json');
|
|
11
|
+
}
|
|
12
|
+
function hash(value) {
|
|
13
|
+
return createHash('sha1').update(value).digest('hex');
|
|
14
|
+
}
|
|
4
15
|
export async function existsWithCache(filePath) {
|
|
5
16
|
const cached = statCache.get(filePath);
|
|
6
17
|
if (cached)
|
|
7
18
|
return cached.exists;
|
|
8
19
|
try {
|
|
9
20
|
const stats = await stat(filePath);
|
|
10
|
-
|
|
11
|
-
|
|
21
|
+
const exists = stats.isFile();
|
|
22
|
+
statCache.set(filePath, { exists, mtime: stats.mtimeMs });
|
|
23
|
+
return exists;
|
|
12
24
|
}
|
|
13
25
|
catch {
|
|
14
26
|
statCache.set(filePath, { exists: false });
|
|
15
27
|
return false;
|
|
16
28
|
}
|
|
17
29
|
}
|
|
30
|
+
export function clearResolveCache() {
|
|
31
|
+
resolveCache.clear();
|
|
32
|
+
}
|
|
33
|
+
export function invalidateStatCache(filePath) {
|
|
34
|
+
statCache.delete(filePath);
|
|
35
|
+
}
|
|
36
|
+
export function getTranspileCacheFile(filePath) {
|
|
37
|
+
return path.join(getTranspileCacheDir(), `${hash(filePath)}.json`);
|
|
38
|
+
}
|
|
39
|
+
export async function ensureTranspileCacheDir() {
|
|
40
|
+
await mkdir(getTranspileCacheDir(), { recursive: true });
|
|
41
|
+
}
|
|
42
|
+
export async function clearTranspileCache() {
|
|
43
|
+
await rm(getTranspileCacheDir(), { recursive: true, force: true });
|
|
44
|
+
}
|
|
45
|
+
export function isTSConfigPath(filePath) {
|
|
46
|
+
return path.resolve(filePath) === getTSConfigPath();
|
|
47
|
+
}
|
|
48
|
+
export async function invalidateFileCaches(filePath) {
|
|
49
|
+
invalidateStatCache(filePath);
|
|
50
|
+
clearResolveCache();
|
|
51
|
+
if (isTSConfigPath(filePath)) {
|
|
52
|
+
await clearTranspileCache();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
await rm(getTranspileCacheFile(filePath), { force: true });
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Ignore cache eviction failures during watch restarts.
|
|
60
|
+
}
|
|
61
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { program } from 'commander';
|
|
3
|
-
import { extname, join, relative } from 'node:path';
|
|
3
|
+
import { extname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
4
4
|
import { pathToFileURL } from 'node:url';
|
|
5
5
|
import { fork } from 'node:child_process';
|
|
6
6
|
import { watch } from 'chokidar';
|
|
7
7
|
import { name, description, version } from './metadata.js';
|
|
8
|
+
import { clearResolveCache, invalidateFileCaches } from './cache.js';
|
|
9
|
+
import { debounce, yellow } from './util.js';
|
|
8
10
|
const DEFAULT_INCLUDE_PATHS = ['.'];
|
|
9
11
|
const DEFAULT_EXCLUDE_PATHS = ['dist', 'build', 'coverage'];
|
|
10
12
|
const DEFAULT_WATCH_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx', 'json'];
|
|
11
13
|
const INTERNAL_IGNORED_PATHS = ['node_modules', '.git'];
|
|
12
|
-
const
|
|
14
|
+
const WATCH_DEBOUNCE_MS = 100;
|
|
15
|
+
const CHILD_EXIT_TIMEOUT_MS = 300;
|
|
16
|
+
const children = new Set();
|
|
13
17
|
program
|
|
14
18
|
.name(name)
|
|
15
19
|
.description(description)
|
|
16
20
|
.version(version, '-v, --version', 'Output the current version')
|
|
17
21
|
.showSuggestionAfterError();
|
|
18
|
-
function cleanup() {
|
|
19
|
-
|
|
22
|
+
function cleanup(signal) {
|
|
23
|
+
process.stdout.write(`${yellow(`Received ${signal}. Stopping watcher and child processes...`)}\n`);
|
|
24
|
+
for (const child of children.values()) {
|
|
20
25
|
try {
|
|
21
|
-
|
|
26
|
+
child.kill('SIGTERM');
|
|
22
27
|
}
|
|
23
28
|
catch {
|
|
24
29
|
//
|
|
@@ -26,10 +31,14 @@ function cleanup() {
|
|
|
26
31
|
}
|
|
27
32
|
process.exit(0);
|
|
28
33
|
}
|
|
29
|
-
process.on('SIGINT',
|
|
30
|
-
|
|
34
|
+
process.on('SIGINT', function () {
|
|
35
|
+
cleanup('SIGINT');
|
|
36
|
+
});
|
|
37
|
+
process.on('SIGTERM', function () {
|
|
38
|
+
cleanup('SIGTERM');
|
|
39
|
+
});
|
|
31
40
|
function spawn(entry, nodeArgs) {
|
|
32
|
-
const
|
|
41
|
+
const child = fork(join(process.cwd(), entry), {
|
|
33
42
|
stdio: 'inherit',
|
|
34
43
|
execArgv: [
|
|
35
44
|
'--enable-source-maps',
|
|
@@ -39,8 +48,25 @@ function spawn(entry, nodeArgs) {
|
|
|
39
48
|
...nodeArgs
|
|
40
49
|
]
|
|
41
50
|
});
|
|
42
|
-
|
|
43
|
-
|
|
51
|
+
children.add(child);
|
|
52
|
+
child.once('exit', function () {
|
|
53
|
+
children.delete(child);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
async function waitForChildExit(child) {
|
|
57
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
58
|
+
return true;
|
|
59
|
+
return await new Promise(function (resolve) {
|
|
60
|
+
const timeout = setTimeout(function () {
|
|
61
|
+
child.off('exit', handleExit);
|
|
62
|
+
resolve(false);
|
|
63
|
+
}, CHILD_EXIT_TIMEOUT_MS);
|
|
64
|
+
function handleExit() {
|
|
65
|
+
clearTimeout(timeout);
|
|
66
|
+
resolve(true);
|
|
67
|
+
}
|
|
68
|
+
child.once('exit', handleExit);
|
|
69
|
+
});
|
|
44
70
|
}
|
|
45
71
|
function normalizePath(value) {
|
|
46
72
|
return value
|
|
@@ -51,11 +77,25 @@ function normalizePath(value) {
|
|
|
51
77
|
function normalizeExt(value) {
|
|
52
78
|
return value.trim().replace(/^\./, '').toLowerCase();
|
|
53
79
|
}
|
|
80
|
+
function hasIgnoredSegment(filePath, ignoredSegments) {
|
|
81
|
+
let start = 0;
|
|
82
|
+
for (let index = 0; index <= filePath.length; index++) {
|
|
83
|
+
if (index !== filePath.length && filePath[index] !== '/')
|
|
84
|
+
continue;
|
|
85
|
+
if (ignoredSegments.has(filePath.slice(start, index)))
|
|
86
|
+
return true;
|
|
87
|
+
start = index + 1;
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
54
91
|
function createWatchConfig(options) {
|
|
55
92
|
const includePaths = options.include.map((value) => join(options.sourceRoot, value));
|
|
56
93
|
const excludePaths = options.exclude.map(normalizePath).filter(Boolean);
|
|
57
|
-
const
|
|
94
|
+
const excludedExactPaths = new Set(excludePaths);
|
|
95
|
+
const excludedSegments = new Set(excludePaths.filter((value) => !value.includes('/')));
|
|
96
|
+
const excludedPrefixes = excludePaths.map((value) => value + '/');
|
|
58
97
|
const allowedExts = new Set(options.ext.map(normalizeExt).filter(Boolean));
|
|
98
|
+
const internalIgnoredSegments = new Set(INTERNAL_IGNORED_PATHS);
|
|
59
99
|
function toRelativeFromRoot(sourceRoot, filePath) {
|
|
60
100
|
const rel = normalizePath(relative(sourceRoot, filePath));
|
|
61
101
|
return rel === '' ? '.' : rel;
|
|
@@ -66,14 +106,16 @@ function createWatchConfig(options) {
|
|
|
66
106
|
return true;
|
|
67
107
|
if (rel === '.')
|
|
68
108
|
return false;
|
|
69
|
-
|
|
70
|
-
if (segments.some((segment) => INTERNAL_IGNORED_PATHS.includes(segment)))
|
|
109
|
+
if (hasIgnoredSegment(rel, internalIgnoredSegments))
|
|
71
110
|
return true;
|
|
72
|
-
if (
|
|
111
|
+
if (hasIgnoredSegment(rel, excludedSegments))
|
|
73
112
|
return true;
|
|
74
|
-
|
|
75
|
-
if (isExcludedByPath)
|
|
113
|
+
if (excludedExactPaths.has(rel))
|
|
76
114
|
return true;
|
|
115
|
+
for (const excludedPrefix of excludedPrefixes) {
|
|
116
|
+
if (rel.startsWith(excludedPrefix))
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
77
119
|
if (!stats || stats.isDirectory())
|
|
78
120
|
return false;
|
|
79
121
|
const extension = extname(rel).slice(1).toLowerCase();
|
|
@@ -88,7 +130,37 @@ function createWatchConfig(options) {
|
|
|
88
130
|
};
|
|
89
131
|
}
|
|
90
132
|
async function handler(entry, options, nodeArgs, isWatch) {
|
|
133
|
+
async function restart(reason) {
|
|
134
|
+
process.stdout.write('\x1Bc');
|
|
135
|
+
if (reason) {
|
|
136
|
+
console.log(yellow(reason));
|
|
137
|
+
}
|
|
138
|
+
for (const child of children.values()) {
|
|
139
|
+
try {
|
|
140
|
+
child.kill('SIGTERM');
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const exited = await waitForChildExit(child);
|
|
146
|
+
if (exited)
|
|
147
|
+
continue;
|
|
148
|
+
console.log(yellow(`${reason ?? 'Restart requested.'} Process hasn't exited. Killing process...`));
|
|
149
|
+
try {
|
|
150
|
+
child.kill('SIGKILL');
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
//
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
clearResolveCache();
|
|
157
|
+
spawn(entry, nodeArgs);
|
|
158
|
+
}
|
|
159
|
+
const restartDebounced = debounce(restart, WATCH_DEBOUNCE_MS);
|
|
91
160
|
process.stdout.write('\x1Bc');
|
|
161
|
+
if (isWatch) {
|
|
162
|
+
console.log(yellow('Watching for changes...'));
|
|
163
|
+
}
|
|
92
164
|
spawn(entry, nodeArgs);
|
|
93
165
|
if (!isWatch)
|
|
94
166
|
return;
|
|
@@ -98,18 +170,14 @@ async function handler(entry, options, nodeArgs, isWatch) {
|
|
|
98
170
|
ignoreInitial: true,
|
|
99
171
|
ignored
|
|
100
172
|
});
|
|
101
|
-
watcher.on('
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
//
|
|
109
|
-
}
|
|
173
|
+
watcher.on('all', async function (eventName, changedPath) {
|
|
174
|
+
if (eventName !== 'change' &&
|
|
175
|
+
eventName !== 'add' &&
|
|
176
|
+
eventName !== 'unlink') {
|
|
177
|
+
return;
|
|
110
178
|
}
|
|
111
|
-
|
|
112
|
-
|
|
179
|
+
await invalidateFileCaches(isAbsolute(changedPath) ? changedPath : (resolve(process.cwd(), changedPath)));
|
|
180
|
+
restartDebounced(`Change detected (${eventName}): ${changedPath}`);
|
|
113
181
|
});
|
|
114
182
|
}
|
|
115
183
|
function parseCsv(value) {
|
package/dist/loader.js
CHANGED
|
@@ -1,19 +1,81 @@
|
|
|
1
1
|
import { transformFile } from '@swc/core';
|
|
2
2
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
3
|
-
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { readFile, stat, writeFile } from 'node:fs/promises';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
+
import { createHash } from 'node:crypto';
|
|
5
6
|
import { parse } from './parse.js';
|
|
6
|
-
import {
|
|
7
|
+
import { clearTranspileCache, ensureTranspileCacheDir, existsWithCache, getTranspileCacheFile, resolveCache } from './cache.js';
|
|
7
8
|
const tsconfigCache = { paths: null, baseUrl: null };
|
|
9
|
+
const transpileCache = new Map();
|
|
10
|
+
const MAX_TRANSPILE_CACHE_ENTRIES = 256;
|
|
11
|
+
const TS_SOURCE_RE = /\.(cts|mts|tsx|ts)$/;
|
|
12
|
+
function hash(value) {
|
|
13
|
+
return createHash('sha1').update(value).digest('hex');
|
|
14
|
+
}
|
|
15
|
+
function getMemoryCachedTranspile(filename, mtimeMs, size, configHash) {
|
|
16
|
+
const memoryCached = transpileCache.get(filename);
|
|
17
|
+
if (!memoryCached ||
|
|
18
|
+
memoryCached.mtimeMs !== mtimeMs ||
|
|
19
|
+
memoryCached.size !== size ||
|
|
20
|
+
memoryCached.configHash !== configHash) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
transpileCache.delete(filename);
|
|
24
|
+
transpileCache.set(filename, memoryCached);
|
|
25
|
+
return memoryCached.code;
|
|
26
|
+
}
|
|
27
|
+
function setMemoryCachedTranspile(filename, entry) {
|
|
28
|
+
if (transpileCache.has(filename)) {
|
|
29
|
+
transpileCache.delete(filename);
|
|
30
|
+
}
|
|
31
|
+
transpileCache.set(filename, entry);
|
|
32
|
+
if (transpileCache.size <= MAX_TRANSPILE_CACHE_ENTRIES)
|
|
33
|
+
return;
|
|
34
|
+
const oldestKey = transpileCache.keys().next().value;
|
|
35
|
+
if (oldestKey)
|
|
36
|
+
transpileCache.delete(oldestKey);
|
|
37
|
+
}
|
|
38
|
+
async function readCachedTranspile(filename, mtimeMs, size, configHash) {
|
|
39
|
+
const memoryCached = getMemoryCachedTranspile(filename, mtimeMs, size, configHash);
|
|
40
|
+
if (memoryCached !== null)
|
|
41
|
+
return memoryCached;
|
|
42
|
+
try {
|
|
43
|
+
const raw = await readFile(getTranspileCacheFile(filename), 'utf8');
|
|
44
|
+
const diskCached = JSON.parse(raw);
|
|
45
|
+
if (diskCached.mtimeMs !== mtimeMs ||
|
|
46
|
+
diskCached.size !== size ||
|
|
47
|
+
diskCached.configHash !== configHash) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
setMemoryCachedTranspile(filename, diskCached);
|
|
51
|
+
return diskCached.code;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function writeCachedTranspile(filename, entry) {
|
|
58
|
+
setMemoryCachedTranspile(filename, entry);
|
|
59
|
+
try {
|
|
60
|
+
await ensureTranspileCacheDir();
|
|
61
|
+
await writeFile(getTranspileCacheFile(filename), JSON.stringify(entry));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Ignore cache write failures and continue with fresh output.
|
|
65
|
+
}
|
|
66
|
+
}
|
|
8
67
|
async function loadTSConfig() {
|
|
9
68
|
if (tsconfigCache.paths !== null && tsconfigCache.baseUrl !== null) {
|
|
10
69
|
return tsconfigCache;
|
|
11
70
|
}
|
|
12
71
|
try {
|
|
13
72
|
const data = await readFile(path.join(process.cwd(), 'tsconfig.json'), 'utf-8');
|
|
14
|
-
const { compilerOptions
|
|
73
|
+
const { compilerOptions } = parse(data);
|
|
74
|
+
const paths = compilerOptions?.paths ?? null;
|
|
75
|
+
const baseUrl = compilerOptions?.baseUrl;
|
|
15
76
|
tsconfigCache.paths = paths || null;
|
|
16
|
-
tsconfigCache.baseUrl =
|
|
77
|
+
tsconfigCache.baseUrl =
|
|
78
|
+
baseUrl ? path.resolve(process.cwd(), baseUrl) : process.cwd();
|
|
17
79
|
return tsconfigCache;
|
|
18
80
|
}
|
|
19
81
|
catch {
|
|
@@ -28,7 +90,10 @@ export async function resolve(specifier, ctx, next) {
|
|
|
28
90
|
}
|
|
29
91
|
const cacheKey = `${ctx.parentURL}::${specifier}`;
|
|
30
92
|
const cached = resolveCache.get(cacheKey);
|
|
31
|
-
if (cached) {
|
|
93
|
+
if (cached !== undefined) {
|
|
94
|
+
if (cached === null) {
|
|
95
|
+
return next(specifier, ctx);
|
|
96
|
+
}
|
|
32
97
|
return {
|
|
33
98
|
url: cached,
|
|
34
99
|
format: 'module',
|
|
@@ -42,12 +107,18 @@ export async function resolve(specifier, ctx, next) {
|
|
|
42
107
|
basePath,
|
|
43
108
|
basePath + '.ts',
|
|
44
109
|
basePath + '.tsx',
|
|
110
|
+
basePath + '.mts',
|
|
111
|
+
basePath + '.cts',
|
|
45
112
|
basePath + '.js',
|
|
46
113
|
basePath + '.mjs',
|
|
114
|
+
basePath + '.cjs',
|
|
47
115
|
path.join(basePath, 'index.ts'),
|
|
48
116
|
path.join(basePath, 'index.tsx'),
|
|
117
|
+
path.join(basePath, 'index.mts'),
|
|
118
|
+
path.join(basePath, 'index.cts'),
|
|
49
119
|
path.join(basePath, 'index.js'),
|
|
50
|
-
path.join(basePath, 'index.mjs')
|
|
120
|
+
path.join(basePath, 'index.mjs'),
|
|
121
|
+
path.join(basePath, 'index.cjs')
|
|
51
122
|
];
|
|
52
123
|
for (const file of tryFiles) {
|
|
53
124
|
if (await existsWithCache(file)) {
|
|
@@ -60,14 +131,21 @@ export async function resolve(specifier, ctx, next) {
|
|
|
60
131
|
};
|
|
61
132
|
}
|
|
62
133
|
}
|
|
134
|
+
resolveCache.set(cacheKey, null);
|
|
63
135
|
return next(specifier, ctx);
|
|
64
136
|
}
|
|
65
137
|
export async function load(url, ctx, next) {
|
|
66
|
-
if (!url.startsWith('file://') || !
|
|
138
|
+
if (!url.startsWith('file://') || !TS_SOURCE_RE.test(url)) {
|
|
67
139
|
return next(url, ctx);
|
|
68
140
|
}
|
|
69
141
|
const { paths, baseUrl } = await loadTSConfig();
|
|
70
142
|
const filename = fileURLToPath(url);
|
|
143
|
+
const fileStats = await stat(filename);
|
|
144
|
+
const configHash = hash(JSON.stringify({ baseUrl: baseUrl || process.cwd(), paths: paths ?? {} }));
|
|
145
|
+
const cachedCode = await readCachedTranspile(filename, fileStats.mtimeMs, fileStats.size, configHash);
|
|
146
|
+
if (cachedCode !== null) {
|
|
147
|
+
return { format: 'module', source: cachedCode, shortCircuit: true };
|
|
148
|
+
}
|
|
71
149
|
const { code } = await transformFile(filename, {
|
|
72
150
|
filename,
|
|
73
151
|
jsc: {
|
|
@@ -100,5 +178,20 @@ export async function load(url, ctx, next) {
|
|
|
100
178
|
},
|
|
101
179
|
sourceMaps: 'inline'
|
|
102
180
|
});
|
|
181
|
+
await writeCachedTranspile(filename, {
|
|
182
|
+
code,
|
|
183
|
+
mtimeMs: fileStats.mtimeMs,
|
|
184
|
+
size: fileStats.size,
|
|
185
|
+
configHash
|
|
186
|
+
});
|
|
103
187
|
return { format: 'module', source: code, shortCircuit: true };
|
|
104
188
|
}
|
|
189
|
+
export async function resetLoaderState(options) {
|
|
190
|
+
tsconfigCache.paths = null;
|
|
191
|
+
tsconfigCache.baseUrl = null;
|
|
192
|
+
transpileCache.clear();
|
|
193
|
+
resolveCache.clear();
|
|
194
|
+
if (!options?.preserveTranspileCache) {
|
|
195
|
+
await clearTranspileCache();
|
|
196
|
+
}
|
|
197
|
+
}
|
package/dist/util.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function debounce(callback, waitMs) {
|
|
2
|
+
let timer;
|
|
3
|
+
return function (...args) {
|
|
4
|
+
if (timer)
|
|
5
|
+
clearTimeout(timer);
|
|
6
|
+
timer = setTimeout(() => callback(...args), waitMs);
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function color(code, value) {
|
|
10
|
+
return `\u001B[${code}m${value}\u001B[0m`;
|
|
11
|
+
}
|
|
12
|
+
export function yellow(value) {
|
|
13
|
+
return color(33, value);
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tsnite",
|
|
3
3
|
"description": "TypeScript at full throttle—fast, safe, unstoppable. 🚀",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.1",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
7
7
|
"esm",
|
|
@@ -32,30 +32,29 @@
|
|
|
32
32
|
"prepare": "husky"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@swc/core": "^1.15.
|
|
35
|
+
"@swc/core": "^1.15.24",
|
|
36
36
|
"chokidar": "^5.0.0",
|
|
37
37
|
"commander": "^14.0.3"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@commitlint/cli": "^20.
|
|
41
|
-
"@commitlint/config-conventional": "^20.
|
|
40
|
+
"@commitlint/cli": "^20.5.0",
|
|
41
|
+
"@commitlint/config-conventional": "^20.5.0",
|
|
42
42
|
"@eslint/js": "^10.0.1",
|
|
43
43
|
"@jest/globals": "^30.3.0",
|
|
44
44
|
"@swc/jest": "^0.2.39",
|
|
45
|
-
"eslint": "^10.0
|
|
46
|
-
"eslint-plugin-jest": "^29.15.
|
|
45
|
+
"eslint": "^10.2.0",
|
|
46
|
+
"eslint-plugin-jest": "^29.15.2",
|
|
47
47
|
"eslint-plugin-prettier": "^5.5.5",
|
|
48
|
-
"globals": "^17.
|
|
48
|
+
"globals": "^17.5.0",
|
|
49
49
|
"husky": "^9.1.7",
|
|
50
50
|
"jest": "^30.3.0",
|
|
51
51
|
"jest-environment-node": "^30.3.0",
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"prettier": "^3.8.1",
|
|
52
|
+
"lint-staged": "^16.4.0",
|
|
53
|
+
"prettier": "^3.8.2",
|
|
55
54
|
"rimraf": "^6.1.3",
|
|
56
55
|
"tsc-alias": "^1.8.16",
|
|
57
|
-
"typescript": "^
|
|
58
|
-
"typescript-eslint": "^8.
|
|
56
|
+
"typescript": "^6.0.2",
|
|
57
|
+
"typescript-eslint": "^8.58.1"
|
|
59
58
|
},
|
|
60
59
|
"engines": {
|
|
61
60
|
"node": "^20.9.0 || ^22.11.0 || ^24.11.0"
|