@ripeseed/rs-tunnel 0.1.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.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -0
  3. package/dist/commands/doctor.d.ts +1 -0
  4. package/dist/commands/doctor.js +20 -0
  5. package/dist/commands/doctor.js.map +1 -0
  6. package/dist/commands/list.d.ts +1 -0
  7. package/dist/commands/list.js +18 -0
  8. package/dist/commands/list.js.map +1 -0
  9. package/dist/commands/login.d.ts +1 -0
  10. package/dist/commands/login.js +45 -0
  11. package/dist/commands/login.js.map +1 -0
  12. package/dist/commands/logout.d.ts +1 -0
  13. package/dist/commands/logout.js +19 -0
  14. package/dist/commands/logout.js.map +1 -0
  15. package/dist/commands/stop.d.ts +1 -0
  16. package/dist/commands/stop.js +15 -0
  17. package/dist/commands/stop.js.map +1 -0
  18. package/dist/commands/up.d.ts +32 -0
  19. package/dist/commands/up.js +319 -0
  20. package/dist/commands/up.js.map +1 -0
  21. package/dist/commands/up.test.d.ts +1 -0
  22. package/dist/commands/up.test.js +467 -0
  23. package/dist/commands/up.test.js.map +1 -0
  24. package/dist/config.d.ts +10 -0
  25. package/dist/config.js +135 -0
  26. package/dist/config.js.map +1 -0
  27. package/dist/config.test.d.ts +1 -0
  28. package/dist/config.test.js +67 -0
  29. package/dist/config.test.js.map +1 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.js +75 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/lib/api-client.d.ts +73 -0
  34. package/dist/lib/api-client.js +146 -0
  35. package/dist/lib/api-client.js.map +1 -0
  36. package/dist/lib/cloudflared.d.ts +3 -0
  37. package/dist/lib/cloudflared.js +165 -0
  38. package/dist/lib/cloudflared.js.map +1 -0
  39. package/dist/lib/local-callback.d.ts +9 -0
  40. package/dist/lib/local-callback.js +68 -0
  41. package/dist/lib/local-callback.js.map +1 -0
  42. package/dist/lib/local-proxy.d.ts +27 -0
  43. package/dist/lib/local-proxy.js +200 -0
  44. package/dist/lib/local-proxy.js.map +1 -0
  45. package/dist/lib/local-proxy.test.d.ts +1 -0
  46. package/dist/lib/local-proxy.test.js +181 -0
  47. package/dist/lib/local-proxy.test.js.map +1 -0
  48. package/dist/lib/pkce.d.ts +4 -0
  49. package/dist/lib/pkce.js +10 -0
  50. package/dist/lib/pkce.js.map +1 -0
  51. package/dist/lib/session.d.ts +4 -0
  52. package/dist/lib/session.js +47 -0
  53. package/dist/lib/session.js.map +1 -0
  54. package/dist/lib/tunnel-stats.d.ts +19 -0
  55. package/dist/lib/tunnel-stats.js +75 -0
  56. package/dist/lib/tunnel-stats.js.map +1 -0
  57. package/dist/lib/tunnel-stats.test.d.ts +1 -0
  58. package/dist/lib/tunnel-stats.test.js +44 -0
  59. package/dist/lib/tunnel-stats.test.js.map +1 -0
  60. package/dist/lib/up-dashboard.d.ts +19 -0
  61. package/dist/lib/up-dashboard.js +170 -0
  62. package/dist/lib/up-dashboard.js.map +1 -0
  63. package/dist/lib/version.d.ts +1 -0
  64. package/dist/lib/version.js +18 -0
  65. package/dist/lib/version.js.map +1 -0
  66. package/dist/store/credentials.d.ts +4 -0
  67. package/dist/store/credentials.js +99 -0
  68. package/dist/store/credentials.js.map +1 -0
  69. package/dist/types.d.ts +10 -0
  70. package/dist/types.js +2 -0
  71. package/dist/types.js.map +1 -0
  72. package/package.json +51 -0
