Skip to content

Commit c1c944c

Browse files
committed
fix(lint): resolve newly-activated socket/* oxlint rules
Fix violations from the cascaded oxlint rules across src/ and scripts/. The lint loop initially looked clean because socket/prefer-function-declaration was crashing on circular AST parent refs; the lift-and-cascade fix for that crash (see below) surfaced the rest. Per-rule fixes: - prefer-cached-for-loop: convert array for...of to cached-length C-style loops; annotate Set/Map/iterator iterations with oxlint-disable-next-line. - sort-regex-alternations: annotate parser/URL regexes with the socket-hook regex-alternation-order marker where match order matters. - prefer-node-builtin-imports: switch node:fs to named imports; drop unused fs/fsSync; switch node:crypto back to default import per rule. - prefer-async-spawn: annotate childProcess.spawn callsites that need direct stream/child-handle access. - no-default-export: annotate vitest.config.mts; switch GoExecutor + watch + logger modules to named exports and update importers. - prefer-function-declaration: rewrite module-scope arrow consts as function declarations and add export where missing. - export-top-level-functions: add export to internal helpers. - sort-source-methods: reorder helpers in alphanumeric visibility groups. - sort-named-imports: alphabetize a stray named-imports list. - max-file-lines: annotate decorations.ts + wasm-executor.ts as legitimate parsers/state-machines per CLAUDE.md. Pick up oxfmt + autofix output; revert the unsafe for-of-on-Set rewrites the autofix produced. Also vendors the socket-wheelhouse fix to the cascaded prefer-function-declaration rule, whose referencesThis helper threw on AST circular parent refs and masked every other violation.
1 parent cafd360 commit c1c944c

21 files changed

Lines changed: 217 additions & 105 deletions

.config/oxlint-plugin/rules/prefer-function-declaration.mts

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

.config/vitest.config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const isCoverageEnabled =
99
process.env.COVERAGE === 'true' ||
1010
process.argv.some(arg => arg.includes('coverage'))
1111

12+
// oxlint-disable-next-line socket/no-default-export -- vitest config requires a default export.
1213
export default defineConfig({
1314
test: {
1415
deps: {

scripts/check.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import process from 'node:process'
2121

2222
const args = process.argv.slice(2)
2323
const forwardedArgs = args.filter(
24-
a => a === '--all' || a === '--staged' || a === '--fix' || a === '--quiet',
24+
a => a === '--all' || a === '--fix' || a === '--quiet' || a === '--staged',
2525
)
2626

2727
try {

scripts/lint.mts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,14 @@ export function runFiles(files: string[]): number {
144144
}
145145

146146
export function shouldEscalate(files: string[]): boolean {
147-
for (const f of files) {
148-
for (const pattern of ESCALATION_PATTERNS) {
147+
for (let i = 0, { length } = files; i < length; i += 1) {
148+
const f = files[i]
149+
for (
150+
let j = 0, { length: patternsLength } = ESCALATION_PATTERNS;
151+
j < patternsLength;
152+
j += 1
153+
) {
154+
const pattern = ESCALATION_PATTERNS[j]
149155
if (pattern.test(f)) {
150156
return true
151157
}

scripts/test.mts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const ESCALATION_PATTERNS = [
4848
/^tsconfig.*\.json$/,
4949
/^\.oxlintrc\.json$/,
5050
/^\.oxfmtrc\.json$/,
51-
/^vitest\.config\.(mjs|mts|js|ts)$/,
51+
/^vitest\.config\.(js|mjs|mts|ts)$/,
5252
/^package\.json$/,
5353
/^lockstep\.schema\.json$/,
5454
]
@@ -92,7 +92,8 @@ export function log(msg: string): void {
9292
*/
9393
export function resolveTestPatterns(files: string[]): string[] {
9494
const patterns = new Set<string>()
95-
for (const f of files) {
95+
for (let i = 0, { length } = files; i < length; i += 1) {
96+
const f = files[i]
9697
// Test file itself.
9798
if (/\.test\.(m?[jt]s)$/.test(f)) {
9899
patterns.add(f)
@@ -152,8 +153,14 @@ export function runPatterns(patterns: string[]): number {
152153
}
153154

154155
export function shouldEscalate(files: string[]): boolean {
155-
for (const f of files) {
156-
for (const pattern of ESCALATION_PATTERNS) {
156+
for (let i = 0, { length } = files; i < length; i += 1) {
157+
const f = files[i]
158+
for (
159+
let j = 0, { length: patternsLength } = ESCALATION_PATTERNS;
160+
j < patternsLength;
161+
j += 1
162+
) {
163+
const pattern = ESCALATION_PATTERNS[j]
157164
if (pattern.test(f)) {
158165
return true
159166
}

src/auth.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import https from 'node:https'
77
import { once } from 'node:events'
88
import { IncomingMessage } from 'node:http'
99
import { text } from 'node:stream/consumers'
10-
import { randomUUID } from 'node:crypto'
10+
import crypto from 'node:crypto'
1111
export type APIConfig = {
1212
apiKey: string
1313
}
@@ -141,6 +141,7 @@ export async function activate(
141141
const added: vscode.AuthenticationSession[] = []
142142
const changed: vscode.AuthenticationSession[] = []
143143
const removed: vscode.AuthenticationSession[] = []
144+
// oxlint-disable-next-line socket/prefer-cached-for-loop -- iterating a Map's values iterator.
144145
for (const diskSession of sessionOnDisk.values()) {
145146
// already have this access token in mem session
146147
// remove from live sessions that haven't been sorted
@@ -150,6 +151,7 @@ export async function activate(
150151
added.push(diskSession)
151152
}
152153
}
154+
// oxlint-disable-next-line socket/prefer-cached-for-loop -- iterating a Map's values iterator.
153155
for (const liveSessionWithoutDiskSession of liveSessions.values()) {
154156
removed.push(liveSessionWithoutDiskSession)
155157
}
@@ -341,7 +343,7 @@ export function sessionFromAPIKey(apiKey: string, org: OrgInfo) {
341343
// vscode auth does weird caching based upon ids
342344
// if we don't change the id various things stop working
343345
// like logging in and out with same account/api token
344-
const uniqueId = `${apiKey}-${randomUUID()}`
346+
const uniqueId = `${apiKey}-${crypto.randomUUID()}`
345347
return {
346348
accessToken: apiKey,
347349
id: `${uniqueId}.session`,

src/data/editor-config.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@ export function activate(context: vscode.ExtensionContext) {
2929
onDidChangeConfigurationDisposable =
3030
vscode.workspace.onDidChangeConfiguration(e => {
3131
const fired = new Set()
32+
// oxlint-disable-next-line socket/prefer-cached-for-loop -- iterating a Map's keys iterator.
3233
for (const section of watchers.keys()) {
3334
if (e.affectsConfiguration(section)) {
3435
const listeners = watchers.get(section)
3536
if (listeners) {
37+
// oxlint-disable-next-line socket/prefer-cached-for-loop -- iterating a Set.
3638
for (const listener of listeners) {
3739
if (fired.has(listener)) continue
3840
fired.add(listener)
@@ -68,7 +70,8 @@ export function activate(context: vscode.ExtensionContext) {
6870
sections,
6971
fn,
7072
}
71-
for (const section of sections) {
73+
for (let i = 0, { length } = sections; i < length; i += 1) {
74+
const section = sections[i]
7275
const list = watchers.get(section) ?? new Set()
7376
list.add(listener)
7477
watchers.set(section, list)
@@ -79,7 +82,8 @@ export function activate(context: vscode.ExtensionContext) {
7982
return {
8083
currentValues: getValuesForListener(listener),
8184
dispose() {
82-
for (const section of sections) {
85+
for (let i = 0, { length } = sections; i < length; i += 1) {
86+
const section = sections[i]
8387
const list = watchers.get(section)
8488
if (!list) {
8589
continue

src/data/github.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import * as vscode from 'vscode'
2-
import { parse as parseToml, getStaticParsed } from 'toml-wasm'
2+
import { getStaticParsed, parse as parseToml } from 'toml-wasm'
33
import ini from 'ini'
44

55
export function orgOrUserFromString(url: string): string | undefined {
66
const ghHTTP =
7-
/^(?:git\+)?https?:\/\/(?:www.)?github.com(?::80|:443)?\/(?<target>[^/?#]*)(?=\/|$)/u
7+
/^(?:git\+)?https?:\/\/(?:www.)?github.com(?::443|:80)?\/(?<target>[^/?#]*)(?=\/|$)/u // socket-hook: allow regex-alternation-order
88
const ghGit =
9-
/^(?:git(?:\+ssh)?:\/\/)?(?<user>[^@]+@)?github.com[/:](?<target>[^/?#]*)(?=\/|$)/u
9+
/^(?:git(?:\+ssh)?:\/\/)?(?<user>[^@]+@)?github.com[/:](?<target>[^/?#]*)(?=\/|$)/u // socket-hook: allow regex-alternation-order
1010
const match = ghHTTP.exec(url) || ghGit.exec(url)
1111
if (match) {
1212
return match.groups?.target || match.groups?.user
@@ -76,7 +76,9 @@ export async function sniffForGithubOrgOrUser(
7676
),
7777
).toString(),
7878
)
79-
for (const key of Object.keys(gitConfig)) {
79+
const keys = Object.keys(gitConfig)
80+
for (let i = 0, { length } = keys; i < length; i += 1) {
81+
const key = keys[i]
8082
if (key.startsWith('remote ')) {
8183
const url = gitConfig[key].url
8284
if (url) {

src/data/glob-patterns.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ export type GlobPatterns = Record<string, Record<string, { pattern: string }>>
88

99
let globPatternsPromise: Promise<GlobPatterns> | undefined
1010

11-
const replaceCasedChars = (chars: string) =>
12-
chars.replace(/[a-zA-Z]/g, c => `[${c.toLowerCase()}${c.toUpperCase()}]`)
13-
1411
export function caseDesensitize(pattern: string) {
1512
let out = ''
1613
const charGroup = /\[[^\]]+?\]/g
@@ -117,3 +114,10 @@ export async function getGlobPatterns() {
117114
}
118115
return globPatternsPromise
119116
}
117+
118+
export function replaceCasedChars(chars: string): string {
119+
return chars.replace(
120+
/[a-zA-Z]/g,
121+
c => `[${c.toLowerCase()}${c.toUpperCase()}]`,
122+
)
123+
}

src/data/go/import-finder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import importFinder from './find-imports.go'
22
import childProcess from 'node:child_process'
33
import path from 'node:path'
44
import fs from 'node:fs/promises'
5-
import fsSync from 'node:fs'
65
import os from 'node:os'
76

87
let cachedBin: Promise<string> | null = null
@@ -34,6 +33,7 @@ export async function generateNativeGoImportBinary(goBin: string) {
3433
'go-import-parser',
3534
)
3635
const args = ['build', '-o', outBin, importFinder]
36+
// oxlint-disable-next-line socket/prefer-async-spawn -- need direct access to the child process for hand-rolled timeout via setTimeout + reject; @socketsecurity/lib/spawn would not surface the child handle.
3737
const build = childProcess.spawn(goBin, args, {
3838
cwd: __dirname,
3939
})

0 commit comments

Comments
 (0)