Skip to content

Commit 8f5985f

Browse files
committed
feat(primordials): close coverage gaps surfaced by socket-btm corpus
Audited socket-btm/packages/node-smol-builder/additions/source-patched/ lib/**/*.js — every primordial identifier referenced there should be exportable from @socketsecurity/lib/primordials. Diffed against the existing surface and closed the 22 gaps found. Added: - BufferCtor / BufferPrototypeSlice / BufferPrototypeToString (Node-only globals, typed `T | undefined` so browser code is forced into a null-check at the type level rather than crashing at runtime). - DatePrototypeGetTime / DatePrototypeToISOString / DatePrototypeValueOf. - IteratorPrototypeNext / IteratorPrototypeReturn — walks the iterator prototype chain to find whichever level owns `.next`, since some engines collapse the shared ancestor and others don't. - MapPrototype{Clear,Delete,Entries,ForEach,Get,Has,Keys,Set,Values}. - PromisePrototype{Catch,Finally,Then}. - SetPrototype{Add,Clear,Delete,Entries,ForEach,Has,Keys,Values}. - URLSearchParamsPrototype{Append,Delete,ForEach,Get,GetAll,Has,Set}. - WeakMapPrototype{Delete,Get,Has,Set}. - WeakSetPrototype{Add,Delete,Has}. Re-running the diff against btm now reports 0 missing primordials. Total exported surface: 203 (was 161). Test suite expanded to 74 tests (up from 64), with one focused block per new section and runtime-feature gates for Buffer/IteratorReturn so the suite passes both with and without the optional capabilities. Bump to 5.27.0 (additive, no breaking changes).
1 parent ab02430 commit 8f5985f

3 files changed

Lines changed: 322 additions & 1 deletion

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@socketsecurity/lib",
3-
"version": "5.26.0",
3+
"version": "5.27.0",
44
"packageManager": "pnpm@11.0.0-rc.5",
55
"license": "MIT",
66
"description": "Core utilities and infrastructure for Socket.dev security tools",

src/primordials.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ export const applyBind = bind.bind(apply) as <
4848
// ─── Constructors ──────────────────────────────────────────────────────
4949
export const ArrayCtor: ArrayConstructor = Array
5050
export const BooleanCtor: BooleanConstructor = Boolean
51+
// BufferCtor is a Node-only global; `undefined` in the browser. Callers
52+
// that import it in browser code get a type-safe `undefined` rather than
53+
// a runtime ReferenceError.
54+
export const BufferCtor: typeof globalThis.Buffer | undefined = (
55+
globalThis as { Buffer?: typeof globalThis.Buffer }
56+
).Buffer
5157
export const DateCtor: DateConstructor = Date
5258
export const ErrorCtor: ErrorConstructor = Error
5359
export const MapCtor: MapConstructor = Map
@@ -135,6 +141,28 @@ export const ArrayPrototypeUnshift = uncurryThis(Array.prototype.unshift) as <
135141
) => number
136142
export const ArrayPrototypeValues = uncurryThis(Array.prototype.values)
137143

