Skip to content

Commit 0e600f7

Browse files
authored
refactor: rename scripts/*.mjs to *.mts for native TypeScript (#584)
* refactor: rename scripts/*.mjs to *.mts with full TypeScript types * fix: update stale .mjs references to .mts after script rename The previous commit renamed scripts/*.mjs to *.mts but left behind stale .mjs extensions in cross-file imports, spawn args, comments, and workflow path triggers. Also renames .config/esbuild.config.mjs to .mts to match the import in build.mts. * fix(scripts): resolve all TypeScript type errors in .mts scripts - Add type annotations to esbuild plugin params (PluginBuild, BuildResult, etc.) - Use bracket notation for index signature access (process.env, parseArgs values) - Add null/undefined guards for possibly-undefined values - Fix catch clauses to use `catch (e)` with proper type narrowing - Add `as const` for string literal types (format, platform, sourcemap) - Add @types/semver for semver type declarations - Fix openapi-typescript transform callback signatures - Handle exactOptionalPropertyTypes correctly in return types - Fix babel traverse/parser version mismatch with proper casts
1 parent 9f4951d commit 0e600f7

32 files changed

Lines changed: 1257 additions & 696 deletions
Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ import path from 'node:path'
88
import process from 'node:process'
99
import { fileURLToPath } from 'node:url'
1010

11+
import type { Comment } from '@babel/types'
12+
1113
import { parse } from '@babel/parser'
1214
import MagicString from 'magic-string'
1315

16+
import type { BuildResult, Metafile, OnResolveArgs, PluginBuild } from 'esbuild'
17+
1418
import { NODE_MODULES } from '@socketsecurity/lib/paths/dirnames'
1519
import { envAsBoolean } from '@socketsecurity/lib/env/helpers'
1620
import { getDefaultLogger } from '@socketsecurity/lib/logger'
@@ -35,8 +39,8 @@ const externalDependencies = Object.keys(packageJson.dependencies || {})
3539
function createPathShorteningPlugin() {
3640
return {
3741
name: 'shorten-module-paths',
38-
setup(build) {
39-
build.onEnd(async result => {
42+
setup(build: PluginBuild) {
43+
build.onEnd(async (result: BuildResult) => {
4044
if (!result.outputFiles && result.metafile) {
4145
const outputs = Object.keys(result.metafile.outputs).filter(
4246
f => f.endsWith('.js') || f.endsWith('.mjs'),
@@ -52,7 +56,7 @@ function createPathShorteningPlugin() {
5256
const conflictDetector = new Map()
5357

5458
// eslint-disable-next-line unicorn/consistent-function-scoping
55-
const shortenPath = longPath => {
59+
const shortenPath = (longPath: string): string => {
5660
if (pathMap.has(longPath)) {
5761
return pathMap.get(longPath)
5862
}
@@ -102,15 +106,19 @@ function createPathShorteningPlugin() {
102106
})
103107

104108
// Walk through all comments
105-
for (const comment of ast.comments || []) {
109+
for (const comment of (ast.comments || []) as Comment[]) {
106110
if (
107111
comment.type === 'CommentLine' &&
108112
comment.value.includes(NODE_MODULES)
109113
) {
110114
const originalPath = comment.value.trim()
111115
const shortPath = shortenPath(originalPath)
112116

113-
if (shortPath !== originalPath) {
117+
if (
118+
shortPath !== originalPath &&
119+
comment.start != null &&
120+
comment.end != null
121+
) {
114122
magicString.overwrite(
115123
comment.start,
116124
comment.end,
@@ -121,33 +129,36 @@ function createPathShorteningPlugin() {
121129
}
122130

123131
// Walk through all string literals
124-
function walk(node) {
132+
function walk(node: unknown) {
125133
if (!node || typeof node !== 'object') {
126134
return
127135
}
136+
const n = node as Record<string, unknown>
128137

129138
if (
130-
node.type === 'StringLiteral' &&
131-
node.value &&
132-
node.value.includes(NODE_MODULES)
139+
n['type'] === 'StringLiteral' &&
140+
typeof n['value'] === 'string' &&
141+
n['value'].includes(NODE_MODULES)
133142
) {
134-
const originalPath = node.value
143+
const originalPath = n['value']
135144
const shortPath = shortenPath(originalPath)
136-
137-
if (shortPath !== originalPath) {
138-
magicString.overwrite(
139-
node.start + 1,
140-
node.end - 1,
141-
shortPath,
142-
)
145+
const start = n['start']
146+
const end = n['end']
147+
148+
if (
149+
shortPath !== originalPath &&
150+
typeof start === 'number' &&
151+
typeof end === 'number'
152+
) {
153+
magicString.overwrite(start + 1, end - 1, shortPath)
143154
}
144155
}
145156

146-
for (const key of Object.keys(node)) {
157+
for (const key of Object.keys(n)) {
147158
if (key === 'start' || key === 'end' || key === 'loc') {
148159
continue
149160
}
150-
const value = node[key]
161+
const value = n[key]
151162
if (Array.isArray(value)) {
152163
for (const item of value) {
153164
walk(item)
@@ -158,12 +169,12 @@ function createPathShorteningPlugin() {
158169
}
159170
}
160171

161-
walk(ast.program)
172+
walk(ast.program as unknown)
162173
// eslint-disable-next-line no-await-in-loop
163174
await fs.writeFile(outputPath, magicString.toString(), 'utf8')
164-
} catch (error) {
175+
} catch (e) {
165176
logger.error(
166-
`Failed to shorten paths in ${outputPath}: ${error.message}`,
177+
`Failed to shorten paths in ${outputPath}: ${e instanceof Error ? e.message : String(e)}`,
167178
)
168179
}
169180
}
@@ -181,7 +192,7 @@ function createNodeProtocolPlugin() {
181192
// Get list of Node.js built-in modules dynamically
182193
return {
183194
name: 'node-protocol',
184-
setup(build) {
195+
setup(build: PluginBuild) {
185196
for (const builtin of Module.builtinModules) {
186197
// Skip builtins that already have node: prefix
187198
if (builtin.startsWith('node:')) {
@@ -193,7 +204,7 @@ function createNodeProtocolPlugin() {
193204
const escapedBuiltin = builtin.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
194205
build.onResolve(
195206
{ filter: new RegExp(`^${escapedBuiltin}$`) },
196-
_args => {
207+
(_args: OnResolveArgs) => {
197208
// Return with node: prefix and mark as external
198209
return {
199210
path: `node:${builtin}`,
@@ -237,7 +248,7 @@ function createLibStubPlugin() {
237248

238249
return {
239250
name: 'stub-unused-internals',
240-
setup(build) {
251+
setup(build: PluginBuild) {
241252
// Stub heavy lib modules with empty exports.
242253
build.onLoad({ filter: libStubPattern }, () => ({
243254
contents: 'module.exports = {}',
@@ -262,13 +273,13 @@ export const buildConfig = {
262273
outdir: distPath,
263274
outbase: srcPath,
264275
bundle: true,
265-
format: 'cjs',
276+
format: 'cjs' as const,
266277
// Target Node.js environment (not browser).
267-
platform: 'node',
278+
platform: 'node' as const,
268279
// Target Node.js 18+ features.
269280
target: 'node18',
270281
// Enable source maps for coverage (set COVERAGE=true env var)
271-
sourcemap: envAsBoolean(process.env.COVERAGE),
282+
sourcemap: envAsBoolean(process.env['COVERAGE']),
272283
minify: false,
273284
treeShaking: true,
274285
// For bundle analysis
@@ -292,7 +303,7 @@ export const buildConfig = {
292303
// Define constants for optimization
293304
define: {
294305
'process.env.NODE_ENV': JSON.stringify(
295-
process.env.NODE_ENV || 'production',
306+
process.env['NODE_ENV'] || 'production',
296307
),
297308
},
298309
}
@@ -301,15 +312,15 @@ export const buildConfig = {
301312
export const watchConfig = {
302313
...buildConfig,
303314
minify: false,
304-
sourcemap: 'inline',
315+
sourcemap: 'inline' as const,
305316
logLevel: 'debug',
306317
watch: {
307-
onRebuild(error, result) {
318+
onRebuild(error: Error | null, result: BuildResult | null) {
308319
if (error) {
309320
logger.error(`Watch build failed: ${error}`)
310321
} else {
311322
logger.log('Watch build succeeded')
312-
if (result.metafile) {
323+
if (result?.metafile) {
313324
const analysis = analyzeMetafile(result.metafile)
314325
logger.log(analysis)
315326
}
@@ -321,12 +332,12 @@ export const watchConfig = {
321332
/**
322333
* Analyze build output for size information
323334
*/
324-
function analyzeMetafile(metafile) {
335+
function analyzeMetafile(metafile: Metafile) {
325336
const outputs = Object.keys(metafile.outputs)
326337
let totalSize = 0
327338

328339
const files = outputs.map(file => {
329-
const output = metafile.outputs[file]
340+
const output = metafile.outputs[file]!
330341
totalSize += output.bytes
331342
return {
332343
name: path.relative(rootPath, file),

.github/workflows/generate.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ on:
66
- main
77
paths:
88
- '.github/workflows/generate.yml'
9-
- 'scripts/generate-sdk.mjs'
10-
- 'scripts/generate-types.mjs'
11-
- 'scripts/generate-strict-types.mjs'
9+
- 'scripts/generate-sdk.mts'
10+
- 'scripts/generate-types.mts'
11+
- 'scripts/generate-strict-types.mts'
1212
schedule:
1313
# At 07:23 on every day-of-week from Monday through Friday.
1414
- cron: '23 7 * * 1-5'

package.json

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,40 +42,41 @@
4242
}
4343
},
4444
"scripts": {
45-
"build": "node scripts/build.mjs",
46-
"bump": "node scripts/bump.mjs",
47-
"check": "node scripts/check.mjs",
48-
"clean": "node scripts/clean.mjs",
49-
"cover": "node scripts/cover.mjs",
50-
"fix": "node scripts/fix.mjs",
45+
"build": "node scripts/build.mts",
46+
"bump": "node scripts/bump.mts",
47+
"check": "node scripts/check.mts",
48+
"clean": "node scripts/clean.mts",
49+
"cover": "node scripts/cover.mts",
50+
"fix": "node scripts/fix.mts",
5151
"format": "oxfmt --write .",
5252
"format:check": "oxfmt --check .",
53-
"generate-sdk": "node scripts/generate-sdk.mjs",
54-
"lint": "node scripts/lint.mjs",
53+
"generate-sdk": "node scripts/generate-sdk.mts",
54+
"lint": "node scripts/lint.mts",
5555
"precommit": "pnpm run check --lint --staged",
5656
"prepare": "husky",
57-
"ci:validate": "node scripts/ci-validate.mjs",
57+
"ci:validate": "node scripts/ci-validate.mts",
5858
"prepublishOnly": "echo 'ERROR: Use GitHub Actions workflow for publishing' && exit 1",
59-
"publish": "node scripts/publish.mjs",
60-
"publish:ci": "node scripts/publish.mjs --tag ${DIST_TAG:-latest}",
61-
"claude": "node scripts/claude.mjs",
59+
"publish": "node scripts/publish.mts",
60+
"publish:ci": "node scripts/publish.mts --tag ${DIST_TAG:-latest}",
61+
"claude": "node scripts/claude.mts",
6262
"security": "agentshield scan && { command -v zizmor >/dev/null && zizmor .github/ || echo 'zizmor not installed — run pnpm run setup to install'; }",
63-
"test": "node scripts/test.mjs",
63+
"test": "node scripts/test.mts",
6464
"type": "tsgo --noEmit -p .config/tsconfig.check.json",
65-
"update": "node scripts/update.mjs"
65+
"update": "node scripts/update.mts"
6666
},
6767
"devDependencies": {
6868
"@anthropic-ai/claude-code": "2.1.92",
69-
"@socketsecurity/lib": "5.18.2",
7069
"@babel/generator": "7.28.5",
7170
"@babel/parser": "7.26.3",
7271
"@babel/traverse": "7.26.4",
7372
"@babel/types": "7.26.3",
7473
"@dotenvx/dotenvx": "1.54.1",
7574
"@oxlint/migrate": "1.52.0",
75+
"@socketsecurity/lib": "5.18.2",
7676
"@sveltejs/acorn-typescript": "1.0.8",
7777
"@types/babel__traverse": "7.28.0",
7878
"@types/node": "24.9.2",
79+
"@types/semver": "^7.7.1",
7980
"@typescript/native-preview": "7.0.0-dev.20260415.1",
8081
"@vitest/coverage-v8": "4.0.3",
8182
"acorn": "8.15.0",

pnpm-lock.yaml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)