Skip to content

Commit f4b0328

Browse files
authored
refactor: use ts exts for relative paths (#1111)
* refactor: use ts exts for relative paths * test: fix coverage
1 parent a23261b commit f4b0328

21 files changed

+228
-147
lines changed

.github/workflows/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ jobs:
215215
- name: Install deps
216216
run: npm ci
217217
- name: Install TypeScript ${{ matrix.ts }}
218-
run: npm i --force --no-package-lock typescript@${{ matrix.ts }}
218+
run: npm i --force --no-package-lock --no-fund typescript@${{ matrix.ts }}
219219
- uses: actions/download-artifact@v4
220220
with:
221221
name: build

.nycrc

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,14 @@
22
"reporter": ["html", "text"],
33
"lines": 98,
44
"branches": "90",
5-
"statements": "98"
5+
"statements": "98",
6+
"exclude": [
7+
"build/deno.js",
8+
"build/vendor-extra.cjs",
9+
"build/vendor-core.cjs",
10+
"build/esblib.cjs",
11+
"test/**",
12+
"scripts",
13+
"src/util.ts"
14+
]
615
}

.size-limit.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
{
3131
"name": "all",
3232
"path": "build/*",
33-
"limit": "850.2 kB",
33+
"limit": "850.25 kB",
3434
"brotli": false,
3535
"gzip": false
3636
}

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"fmt": "prettier --write .",
6464
"fmt:check": "prettier --check .",
6565
"build": "npm run build:js && npm run build:dts && npm run build:tests",
66-
"build:js": "node scripts/build-js.mjs --format=cjs --hybrid --entry=src/*.ts:!src/error.ts:!src/repl.ts && npm run build:vendor",
66+
"build:js": "node scripts/build-js.mjs --format=cjs --hybrid --entry=src/*.ts:!src/error.ts:!src/repl.ts:!src/md.ts && npm run build:vendor",
6767
"build:vendor": "node scripts/build-js.mjs --format=cjs --entry=src/vendor-*.ts --bundle=all",
6868
"build:tests": "node scripts/build-tests.mjs",
6969
"build:dts": "tsc --project tsconfig.json && rm build/error.d.ts build/repl.d.ts && node scripts/build-dts.mjs",
@@ -75,7 +75,7 @@
7575
"test:it": "node ./test/it/build.test.js",
7676
"test:jsr": "node ./test/it/build-jsr.test.js",
7777
"test:unit": "node --experimental-strip-types ./test/all.test.js",
78-
"test:coverage": "c8 -x build/deno.js -x build/vendor-extra.cjs -x build/vendor-core.cjs -x build/esblib.cjs -x 'test/**' -x scripts --check-coverage npm run test:unit",
78+
"test:coverage": "c8 -c .nycrc --check-coverage npm run test:unit",
7979
"test:circular": "madge --circular src/*",
8080
"test:types": "tsd",
8181
"test:license": "node ./test/extra.test.js",
@@ -84,7 +84,7 @@
8484
"test:smoke:strip-types": "node --experimental-strip-types test/smoke/ts.test.ts",
8585
"test:smoke:tsx": "tsx test/smoke/ts.test.ts",
8686
"test:smoke:tsc": "cd test/smoke && mkdir -p node_modules && ln -s ../../../ ./node_modules/zx; ../../node_modules/typescript/bin/tsc -v && ../../node_modules/typescript/bin/tsc --esModuleInterop --module node16 --rootDir . --outdir ./temp ts.test.ts && node ./temp/ts.test.js",
87-
"test:smoke:ts-node": "node --loader ts-node/esm test/smoke/ts.test.ts",
87+
"test:smoke:ts-node": "cd test/smoke && node --loader ts-node/esm ts.test.ts",
8888
"test:smoke:bun": "bun test ./test/smoke/bun.test.js && bun ./test/smoke/node.test.mjs",
8989
"test:smoke:win32": "node ./test/smoke/win32.test.js",
9090
"test:smoke:cjs": "node ./test/smoke/node.test.cjs",

scripts/build-dts.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ for (const dts of await glob(['build/**/*.d.ts', '!build/vendor-*.d.ts'])) {
110110
const contents =
111111
(pkgEntries.some((e) => dts.includes(e)) ? prefix : '') +
112112
(await fs.readFile(dts, 'utf8'))
113+
.replaceAll(".ts';", ".js';")
113114
.split('\n')
114115
.filter((line) => !line.startsWith('/// <reference types'))
115116
.join('\n')

src/cli.ts

+8-78
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ import {
2828
path,
2929
stdin,
3030
VERSION,
31-
} from './index.js'
32-
import { installDeps, parseDeps } from './deps.js'
33-
import { startRepl } from './repl.js'
34-
import { randomId, bufToString } from './util.js'
35-
import { createRequire, type minimist } from './vendor.js'
31+
} from './index.ts'
32+
import { installDeps, parseDeps } from './deps.ts'
33+
import { startRepl } from './repl.ts'
34+
import { randomId, bufToString } from './util.ts'
35+
import { transformMarkdown } from './md.ts'
36+
import { createRequire, type minimist } from './vendor.ts'
3637