144+
// ─── Buffer (prototype) ────────────────────────────────────────────────
145+
// Buffer is a Node-only global; these helpers are `undefined` in browsers.
146+
// Typed as `Function | undefined` so TS forces a null-check in cross-env code.
147+
export const BufferPrototypeSlice:
148+
| ((buf: Buffer, start?: number, end?: number) => Buffer)
149+
| undefined = BufferCtor ? uncurryThis(BufferCtor.prototype.slice) : undefined
150+
export const BufferPrototypeToString:
151+
| ((
152+
buf: Buffer,
153+
encoding?: BufferEncoding,
154+
start?: number,
155+
end?: number,
156+
) => string)
157+
| undefined = BufferCtor
158+
? uncurryThis(BufferCtor.prototype.toString)
159+
: undefined
160+
161+
// ─── Date (prototype) ──────────────────────────────────────────────────
162+
export const DatePrototypeGetTime = uncurryThis(Date.prototype.getTime)
163+
export const DatePrototypeToISOString = uncurryThis(Date.prototype.toISOString)
164+
export const DatePrototypeValueOf = uncurryThis(Date.prototype.valueOf)
165+
138166
// ─── Function ──────────────────────────────────────────────────────────
139167
export const FunctionPrototypeApply = uncurryThis(Function.prototype.apply) as (
140168
self: (...args: unknown[]) => unknown,
@@ -152,6 +180,40 @@ export const FunctionPrototypeCall = uncurryThis(Function.prototype.call) as (
152180
...args: unknown[]
153181
) => unknown
154182

183+
// ─── Iterator (prototype) ──────────────────────────────────────────────
184+
// Map#keys() / Set#values() / etc. share an iterator prototype chain.
185+
// In some engines `.next` lives on the immediate prototype; in others it
186+
// lives on a shared ancestor. Walk up until we find the level that owns
187+
// the method so `uncurryThis` grabs the same one regardless of engine.
188+
const _anyIterator = new Map().keys() as Iterator<unknown>
189+
let _iteratorLookup: object | null = Object.getPrototypeOf(_anyIterator)
190+
while (
191+
_iteratorLookup &&
192+
typeof (_iteratorLookup as { next?: unknown }).next !== 'function'
193+
) {
194+
_iteratorLookup = Object.getPrototypeOf(_iteratorLookup)
195+
}
196+
const _iteratorProto = _iteratorLookup as {
197+
next: (this: Iterator<unknown>) => IteratorResult<unknown>
198+
return?: (this: Iterator<unknown>, value?: unknown) => IteratorResult<unknown>
199+
}
200+
export const IteratorPrototypeNext = uncurryThis(_iteratorProto.next)
201+
export const IteratorPrototypeReturn =
202+
typeof _iteratorProto.return === 'function'
203+
? uncurryThis(_iteratorProto.return)
204+
: undefined
205+
206+
// ─── Map (prototype) ───────────────────────────────────────────────────
207+
export const MapPrototypeClear = uncurryThis(Map.prototype.clear)
208+
export const MapPrototypeDelete = uncurryThis(Map.prototype.delete)
209+
export const MapPrototypeEntries = uncurryThis(Map.prototype.entries)
210+
export const MapPrototypeForEach = uncurryThis(Map.prototype.forEach)
211+
export const MapPrototypeGet = uncurryThis(Map.prototype.get)
212+
export const MapPrototypeHas = uncurryThis(Map.prototype.has)
213+
export const MapPrototypeKeys = uncurryThis(Map.prototype.keys)
214+
export const MapPrototypeSet = uncurryThis(Map.prototype.set)
215+
export const MapPrototypeValues = uncurryThis(Map.prototype.values)
216+
155217
// ─── Math ──────────────────────────────────────────────────────────────
156218
export const MathAbs = Math.abs
157219
export const MathCeil = Math.ceil
@@ -213,6 +275,11 @@ export const ObjectPrototypePropertyIsEnumerable = uncurryThis(
213275
export const ObjectPrototypeToString = uncurryThis(Object.prototype.toString)
214276
export const ObjectPrototypeValueOf = uncurryThis(Object.prototype.valueOf)
215277

278+
// ─── Promise (prototype) ───────────────────────────────────────────────
279+
export const PromisePrototypeCatch = uncurryThis(Promise.prototype.catch)
280+
export const PromisePrototypeFinally = uncurryThis(Promise.prototype.finally)
281+
export const PromisePrototypeThen = uncurryThis(Promise.prototype.then)
282+
216283
// ─── Reflect ───────────────────────────────────────────────────────────
217284
export const ReflectApply = Reflect.apply
218285
export const ReflectConstruct = Reflect.construct
@@ -242,6 +309,16 @@ export const RegExpPrototypeSymbolReplace = uncurryThis(
242309
) => string,
243310
)
244311

312+
// ─── Set (prototype) ───────────────────────────────────────────────────
313+
export const SetPrototypeAdd = uncurryThis(Set.prototype.add)
314+
export const SetPrototypeClear = uncurryThis(Set.prototype.clear)
315+
export const SetPrototypeDelete = uncurryThis(Set.prototype.delete)
316+
export const SetPrototypeEntries = uncurryThis(Set.prototype.entries)
317+
export const SetPrototypeForEach = uncurryThis(Set.prototype.forEach)
318+
export const SetPrototypeHas = uncurryThis(Set.prototype.has)
319+
export const SetPrototypeKeys = uncurryThis(Set.prototype.keys)
320+
export const SetPrototypeValues = uncurryThis(Set.prototype.values)
321+
245322
// ─── String (static) ───────────────────────────────────────────────────
246323
export const StringFromCharCode = String.fromCharCode
247324
export const StringFromCodePoint = String.fromCodePoint
@@ -326,3 +403,37 @@ export const SymbolFor = Symbol.for
326403
export const SymbolIterator = Symbol.iterator
327404
export const SymbolToPrimitive = Symbol.toPrimitive
328405
export const SymbolToStringTag = Symbol.toStringTag
406+
407+
// ─── URLSearchParams (prototype) ───────────────────────────────────────
408+
export const URLSearchParamsPrototypeAppend = uncurryThis(
409+
URLSearchParams.prototype.append,
410+
)
411+
export const URLSearchParamsPrototypeDelete = uncurryThis(
412+
URLSearchParams.prototype.delete,
413+
)
414+
export const URLSearchParamsPrototypeForEach = uncurryThis(
415+
URLSearchParams.prototype.forEach,
416+
)
417+
export const URLSearchParamsPrototypeGet = uncurryThis(
418+
URLSearchParams.prototype.get,
419+
)
420+
export const URLSearchParamsPrototypeGetAll = uncurryThis(
421+
URLSearchParams.prototype.getAll,
422+
)
423+
export const URLSearchParamsPrototypeHas = uncurryThis(
424+
URLSearchParams.prototype.has,
425+
)
426+
export const URLSearchParamsPrototypeSet = uncurryThis(
427+
URLSearchParams.prototype.set,
428+
)
429+
430+
// ─── WeakMap (prototype) ───────────────────────────────────────────────
431+
export const WeakMapPrototypeDelete = uncurryThis(WeakMap.prototype.delete)
432+
export const WeakMapPrototypeGet = uncurryThis(WeakMap.prototype.get)
433+
export const WeakMapPrototypeHas = uncurryThis(WeakMap.prototype.has)
434+
export const WeakMapPrototypeSet = uncurryThis(WeakMap.prototype.set)
435+
436+
// ─── WeakSet (prototype) ───────────────────────────────────────────────
437+
export const WeakSetPrototypeAdd = uncurryThis(WeakSet.prototype.add)
438+
export const WeakSetPrototypeDelete = uncurryThis(WeakSet.prototype.delete)
439+
export const WeakSetPrototypeHas = uncurryThis(WeakSet.prototype.has)

0 commit comments

Comments
 (0)