Skip to content

Commit 03aa500

Browse files
committed
refactor: adopt @socketsecurity/lib/primordials
Migrates the 20 call sites flagged by `pnpm prim audit` to the shared primordials surface from socket-lib 5.25.0: - 4× StringPrototypeTrim (replaces .trim()) - 9× DateNow (replaces Date.now() in http-client timing) - 2× SetCtor (replaces new Set(...)) - 2× ErrorCtor (replaces new Error(...)) - 2× ArrayIsArray (replaces Array.isArray) - 2× PromiseWithResolvers (replaces Promise.withResolvers) - 1× MapCtor (replaces new Map(...)) - 1× TypeErrorCtor (replaces new TypeError(...)) - 1× StringPrototypeToLowerCase (replaces .toLowerCase()) - 1× StringPrototypeEndsWith (replaces .endsWith()) - 1× URLSearchParamsCtor (replaces new URLSearchParams(...)) After: prim audit reports zero migration candidates.
1 parent ddb7cd9 commit 03aa500

6 files changed

Lines changed: 52 additions & 29 deletions

File tree

src/constants.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Provides default values, HTTP agents, and public policy configurations for API interactions.
44
*/
55

6+
import { MapCtor, SetCtor } from '@socketsecurity/lib/primordials'
7+
68
import rootPkgJson from '../package.json' with { type: 'json' }
79
import { createUserAgentFromPkgJson } from './user-agent'
810

@@ -60,10 +62,10 @@ export const SOCKET_FIREWALL_API_URL = 'https://firewall-api.socket.dev/purl'
6062

6163
// https://github.com/sindresorhus/got/blob/v14.4.6/documentation/2-options.md#agent
6264
// Valid HTTP agent names for Got-style agent configuration compatibility.
63-
export const httpAgentNames = new Set(['http', 'https', 'http2'])
65+
export const httpAgentNames = new SetCtor(['http', 'https', 'http2'])
6466