3738
const EXT = '.mjs'
3839
const EXT_RE = /^\.[mc]?[jt]sx?$/
@@ -206,86 +207,15 @@ async function readScriptFromHttp(remote: string): Promise<string> {
206207
return res.text()
207208
}
208209

210+
export { transformMarkdown }
211+
209212
export function injectGlobalRequire(origin: string): void {
210213
const __filename = path.resolve(origin)
211214
const __dirname = path.dirname(__filename)
212215
const require = createRequire(origin)
213216
Object.assign(globalThis, { __filename, __dirname, require })
214217
}
215218

216-
export function transformMarkdown(buf: Buffer | string): string {
217-
const output = []
218-
const tabRe = /^( +|\t)/
219-
const codeBlockRe =
220-
/^(?<fence>(`{3,20}|~{3,20}))(?:(?<js>(js|javascript|ts|typescript))|(?<bash>(sh|shell|bash))|.*)$/
221-
let state = 'root'
222-
let codeBlockEnd = ''
223-
let prevLineIsEmpty = true
224-
for (const line of bufToString(buf).split(/\r?\n/)) {
225-
switch (state) {
226-
case 'root':
227-
if (tabRe.test(line) && prevLineIsEmpty) {
228-
output.push(line)
229-
state = 'tab'
230-
continue
231-
}
232-
const { fence, js, bash } = line.match(codeBlockRe)?.groups || {}
233-
if (!fence) {
234-
prevLineIsEmpty = line === ''
235-
output.push('// ' + line)
236-
continue
237-
}
238-
codeBlockEnd = fence
239-
if (js) {
240-
state = 'js'
241-
output.push('')
242-
} else if (bash) {
243-
state = 'bash'
244-
output.push('await $`')
245-
} else {
246-
state = 'other'
247-
output.push('')
248-
}
249-
break
250-
case 'tab':
251-
if (line === '') {
252-
output.push('')
253-
} else if (tabRe.test(line)) {
254-
output.push(line)
255-
} else {
256-
output.push('// ' + line)
257-
state = 'root'
258-
}
259-
break
260-
case 'js':
261-
if (line === codeBlockEnd) {
262-
output.push('')
263-
state = 'root'
264-
} else {
265-
output.push(line)
266-
}
267-
break
268-
case 'bash':
269-
if (line === codeBlockEnd) {
270-
output.push('`')
271-
state = 'root'
272-
} else {
273-
output.push(line)
274-
}
275-
break
276-
case 'other':
277-
if (line === codeBlockEnd) {
278-
output.push('')
279-
state = 'root'
280-
} else {
281-
output.push('// ' + line)
282-
}
283-
break
284-
}
285-
}
286-
return output.join('\n')
287-
}
288-
289219
export function isMain(
290220
metaurl: string = import.meta.url,
291221
scriptpath: string = process.argv[1]

src/core.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
formatExitMessage,
3232
getCallerLocation,
3333
getExitCodeInfo,
34-
} from './error.js'
34+
} from './error.ts'
3535
import {
3636
exec,
3737
buildCmd,
@@ -41,7 +41,7 @@ import {
4141
VoidStream,
4242
type ChalkInstance,
4343
type TSpawnStore,
44-
} from './vendor-core.js'
44+
} from './vendor-core.ts'
4545
import {
4646
type Duration,
4747
log,
@@ -60,9 +60,9 @@ import {
6060
toCamelCase,
6161
randomId,
6262
bufArrJoin,
63-
} from './util.js'
63+
} from './util.ts'
6464

65-
export { log, type LogEntry } from './util.js'
65+
export { log, type LogEntry } from './util.ts'
6666

6767
const CWD = Symbol('processCwd')
6868
const SYNC = Symbol('syncExec')

src/deps.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
import { $ } from './core.js'
16-
import { spinner } from './goods.js'
17-
import { depseek } from './vendor.js'
15+
import { $ } from './core.ts'
16+
import { spinner } from './goods.ts'
17+
import { depseek } from './vendor.ts'
1818