@@ -0,0 +1,44 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { TunnelStats } from './tunnel-stats.js';
3
+ describe('TunnelStats', () => {
4
+ it('returns n/a metrics as null when no requests are recorded', () => {
5
+ const stats = new TunnelStats();
6
+ stats.updateConnections({ totalConnections: 0, openConnections: 0 });
7
+ const snapshot = stats.getSnapshot(1000);
8
+ expect(snapshot.ttl).toBe(0);
9
+ expect(snapshot.opn).toBe(0);
10
+ expect(snapshot.rt1Ms).toBeNull();
11
+ expect(snapshot.rt5Ms).toBeNull();
12
+ expect(snapshot.p50Ms).toBeNull();
13
+ expect(snapshot.p90Ms).toBeNull();
14
+ });
15
+ it('evicts old samples from rolling windows', () => {
16
+ const stats = new TunnelStats();
17
+ stats.updateConnections({ totalConnections: 5, openConnections: 1 });
18
+ stats.recordRequest({ startedAtEpochMs: 0, durationMs: 5 });
19
+ stats.recordRequest({ startedAtEpochMs: 240_000, durationMs: 40 });
20
+ const beforeFiveMinuteCutoff = stats.getSnapshot(300_000);
21
+ expect(beforeFiveMinuteCutoff.ttl).toBe(5);
22
+ expect(beforeFiveMinuteCutoff.opn).toBe(1);
23
+ expect(beforeFiveMinuteCutoff.rt1Ms).toBe(40);
24
+ expect(beforeFiveMinuteCutoff.rt5Ms).toBe(22.5);
25
+ const afterFiveMinuteCutoff = stats.getSnapshot(300_001);
26
+ expect(afterFiveMinuteCutoff.rt1Ms).toBeNull();
27
+ expect(afterFiveMinuteCutoff.rt5Ms).toBe(40);
28
+ expect(afterFiveMinuteCutoff.p50Ms).toBe(40);
29
+ expect(afterFiveMinuteCutoff.p90Ms).toBe(40);
30
+ });
31
+ it('calculates rt1, rt5, p50, and p90 deterministically', () => {
32
+ const stats = new TunnelStats();
33
+ const durations = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
34
+ for (const durationMs of durations) {
35
+ stats.recordRequest({ startedAtEpochMs: 10_000, durationMs });
36
+ }
37
+ const snapshot = stats.getSnapshot(10_500);
38
+ expect(snapshot.rt1Ms).toBe(55);
39
+ expect(snapshot.rt5Ms).toBe(55);
40
+ expect(snapshot.p50Ms).toBe(50);
41
+ expect(snapshot.p90Ms).toBe(90);
42
+ });
43
+ });
44
+ //# sourceMappingURL=tunnel-stats.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-stats.test.js","sourceRoot":"","sources":["../../src/lib/tunnel-stats.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { ProxyRequestEvent } from './local-proxy.js';
2
+ import type { TunnelStatsSnapshot } from './tunnel-stats.js';
3
+ export type UpDashboard = {
4
+ setRegion: (region: string | null) => void;
5
+ setMetrics: (metrics: TunnelStatsSnapshot) => void;
6
+ addRequest: (event: ProxyRequestEvent) => void;
7
+ addCloudflaredLine: (line: string) => void;
8
+ addMessage: (line: string) => void;
9
+ stop: () => void;
10
+ };
11
+ type CreateUpDashboardInput = {
12
+ account: string;
13
+ version: string;
14
+ forwarding: string;
15
+ verbose: boolean;
16
+ stdout?: NodeJS.WriteStream;
17
+ };
18
+ export declare function createUpDashboard(input: CreateUpDashboardInput): UpDashboard;
19
+ export {};
@@ -0,0 +1,170 @@
1
+ import http from 'node:http';
2
+ const HEADER_DIVIDER = '------------';
3
+ const MAX_LOG_LINES = 120;
4
+ function formatTimestamp(epochMs) {
5
+ const date = new Date(epochMs);
6
+ const hours = String(date.getHours()).padStart(2, '0');
7
+ const minutes = String(date.getMinutes()).padStart(2, '0');
8
+ const seconds = String(date.getSeconds()).padStart(2, '0');
9
+ const millis = String(date.getMilliseconds()).padStart(3, '0');
10
+ return `${hours}:${minutes}:${seconds}.${millis}`;
11
+ }
12
+ function formatMetric(ms) {
13
+ if (ms === null) {
14
+ return 'n/a';
15
+ }
16
+ return `${Math.round(ms)}ms`;
17
+ }
18
+ function formatStatus(event) {
19
+ const statusText = event.statusMessage || http.STATUS_CODES[event.statusCode] || '';
20
+ const text = `${event.statusCode} ${statusText}`.trim();
21
+ return text.length > 0 ? text : String(event.statusCode);
22
+ }
23
+ function truncate(value, width) {
24
+ if (value.length <= width) {
25
+ return value.padEnd(width, ' ');
26
+ }
27
+ if (width <= 3) {
28
+ return value.slice(0, width);
29
+ }
30
+ return `${value.slice(0, width - 3)}...`;
31
+ }
32
+ function formatRequestLine(event, width) {
33
+ const timestamp = formatTimestamp(event.startedAtEpochMs);
34
+ const method = (event.protocol === 'ws' ? 'WS' : event.method.toUpperCase()).padEnd(6, ' ');
35
+ const pathWidth = Math.max(16, Math.min(48, width - 44));
36
+ const path = truncate(event.path, pathWidth);
37
+ const status = formatStatus(event);
38
+ return `${timestamp} PKT ${method} ${path} ${status}`;
39
+ }
40
+ function formatConnectionRow(metrics) {
41
+ const columns = [
42
+ String(metrics.ttl).padStart(7, ' '),
43
+ String(metrics.opn).padStart(7, ' '),
44
+ formatMetric(metrics.rt1Ms).padStart(7, ' '),
45
+ formatMetric(metrics.rt5Ms).padStart(7, ' '),
46
+ formatMetric(metrics.p50Ms).padStart(7, ' '),
47
+ formatMetric(metrics.p90Ms).padStart(7, ' '),
48
+ ];
49
+ return `Connections ttl opn rt1 rt5 p50 p90\n ${columns.join('')}`;
50
+ }
51
+ function buildHeader(input) {
52
+ return [
53
+ `Account ${input.account}`,
54
+ `Version rs-tunnel ${input.version}`,
55
+ `Region ${input.region}`,
56
+ `Latency ${input.latency}`,
57
+ `Forwarding ${input.forwarding}`,
58
+ '',
59
+ formatConnectionRow(input.metrics),
60
+ '',
61
+ 'HTTP Requests',
62
+ HEADER_DIVIDER,
63
+ ].join('\n');
64
+ }
65
+ export function createUpDashboard(input) {
66
+ const stdout = input.stdout ?? process.stdout;
67
+ const isTty = Boolean(stdout.isTTY);
68
+ let region = 'n/a';
69
+ let metrics = {
70
+ ttl: 0,
71
+ opn: 0,
72
+ rt1Ms: null,
73
+ rt5Ms: null,
74
+ p50Ms: null,
75
+ p90Ms: null,
76
+ };
77
+ const logLines = [];
78
+ let lastNonTtyMetricsAt = 0;
79
+ const appendLogLine = (line) => {
80
+ logLines.push(line);
81
+ if (logLines.length > MAX_LOG_LINES) {
82
+ logLines.shift();
83
+ }
84
+ if (!isTty) {
85
+ stdout.write(`${line}\n`);
86
+ }
87
+ };
88
+ const render = () => {
89
+ if (!isTty) {
90
+ return;
91
+ }
92
+ const columns = stdout.columns ?? 100;
93
+ const requestLines = logLines.map((line) => truncate(line, Math.max(30, columns - 1))).join('\n');
94
+ const latency = formatMetric(metrics.rt1Ms);
95
+ const body = [
96
+ buildHeader({
97
+ account: input.account,
98
+ version: input.version,
99
+ region,
100
+ latency,
101
+ forwarding: input.forwarding,
102
+ metrics,
103
+ }),
104
+ requestLines,
105
+ ]
106
+ .filter((section) => section.length > 0)
107
+ .join('\n');
108
+ stdout.write('\x1b[2J\x1b[H');
109
+ stdout.write(body);
110
+ stdout.write('\n');
111
+ };
112
+ if (!isTty) {
113
+ const header = buildHeader({
114
+ account: input.account,
115
+ version: input.version,
116
+ region,
117
+ latency: formatMetric(metrics.rt1Ms),
118
+ forwarding: input.forwarding,
119
+ metrics,
120
+ });
121
+ stdout.write(`${header}\n`);
122
+ }
123
+ const renderInterval = isTty ? setInterval(render, 300) : null;
124
+ if (renderInterval) {
125
+ render();
126
+ }
127
+ return {
128
+ setRegion: (nextRegion) => {
129
+ const normalized = nextRegion && nextRegion.trim().length > 0 ? nextRegion.trim() : 'n/a';
130
+ if (normalized === region) {
131
+ return;
132
+ }
133
+ region = normalized;
134
+ if (!isTty) {
135
+ stdout.write(`Region ${region}\n`);
136
+ }
137
+ },
138
+ setMetrics: (nextMetrics) => {
139
+ metrics = nextMetrics;
140
+ if (!isTty) {
141
+ const now = Date.now();
142
+ if (now - lastNonTtyMetricsAt >= 5_000) {
143
+ lastNonTtyMetricsAt = now;
144
+ stdout.write(`${formatConnectionRow(metrics)}\n`);
145
+ }
146
+ }
147
+ },
148
+ addRequest: (event) => {
149
+ appendLogLine(formatRequestLine(event, stdout.columns ?? 100));
150
+ },
151
+ addCloudflaredLine: (line) => {
152
+ if (!input.verbose) {
153
+ return;
154
+ }
155
+ appendLogLine(`[cloudflared] ${line}`);
156
+ },
157
+ addMessage: (line) => {
158
+ appendLogLine(`[info] ${line}`);
159
+ },
160
+ stop: () => {
161
+ if (renderInterval) {
162
+ clearInterval(renderInterval);
163
+ }
164
+ if (isTty) {
165
+ render();
166
+ }
167
+ },
168
+ };
169
+ }
170
+ //# sourceMappingURL=up-dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"up-dashboard.js","sourceRoot":"","sources":["../../src/lib/up-dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function getCliVersion(): string;
@@ -0,0 +1,18 @@
1
+ import fs from 'node:fs';
2
+ let cachedVersion = null;
3
+ export function getCliVersion() {
4
+ if (cachedVersion) {
5
+ return cachedVersion;
6
+ }
7
+ try {
8
+ const packageJsonUrl = new URL('../../package.json', import.meta.url);
9
+ const packageJsonRaw = fs.readFileSync(packageJsonUrl, 'utf8');
10
+ const packageJson = JSON.parse(packageJsonRaw);
11
+ cachedVersion = typeof packageJson.version === 'string' && packageJson.version.length > 0 ? packageJson.version : 'unknown';
12
+ }
13
+ catch {
14
+ cachedVersion = 'unknown';
15
+ }
16
+ return cachedVersion;
17
+ }
18
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/lib/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,IAAI,aAAa,GAAkB,IAAI,CAAC;AAExC,MAAM,UAAU,aAAa;IAC3B,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtE,MAAM,cAAc,GAAG,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAA0B,CAAC;QACxE,aAAa,GAAG,OAAO,WAAW,CAAC,OAAO,KAAK,QAAQ,IAAI,WAAW,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9H,CAAC;IAAC,MAAM,CAAC;QACP,aAAa,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { StoredSession } from '../types.js';
2
+ export declare function saveSession(session: StoredSession): Promise<void>;
3
+ export declare function loadSession(): Promise<StoredSession | null>;
4
+ export declare function clearSession(): Promise<void>;
@@ -0,0 +1,99 @@
1
+ import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
2
+ import fs from 'node:fs/promises';
3
+ import { getCliHomeDir, getFallbackKeyPath, getFallbackSessionPath } from '../config.js';
4
+ const KEYTAR_SERVICE = 'rs-tunnel';
5
+ const KEYTAR_ACCOUNT = 'default';
6
+ async function loadKeytar() {
7
+ try {
8
+ const keytar = await import('keytar');
9
+ return keytar.default;
10
+ }
11
+ catch {
12
+ return undefined;
13
+ }
14
+ }
15
+ async function ensureDir() {
16
+ await fs.mkdir(getCliHomeDir(), { recursive: true, mode: 0o700 });
17
+ }
18
+ async function getOrCreateFileKey() {
19
+ await ensureDir();
20
+ const keyPath = getFallbackKeyPath();
21
+ try {
22
+ const existing = await fs.readFile(keyPath, 'utf8');
23
+ return Buffer.from(existing.trim(), 'base64');
24
+ }
25
+ catch {
26
+ const key = randomBytes(32);
27
+ await fs.writeFile(keyPath, key.toString('base64'), { mode: 0o600 });
28
+ return key;
29
+ }
30
+ }
31
+ function encrypt(plaintext, key) {
32
+ const iv = randomBytes(12);
33
+ const cipher = createCipheriv('aes-256-gcm', key, iv);
34
+ const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
35
+ const tag = cipher.getAuthTag();
36
+ return JSON.stringify({
37
+ iv: iv.toString('base64'),
38
+ tag: tag.toString('base64'),
39
+ data: encrypted.toString('base64'),
40
+ });
41
+ }
42
+ function decrypt(payload, key) {
43
+ const parsed = JSON.parse(payload);
44
+ const decipher = createDecipheriv('aes-256-gcm', key, Buffer.from(parsed.iv, 'base64'));
45
+ decipher.setAuthTag(Buffer.from(parsed.tag, 'base64'));
46
+ const decrypted = Buffer.concat([
47
+ decipher.update(Buffer.from(parsed.data, 'base64')),
48
+ decipher.final(),
49
+ ]);
50
+ return decrypted.toString('utf8');
51
+ }
52
+ async function writeFallbackSession(session) {
53
+ await ensureDir();
54
+ const key = await getOrCreateFileKey();
55
+ const encrypted = encrypt(JSON.stringify(session), key);
56
+ await fs.writeFile(getFallbackSessionPath(), encrypted, { mode: 0o600 });
57
+ }
58
+ async function readFallbackSession() {
59
+ try {
60
+ const key = await getOrCreateFileKey();
61
+ const encrypted = await fs.readFile(getFallbackSessionPath(), 'utf8');
62
+ const decrypted = decrypt(encrypted, key);
63
+ return JSON.parse(decrypted);
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ }
69
+ async function deleteFallbackSession() {
70
+ await fs.rm(getFallbackSessionPath(), { force: true });
71
+ }
72
+ export async function saveSession(session) {
73
+ const keytar = await loadKeytar();
74
+ if (keytar) {
75
+ await keytar.setPassword(KEYTAR_SERVICE, KEYTAR_ACCOUNT, JSON.stringify(session));
76
+ return;
77
+ }
78
+ await writeFallbackSession(session);
79
+ }
80
+ export async function loadSession() {
81
+ const keytar = await loadKeytar();
82
+ if (keytar) {
83
+ const raw = await keytar.getPassword(KEYTAR_SERVICE, KEYTAR_ACCOUNT);
84
+ if (!raw) {
85
+ return null;
86
+ }
87
+ return JSON.parse(raw);
88
+ }
89
+ return readFallbackSession();
90
+ }
91
+ export async function clearSession() {
92
+ const keytar = await loadKeytar();
93
+ if (keytar) {
94
+ await keytar.deletePassword(KEYTAR_SERVICE, KEYTAR_ACCOUNT);
95
+ return;
96
+ }
97
+ await deleteFallbackSession();
98
+ }
99
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/store/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { UserProfile } from '@ripeseed/shared';
2
+ export type StoredSession = {
3
+ accessToken: string;
4
+ refreshToken: string;
5
+ expiresAtEpochSec: number;
6
+ profile: UserProfile;
7
+ };
8
+ export type CliConfig = {
9
+ apiBaseUrl: string;
10
+ };
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@ripeseed/rs-tunnel",
3
+ "version": "0.1.2",
4
+ "description": "CLI for running secure public tunnels to localhost through Cloudflare.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/RipeSeed/rs-tunnel.git",
9
+ "directory": "apps/cli"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/RipeSeed/rs-tunnel/issues"
13
+ },
14
+ "homepage": "https://github.com/RipeSeed/rs-tunnel/tree/main/apps/cli",
15
+ "type": "module",
16
+ "main": "dist/index.js",
17
+ "types": "dist/index.d.ts",
18
+ "bin": {
19
+ "rs-tunnel": "dist/index.js"
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "publishConfig": {
25
+ "registry": "https://registry.npmjs.org/",
26
+ "access": "public"
27
+ },
28
+ "dependencies": {
29
+ "commander": "^13.1.0",
30
+ "open": "^10.1.0",
31
+ "zod": "^3.24.1",
32
+ "@ripeseed/shared": "0.1.2"
33
+ },
34
+ "optionalDependencies": {
35
+ "keytar": "^7.9.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^22.12.0",
39
+ "tsx": "^4.19.2",
40
+ "vitest": "^3.0.5",
41
+ "@ripeseed/config": "0.1.0"
42
+ },
43
+ "scripts": {
44
+ "build": "tsc -p tsconfig.json",
45
+ "dev": "pnpm --filter @ripeseed/shared build && tsx watch src/index.ts",
46
+ "lint": "eslint src --ext .ts",
47
+ "typecheck": "tsc -p tsconfig.json --noEmit",
48
+ "test": "vitest run --passWithNoTests",
49
+ "format": "prettier --check src"
50
+ }
51
+ }