6567
// Public security policy.
66-
export const publicPolicy = new Map<ALERT_TYPE, ALERT_ACTION>([
68+
export const publicPolicy = new MapCtor<ALERT_TYPE, ALERT_ACTION>([
6769
// error (1):
6870
['malware', 'error'],
6971
// warn (7):

src/http-client.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ import { isError } from '@socketsecurity/lib/errors'
33
import { httpRequest } from '@socketsecurity/lib/http-request'
44
import { jsonParse } from '@socketsecurity/lib/json/parse'
55
import { perfTimer } from '@socketsecurity/lib/performance'
6+
import {
7+
DateNow,
8+
SetCtor,
9+
StringPrototypeTrim,
10+
} from '@socketsecurity/lib/primordials'
611

712
import {
813
MAX_RESPONSE_SIZE,
@@ -44,7 +49,7 @@ export async function createDeleteRequest(
4449
urlPath: string,
4550
options?: RequestOptionsWithHooks | undefined,
4651
): Promise<HttpResponse> {
47-
const startTime = Date.now()
52+
const startTime = DateNow()
4853
const url = `${baseUrl}${urlPath}`
4954
const method = 'DELETE'
5055
const { hooks, ...rawOpts } = {
@@ -74,7 +79,7 @@ export async function createDeleteRequest(
7479
hooks.onResponse({
7580
method,
7681
url,
77-
duration: Date.now() - startTime,
82+
duration: DateNow() - startTime,
7883
status: response.status,
7984
statusText: response.statusText,
8085
headers: sanitizeHeaders(response.headers),
@@ -87,7 +92,7 @@ export async function createDeleteRequest(
8792
hooks.onResponse({
8893
method,
8994
url,
90-
duration: Date.now() - startTime,
95+
duration: DateNow() - startTime,
9196
error: e as Error,
9297
})
9398
}
@@ -101,7 +106,7 @@ export async function createGetRequest(
101106
urlPath: string,
102107
options?: RequestOptionsWithHooks | undefined,
103108
): Promise<HttpResponse> {
104-
const startTime = Date.now()
109+
const startTime = DateNow()
105110
const url = `${baseUrl}${urlPath}`
106111
const method = 'GET'
107112
const stopTimer = perfTimer('http:get', { urlPath })
@@ -133,7 +138,7 @@ export async function createGetRequest(
133138
hooks.onResponse({
134139
method,
135140
url,
136-
duration: Date.now() - startTime,
141+
duration: DateNow() - startTime,
137142
status: response.status,
138143
statusText: response.statusText,
139144
headers: sanitizeHeaders(response.headers),
@@ -148,7 +153,7 @@ export async function createGetRequest(
148153
hooks.onResponse({
149154
method,
150155
url,
151-
duration: Date.now() - startTime,
156+
duration: DateNow() - startTime,
152157
error: e as Error,
153158
})
154159
}
@@ -164,7 +169,7 @@ export async function createRequestWithJson(
164169
json: unknown,
165170
options?: RequestOptionsWithHooks | undefined,
166171
): Promise<HttpResponse> {
167-
const startTime = Date.now()
172+
const startTime = DateNow()
168173
const url = `${baseUrl}${urlPath}`
169174
const stopTimer = perfTimer(`http:${method.toLowerCase()}`, {
170175
urlPath,
@@ -203,7 +208,7 @@ export async function createRequestWithJson(
203208
hooks.onResponse({
204209
method,
205210
url,
206-
duration: Date.now() - startTime,
211+
duration: DateNow() - startTime,
207212
status: response.status,
208213
statusText: response.statusText,
209214
headers: sanitizeHeaders(response.headers),
@@ -218,7 +223,7 @@ export async function createRequestWithJson(
218223
hooks.onResponse({
219224
method,
220225
url,
221-
duration: Date.now() - startTime,
226+
duration: DateNow() - startTime,
222227
error: e as Error,
223228
})
224229
}
@@ -335,9 +340,10 @@ export function reshapeArtifactForPublicPolicy<
335340
policy?: Map<string, string> | undefined,
336341
): T {
337342
if (!isAuthenticated) {
338-
const allowedActions = actions?.trim()
339-
? new Set(actions.split(','))
340-
: undefined
343+
const allowedActions =
344+
actions && StringPrototypeTrim(actions)
345+
? new SetCtor(actions.split(','))
346+
: undefined
341347
const resolvedPolicy = policy ?? defaultPublicPolicy
342348

343349
const reshapeArtifact = (artifact: SocketArtifactWithExtras) => ({

src/quota-utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { existsSync, readFileSync } from 'node:fs'
33
import { join } from 'node:path'
44

55
import { memoize, once } from '@socketsecurity/lib/memoization'
6+
import { ErrorCtor } from '@socketsecurity/lib/primordials'
67

78
import type { SocketSdkOperations } from './types'
89

@@ -43,7 +44,7 @@ const loadRequirements = once((): Requirements => {
4344
return JSON.parse(data) as Requirements
4445
} catch (e) {
4546
/* c8 ignore next 2 - Error wrapping tested in isolation but memoization prevents coverage in main test run */
46-
throw new Error('Failed to load SDK method requirements', { cause: e })
47+
throw new ErrorCtor('Failed to load SDK method requirements', { cause: e })
4748
}
4849
})
4950

src/socket-sdk-class.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ import { validateFiles } from '@socketsecurity/lib/fs'
1414
import { jsonParse } from '@socketsecurity/lib/json/parse'
1515
import { getOwn, isObjectObject } from '@socketsecurity/lib/objects'
1616
import { pRetry } from '@socketsecurity/lib/promises'
17+
import {
18+
ArrayIsArray,
19+
ErrorCtor,
20+
StringPrototypeTrim,
21+
TypeErrorCtor,
22+
} from '@socketsecurity/lib/primordials'
1723
import { setMaxEventTargetListeners } from '@socketsecurity/lib/suppress-warnings'
1824
import { urlSearchParamAsBoolean } from '@socketsecurity/lib/url'
1925

@@ -144,11 +150,11 @@ export class SocketSdk {
144150
// Input validation for API token.
145151
const MAX_API_TOKEN_LENGTH = 1024
146152
if (typeof apiToken !== 'string') {
147-
throw new TypeError('"apiToken" is required and must be a string')
153+
throw new TypeErrorCtor('"apiToken" is required and must be a string')
148154
}
149-
const trimmedToken = apiToken.trim()
155+
const trimmedToken = StringPrototypeTrim(apiToken)
150156
if (!trimmedToken) {
151-
throw new Error('"apiToken" cannot be empty or whitespace-only')
157+
throw new ErrorCtor('"apiToken" cannot be empty or whitespace-only')
152158
}
153159
if (trimmedToken.length > MAX_API_TOKEN_LENGTH) {
154160
throw new Error(
@@ -480,7 +486,7 @@ export class SocketSdk {
480486
}
481487
}
482488
if (!(error instanceof ResponseError)) {
483-
throw new Error('Unexpected Socket API error', {
489+
throw new ErrorCtor('Unexpected Socket API error', {
484490
cause: error,
485491
})
486492
}
@@ -656,7 +662,7 @@ export class SocketSdk {
656662
}
657663

658664
// Handle array of values (take first).
659-
const value = Array.isArray(retryAfterValue)
665+
const value = ArrayIsArray(retryAfterValue)
660666
? retryAfterValue[0]
661667
: retryAfterValue
662668

src/utils.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ import process from 'node:process'
77

88
import { memoize } from '@socketsecurity/lib/memoization'
99
import { normalizePath } from '@socketsecurity/lib/paths/normalize'
10+
import {
11+
PromiseWithResolvers,
12+
StringPrototypeEndsWith,
13+
StringPrototypeToLowerCase,
14+
StringPrototypeTrim,
15+
URLSearchParamsCtor,
16+
} from '@socketsecurity/lib/primordials'
1017

1118
import type { QueryParams } from './types'
1219

@@ -18,7 +25,7 @@ import type { QueryParams } from './types'
1825
* @returns Set of normalized words
1926
*/
2027
function normalizeToWordSet(s: string): Set<string> {
21-
const words = s.toLowerCase().match(/\w+/g)
28+
const words = StringPrototypeToLowerCase(s).match(/\w+/g)
2229
return new Set(words ?? [])
2330
}
2431

@@ -97,7 +104,7 @@ export function filterRedundantCause(
97104
errorCause: string | undefined,
98105
threshold = 0.6,
99106
): string | undefined {
100-
if (!errorCause || !errorCause.trim()) {
107+
if (!errorCause || !StringPrototypeTrim(errorCause)) {
101108
return undefined
102109
}
103110

@@ -122,7 +129,7 @@ export function filterRedundantCause(
122129
*/
123130
export const normalizeBaseUrl = memoize(
124131
(baseUrl: string): string => {
125-
return baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`
132+
return StringPrototypeEndsWith(baseUrl, '/') ? baseUrl : `${baseUrl}/`
126133
},
127134
{ name: 'normalizeBaseUrl' },
128135
)
@@ -135,8 +142,8 @@ export function promiseWithResolvers<T>(): ReturnType<
135142
typeof Promise.withResolvers<T>
136143
> {
137144
/* c8 ignore next 3 - polyfill for older Node versions without Promise.withResolvers */
138-
if (Promise.withResolvers) {
139-
return Promise.withResolvers<T>()
145+
if (PromiseWithResolvers) {
146+
return PromiseWithResolvers<T>()
140147
}
141148

142149
/* c8 ignore next 7 - polyfill implementation for older Node versions */
@@ -162,8 +169,8 @@ export function queryToSearchParams(
162169
| null
163170
| undefined,
164171
): URLSearchParams {
165-
const params = new URLSearchParams(
166-
init as ConstructorParameters<typeof URLSearchParams>[0],
172+
const params = new URLSearchParamsCtor(
173+
init as ConstructorParameters<typeof URLSearchParamsCtor>[0],
167174
)
168175
// Check if normalization is needed before creating a second instance.
169176
let needsNormalization = false
@@ -245,7 +252,7 @@ export function shouldOmitReason(
245252
threshold = 0.6,
246253
): boolean {
247254
// Omit empty/whitespace-only reasons
248-
if (!reason || !reason.trim()) {
255+
if (!reason || !StringPrototypeTrim(reason)) {
249256
return true
250257
}
251258

src/utils/header-sanitization.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* @fileoverview HTTP header sanitization utilities for secure logging.
33
* Provides functions to redact sensitive header values from logs.
44
*/
5+
import { ArrayIsArray } from '@socketsecurity/lib/primordials'
56

67
/**
78
* List of sensitive HTTP headers that should be redacted in logs.
@@ -29,7 +30,7 @@ export function sanitizeHeaders(
2930
}
3031

3132
// Handle readonly string[] case - this shouldn't normally happen for headers.
32-
if (Array.isArray(headers)) {
33+
if (ArrayIsArray(headers)) {
3334
return { headers: headers.join(', ') }
3435
}
3536

0 commit comments

Comments
 (0)