1919
/**
2020
* Install npm dependencies

src/globals.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
import * as _ from './index.js'
15+
import * as _ from './index.ts'
1616

1717
Object.assign(globalThis, _)
1818
// TODO: global types not working with jsr.io

src/goods.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@
1414

1515
import assert from 'node:assert'
1616
import { createInterface } from 'node:readline'
17-
import { $, within, ProcessOutput } from './core.js'
17+
import { $, within, ProcessOutput } from './core.ts'
1818
import {
1919
type Duration,
2020
identity,
2121
isStringLiteral,
2222
parseBool,
2323
parseDuration,
2424
toCamelCase,
25-
} from './util.js'
25+
} from './util.ts'
2626
import {
2727
type RequestInfo,
2828
type RequestInit,
2929
nodeFetch,
3030
minimist,
31-
} from './vendor.js'
31+
} from './vendor.ts'
3232

3333
export { default as path } from 'node:path'
3434
export * as os from 'node:os'

src/index.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
import { ProcessPromise } from './core.js'
16-
import { fs } from './vendor.js'
15+
import { ProcessPromise } from './core.ts'
16+
import { fs } from './vendor.ts'
1717

18-
export * from './core.js'
19-
export * from './goods.js'
18+
export * from './core.ts'
19+
export * from './goods.ts'
2020
export {
2121
minimist,
2222
chalk,
@@ -27,7 +27,7 @@ export {
2727
ps,
2828
glob,
2929
glob as globby,
30-
} from './vendor.js'
30+
} from './vendor.ts'
3131

3232
export const VERSION: string = fs.readJsonSync(
3333
new URL('../package.json', import.meta.url)
@@ -42,7 +42,7 @@ export {
4242
tempdir as tmpdir,
4343
tempfile,
4444
tempfile as tmpfile,
45-
} from './util.js'
45+
} from './util.ts'
4646

4747
/**
4848
* @deprecated Use $`cmd`.nothrow() instead.

src/md.ts

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import { bufToString } from './util.ts'
16+
17+
export function transformMarkdown(buf: Buffer | string): string {
18+
const output = []
19+
const tabRe = /^( +|\t)/
20+
const codeBlockRe =
21+
/^(?<fence>(`{3,20}|~{3,20}))(?:(?<js>(js|javascript|ts|typescript))|(?<bash>(sh|shell|bash))|.*)$/
22+
let state = 'root'
23+
let codeBlockEnd = ''
24+
let prevLineIsEmpty = true
25+
for (const line of bufToString(buf).split(/\r?\n/)) {
26+
switch (state) {
27+
case 'root':
28+
if (tabRe.test(line) && prevLineIsEmpty) {
29+
output.push(line)
30+
state = 'tab'
31+
continue
32+
}
33+
const { fence, js, bash } = line.match(codeBlockRe)?.groups || {}
34+
if (!fence) {
35+
prevLineIsEmpty = line === ''
36+
output.push('// ' + line)
37+
continue
38+
}
39+
codeBlockEnd = fence
40+
if (js) {
41+
state = 'js'
42+
output.push('')
43+
} else if (bash) {
44+
state = 'bash'
45+
output.push('await $`')
46+
} else {
47+
state = 'other'
48+
output.push('')
49+
}
50+
break
51+
case 'tab':
52+
if (line === '') {
53+
output.push('')
54+
} else if (tabRe.test(line)) {
55+
output.push(line)
56+
} else {
57+
output.push('// ' + line)
58+
state = 'root'
59+
}
60+
break
61+
case 'js':
62+
if (line === codeBlockEnd) {
63+
output.push('')
64+
state = 'root'
65+
} else {
66+
output.push(line)
67+
}
68+
break
69+
case 'bash':
70+
if (line === codeBlockEnd) {
71+
output.push('`')
72+
state = 'root'
73+
} else {
74+
output.push(line)
75+
}
76+
break
77+
case 'other':
78+
if (line === codeBlockEnd) {
79+
output.push('')
80+
state = 'root'
81+
} else {
82+
output.push('// ' + line)
83+
}
84+
break
85+
}
86+
}
87+
return output.join('\n')
88+
}

src/repl.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import os from 'node:os'
1616
import path from 'node:path'
1717
import repl from 'node:repl'
1818
import { inspect } from 'node:util'
19-
import { ProcessOutput, defaults } from './core.js'
20-
import { chalk } from './vendor-core.js'
19+
import { ProcessOutput, defaults } from './core.ts'
20+
import { chalk } from './vendor-core.ts'
2121

2222
const HISTORY =
2323
process.env.ZX_REPL_HISTORY ?? path.join(os.homedir(), '.zx_repl_history')

src/util.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ import {
2020
type RequestInfo,
2121
type RequestInit,
2222
type TSpawnStoreChunks,
23-
} from './vendor-core.js'
23+
} from './vendor-core.ts'
2424
import { inspect } from 'node:util'
2525

26-
export { isStringLiteral } from './vendor-core.js'
26+
export { isStringLiteral } from './vendor-core.ts'
2727

2828
export function tempdir(
2929
prefix: string = `zx-${randomId()}`,

0 commit comments

Comments
 (0)