@socketregistry/packageurl-js
Advanced tools
| import type { PackageURL } from './package-url.js'; | ||
| export type PurlInput = PackageURL | string; | ||
| /** @internal Register the PackageURL class for string parsing in compare functions. */ | ||
| export declare function _registerPackageURL(ctor: typeof PackageURL): void; | ||
| /** | ||
| * Compare two PackageURLs for equality. | ||
| * | ||
| * Two PURLs are considered equal if their canonical string representations match. | ||
| * This comparison is case-sensitive after normalization. | ||
| * | ||
| * Accepts both PackageURL instances and PURL strings. Strings are parsed and | ||
| * normalized before comparison. | ||
| * | ||
| * @param a - First PackageURL or PURL string to compare | ||
| * @param b - Second PackageURL or PURL string to compare | ||
| * @returns true if the PURLs are equal, false otherwise | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const purl1 = PackageURL.fromString('pkg:npm/lodash@4.17.21') | ||
| * const purl2 = PackageURL.fromString('pkg:npm/lodash@4.17.21') | ||
| * | ||
| * equals(purl1, purl2) // -> true | ||
| * equals('pkg:npm/lodash@4.17.21', 'pkg:NPM/lodash@4.17.21') // -> true | ||
| * equals(purl1, 'pkg:npm/lodash@4.17.20') // -> false | ||
| * ``` | ||
| */ | ||
| export declare function equals(a: PurlInput, b: PurlInput): boolean; | ||
| /** | ||
| * Compare two PackageURLs for sorting. | ||
| * | ||
| * Returns a number indicating sort order: | ||
| * - Negative if `a` comes before `b` | ||
| * - Zero if they are equal | ||
| * - Positive if `a` comes after `b` | ||
| * | ||
| * Comparison is based on canonical string representation (lexicographic). | ||
| * | ||
| * Accepts both PackageURL instances and PURL strings. Strings are parsed and | ||
| * normalized before comparison. | ||
| * | ||
| * @param a - First PackageURL or PURL string to compare | ||
| * @param b - Second PackageURL or PURL string to compare | ||
| * @returns -1, 0, or 1 for sort ordering | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * compare('pkg:npm/aaa', 'pkg:npm/bbb') // -> -1 | ||
| * compare('pkg:npm/bbb', 'pkg:npm/aaa') // -> 1 | ||
| * | ||
| * // Use with Array.sort | ||
| * ['pkg:npm/bbb', 'pkg:npm/aaa'].sort(compare) | ||
| * // -> ['pkg:npm/aaa', 'pkg:npm/bbb'] | ||
| * ``` | ||
| */ | ||
| export declare function compare(a: PurlInput, b: PurlInput): -1 | 0 | 1; | ||
| /** | ||
| * Check if a PackageURL matches a pattern with wildcards. | ||
| * | ||
| * Supports glob-style wildcards: | ||
| * - asterisk matches any sequence of characters within a component | ||
| * - double asterisk matches any value including empty (for optional components) | ||
| * - question mark matches single character | ||
| * | ||
| * Pattern matching is performed on normalized PURLs (after type-specific | ||
| * normalization). Each component is matched independently. | ||
| * | ||
| * @param pattern - PURL string with wildcards | ||
| * @param purl - PackageURL instance to test | ||
| * @returns true if purl matches the pattern | ||
| * | ||
| * @example | ||
| * Wildcard in name: matches('pkg:npm/lodash-star', purl) | ||
| * Wildcard in namespace: matches('pkg:npm/@babel/star', purl) | ||
| * Wildcard in version: matches('pkg:npm/react@18.star', purl) | ||
| * Match any type: matches('pkg:star/lodash', purl) | ||
| * Optional version: matches('pkg:npm/lodash@star-star', purl) | ||
| * | ||
| * See test/pattern-matching.test.mts for comprehensive examples. | ||
| */ | ||
| export declare function matches(pattern: string, purl: PackageURL): boolean; | ||
| /** | ||
| * Create a reusable matcher function from a pattern. | ||
| * More efficient for testing multiple PURLs against the same pattern. | ||
| * | ||
| * The returned function can be used with Array methods like filter(), | ||
| * some(), and every() for efficient batch matching operations. | ||
| * | ||
| * @param pattern - PURL pattern string with wildcards | ||
| * @returns Function that tests PURLs against the pattern | ||
| * | ||
| * @example | ||
| * const isBabel = createMatcher('pkg:npm/@babel/star') | ||
| * packages.filter(isBabel) | ||
| * | ||
| * See test/pattern-matching.test.mts for comprehensive examples. | ||
| */ | ||
| export declare function createMatcher(pattern: string): (_purl: PackageURL) => boolean; |
| /** | ||
| * @fileoverview Registry existence check functions. | ||
| * | ||
| * This module provides functions to check if packages exist in their | ||
| * respective registries. Separated from the core module to allow | ||
| * consumers to import the parser without pulling in HTTP dependencies. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { npmExists, purlExists } from '@socketregistry/packageurl-js/exists' | ||
| * ``` | ||
| */ | ||
| export { cargoExists } from './purl-types/cargo.js'; | ||
| export { cocoapodsExists } from './purl-types/cocoapods.js'; | ||
| export { condaExists } from './purl-types/conda.js'; | ||
| export { dockerExists } from './purl-types/docker.js'; | ||
| export { packagistExists } from './purl-types/composer.js'; | ||
| export { cpanExists } from './purl-types/cpan.js'; | ||
| export { cranExists } from './purl-types/cran.js'; | ||
| export { gemExists } from './purl-types/gem.js'; | ||
| export { golangExists } from './purl-types/golang.js'; | ||
| export { hackageExists } from './purl-types/hackage.js'; | ||
| export { hexExists } from './purl-types/hex.js'; | ||
| export { mavenExists } from './purl-types/maven.js'; | ||
| export { npmExists } from './purl-types/npm.js'; | ||
| export { nugetExists } from './purl-types/nuget.js'; | ||
| export { pubExists } from './purl-types/pub.js'; | ||
| export { purlExists } from './purl-exists.js'; | ||
| export { pypiExists } from './purl-types/pypi.js'; | ||
| export { vscodeExtensionExists } from './purl-types/vscode-extension.js'; | ||
| export type { ExistsOptions, ExistsResult } from './purl-types/npm.js'; |
Sorry, the diff of this file is too big to display
| declare const uncurryThis: <T, A extends readonly unknown[], R>(fn: (this: T, ...args: A) => R) => (self: T, ...args: A) => R; | ||
| declare const applyBind: <T, A extends readonly unknown[], R>(fn: (this: T, ...args: A) => R) => (self: T, args: A) => R; | ||
| declare const MapCtor: MapConstructor; | ||
| declare const SetCtor: SetConstructor; | ||
| declare const URLCtor: typeof URL; | ||
| declare const URLSearchParamsCtor: typeof URLSearchParams; | ||
| declare const WeakSetCtor: WeakSetConstructor; | ||
| declare const encodeComponent: typeof encodeURIComponent; | ||
| declare const decodeComponent: typeof decodeURIComponent; | ||
| declare const JSONParse: (text: string, reviver?: ((this: any, key: string, value: any) => any) | undefined) => any; | ||
| declare const JSONStringify: { | ||
| (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; | ||
| (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; | ||
| }; | ||
| declare const ObjectCreate: { | ||
| (o: object | null): any; | ||
| (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; | ||
| }; | ||
| declare const ObjectEntries: { | ||
| <T>(o: ArrayLike<T> | { | ||
| [s: string]: T; | ||
| }): [string, T][]; | ||
| (o: {}): [string, any][]; | ||
| }; | ||
| declare const ObjectFreeze: { | ||
| <T extends Function>(f: T): T; | ||
| <T extends { | ||
| [idx: string]: object | U | null | undefined; | ||
| }, U extends string | number | bigint | symbol | boolean>(o: T): Readonly<T>; | ||
| <T>(o: T): Readonly<T>; | ||
| }; | ||
| declare const ObjectIsFrozen: (o: any) => boolean; | ||
| declare const ObjectKeys: { | ||
| (o: object): string[]; | ||
| (o: {}): string[]; | ||
| }; | ||
| declare const ObjectValues: { | ||
| <T>(o: ArrayLike<T> | { | ||
| [s: string]: T; | ||
| }): T[]; | ||
| (o: {}): any[]; | ||
| }; | ||
| declare const ArrayIsArray: (arg: any) => arg is any[]; | ||
| declare const ArrayPrototypeAt: (self: unknown, index: number) => any; | ||
| declare const ArrayPrototypeFilter: (self: unknown, predicate: (value: any, index: number, array: any[]) => unknown, thisArg?: any) => any[]; | ||
| declare const ArrayPrototypeFlatMap: <U, This = undefined>(self: unknown, callback: (this: This, value: any, index: number, array: any[]) => U | readonly U[], thisArg?: This | undefined) => U[]; | ||
| declare const ArrayPrototypeIncludes: (self: unknown, searchElement: any, fromIndex?: number | undefined) => boolean; | ||
| declare const ArrayPrototypeJoin: (self: unknown, separator?: string | undefined) => string; | ||
| declare const ArrayPrototypeMap: <U>(self: unknown, callbackfn: (value: any, index: number, array: any[]) => U, thisArg?: any) => U[]; | ||
| declare const ArrayPrototypePush: <T>(self: T[], ...items: T[]) => number; | ||
| declare const ArrayPrototypeSlice: (self: unknown, start?: number | undefined, end?: number | undefined) => any[]; | ||
| declare const ArrayPrototypeSome: (self: unknown, predicate: (value: any, index: number, array: any[]) => unknown, thisArg?: any) => boolean; | ||
| declare const ArrayPrototypeToSorted: (self: unknown, compareFn?: ((a: any, b: any) => number) | undefined) => any[]; | ||
| declare const ReflectApply: typeof Reflect.apply; | ||
| declare const ReflectDefineProperty: typeof Reflect.defineProperty; | ||
| declare const ReflectGetOwnPropertyDescriptor: typeof Reflect.getOwnPropertyDescriptor; | ||
| declare const ReflectOwnKeys: typeof Reflect.ownKeys; | ||
| declare const ReflectSetPrototypeOf: typeof Reflect.setPrototypeOf; | ||
| declare const RegExpPrototypeExec: (self: unknown, string: string) => RegExpExecArray | null; | ||
| declare const RegExpPrototypeTest: (self: unknown, string: string) => boolean; | ||
| declare const StringPrototypeCharCodeAt: (self: unknown, index: number) => number; | ||
| declare const StringPrototypeEndsWith: (self: unknown, searchString: string, endPosition?: number | undefined) => boolean; | ||
| declare const StringPrototypeIncludes: (self: unknown, searchString: string, position?: number | undefined) => boolean; | ||
| declare const StringPrototypeIndexOf: (self: unknown, searchString: string, position?: number | undefined) => number; | ||
| declare const StringPrototypeLastIndexOf: (self: unknown, searchString: string, position?: number | undefined) => number; | ||
| declare const StringPrototypeReplace: (self: unknown, searchValue: { | ||
| [Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string; | ||
| }, replacer: (substring: string, ...args: any[]) => string) => string; | ||
| declare const StringPrototypeReplaceAll: (self: string, searchValue: string, replaceValue: string) => string; | ||
| declare const StringPrototypeSlice: (self: unknown, start?: number | undefined, end?: number | undefined) => string; | ||
| declare const StringPrototypeSplit: (self: unknown, splitter: { | ||
| [Symbol.split](string: string, limit?: number | undefined): string[]; | ||
| }, limit?: number | undefined) => string[]; | ||
| declare const StringPrototypeStartsWith: (self: unknown, searchString: string, position?: number | undefined) => boolean; | ||
| declare const StringPrototypeToLowerCase: (self: unknown) => string; | ||
| declare const StringPrototypeToUpperCase: (self: unknown) => string; | ||
| declare const StringPrototypeTrim: (self: unknown) => string; | ||
| export { applyBind, ArrayIsArray, ArrayPrototypeAt, ArrayPrototypeFilter, ArrayPrototypeFlatMap, ArrayPrototypeIncludes, ArrayPrototypeJoin, ArrayPrototypeMap, ArrayPrototypePush, ArrayPrototypeSlice, ArrayPrototypeSome, ArrayPrototypeToSorted, decodeComponent, encodeComponent, JSONParse, JSONStringify, MapCtor, ObjectCreate, ObjectEntries, ObjectFreeze, ObjectIsFrozen, ObjectKeys, ObjectValues, ReflectApply, ReflectDefineProperty, ReflectGetOwnPropertyDescriptor, ReflectOwnKeys, ReflectSetPrototypeOf, RegExpPrototypeExec, RegExpPrototypeTest, SetCtor, StringPrototypeCharCodeAt, StringPrototypeEndsWith, StringPrototypeIncludes, StringPrototypeIndexOf, StringPrototypeLastIndexOf, StringPrototypeReplace, StringPrototypeReplaceAll, StringPrototypeSlice, StringPrototypeSplit, StringPrototypeStartsWith, StringPrototypeToLowerCase, StringPrototypeToUpperCase, StringPrototypeTrim, uncurryThis, URLCtor, URLSearchParamsCtor, WeakSetCtor, }; |
| import type { PackageURL } from './package-url.js'; | ||
| import type { ExistsResult, ExistsOptions } from './purl-types/npm.js'; | ||
| /** | ||
| * Check if a package exists in its registry. | ||
| * | ||
| * Generic wrapper that dispatches to type-specific existence checks based on | ||
| * the package URL type. Queries the appropriate registry (npm, PyPI, crates.io, | ||
| * rubygems.org, etc.) to verify package existence and retrieve latest version. | ||
| * | ||
| * **Supported types:** | ||
| * - `npm` - Node.js packages from npmjs.org | ||
| * - `pypi` - Python packages from pypi.org | ||
| * - `cargo` - Rust crates from crates.io | ||
| * - `gem` - Ruby gems from rubygems.org | ||
| * - `maven` - Java packages from Maven Central | ||
| * - `nuget` - .NET packages from nuget.org | ||
| * - `golang` - Go modules from proxy.golang.org | ||
| * - `composer` - PHP packages from packagist.org | ||
| * - `cocoapods` - iOS/macOS pods from trunk.cocoapods.org | ||
| * - `conda` - Conda packages from anaconda.org | ||
| * - `docker` - Docker images from Docker Hub | ||
| * - `pub` - Dart/Flutter packages from pub.dev | ||
| * - `hex` - Elixir/Erlang packages from hex.pm | ||
| * - `cpan` - Perl modules from metacpan.org | ||
| * - `cran` - R packages from cran.r-universe.dev | ||
| * - `hackage` - Haskell packages from hackage.haskell.org | ||
| * | ||
| * **Unsupported types:** Returns `{ exists: false, error: 'Unsupported type' }` | ||
| * | ||
| * **Caching:** Responses can be cached using a TTL cache to reduce registry | ||
| * requests. Pass `{ cache }` option with a cache instance from `createTtlCache()`. | ||
| * | ||
| * @param purl - PackageURL instance or PURL string to check | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { purlExists, PackageURL } from '@socketregistry/packageurl-js' | ||
| * | ||
| * // Check npm package | ||
| * const npmPurl = PackageURL.fromString('pkg:npm/lodash@4.17.21') | ||
| * const result = await purlExists(npmPurl) | ||
| * // -> { exists: true, latestVersion: '4.17.21' } | ||
| * | ||
| * // Check PyPI package | ||
| * const pypiPurl = PackageURL.fromString('pkg:pypi/requests@2.28.1') | ||
| * const result = await purlExists(pypiPurl) | ||
| * // -> { exists: true, latestVersion: '2.31.0' } | ||
| * | ||
| * // With caching | ||
| * import { createTtlCache } from '@socketsecurity/lib/cache-with-ttl' | ||
| * const cache = createTtlCache({ ttl: 5 * 60 * 1000, prefix: 'purl-registry' }) | ||
| * const result = await purlExists(npmPurl, { cache }) | ||
| * | ||
| * // Unsupported type | ||
| * const mavenPurl = PackageURL.fromString('pkg:maven/org.apache/commons@1.0') | ||
| * const result = await purlExists(mavenPurl) | ||
| * // -> { exists: false, error: 'Unsupported type: maven' } | ||
| * ``` | ||
| */ | ||
| export declare function purlExists(purl: PackageURL, options?: ExistsOptions): Promise<ExistsResult>; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize ALPM package URL. | ||
| * Lowercases both namespace and name. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize APK package URL. | ||
| * Lowercases both namespace and name. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize Bazel package URL. | ||
| * Lowercases name only. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Validate Bazel package URL. | ||
| * Bazel packages must have a version (for reproducible builds). | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize Bitbucket package URL. | ||
| * Lowercases both namespace and name. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize Bitnami package URL. | ||
| * Lowercases name only. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Check if a Cargo crate exists in crates.io. | ||
| * | ||
| * Queries crates.io at https://crates.io/api/v1/crates to verify crate | ||
| * existence and optionally validate a specific version. Returns the max_version | ||
| * from crate metadata. | ||
| * | ||
| * **Note:** crates.io requires a User-Agent header for API requests. | ||
| * | ||
| * **Caching:** Responses can be cached using a TTL cache to reduce registry | ||
| * requests. Pass `{ cache }` option with a cache instance from `createTtlCache()`. | ||
| * | ||
| * @param name - Crate name (e.g., 'serde', 'tokio') | ||
| * @param version - Optional version to validate (e.g., '1.0.152') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if crate exists | ||
| * const result = await cargoExists('serde') | ||
| * // -> { exists: true, latestVersion: '1.0.197' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await cargoExists('tokio', '1.35.0') | ||
| * // -> { exists: true, latestVersion: '1.36.0' } | ||
| * | ||
| * // With caching | ||
| * import { createTtlCache } from '@socketsecurity/lib/cache-with-ttl' | ||
| * const cache = createTtlCache({ ttl: 5 * 60 * 1000, prefix: 'cargo' }) | ||
| * const result = await cargoExists('serde', undefined, { cache }) | ||
| * | ||
| * // Non-existent crate | ||
| * const result = await cargoExists('this-crate-does-not-exist') | ||
| * // -> { exists: false, error: 'Crate not found' } | ||
| * ``` | ||
| */ | ||
| export declare function cargoExists(name: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| /** | ||
| * Validate Cargo package URL. | ||
| * Cargo packages must not have a namespace. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Check if a CocoaPod exists in the CocoaPods trunk. | ||
| * | ||
| * Queries trunk.cocoapods.org API to verify pod existence and retrieve | ||
| * the latest version. | ||
| * | ||
| * @param name - Pod name (e.g., 'Alamofire') | ||
| * @param version - Optional version to validate (e.g., '5.8.1') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if pod exists | ||
| * const result = await cocoapodsExists('Alamofire') | ||
| * // -> { exists: true, latestVersion: '5.8.1' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await cocoapodsExists('Alamofire', '5.8.1') | ||
| * // -> { exists: true, latestVersion: '5.8.1' } | ||
| * | ||
| * // Non-existent pod | ||
| * const result = await cocoapodsExists('FakePod') | ||
| * // -> { exists: false, error: 'Pod not found' } | ||
| * ``` | ||
| */ | ||
| export declare function cocoapodsExists(name: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| /** | ||
| * Validate CocoaPods package URL. | ||
| * Name cannot contain whitespace, plus (+) character, or begin with a period (.). | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize Composer package URL. | ||
| * Lowercases both namespace and name. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Check if a Composer package exists on Packagist. | ||
| * | ||
| * Queries Packagist.org API to verify package existence and retrieve | ||
| * the latest version. Composer packages have vendor/package format. | ||
| * | ||
| * @param name - Package name (e.g., 'http-foundation') | ||
| * @param namespace - Vendor name (e.g., 'symfony') | ||
| * @param version - Optional version to validate (e.g., 'v6.3.0') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if package exists | ||
| * const result = await packagistExists('http-foundation', 'symfony') | ||
| * // -> { exists: true, latestVersion: 'v6.3.0' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await packagistExists('http-foundation', 'symfony', 'v6.3.0') | ||
| * // -> { exists: true, latestVersion: 'v6.3.0' } | ||
| * | ||
| * // Non-existent package | ||
| * const result = await packagistExists('fake-package', 'vendor') | ||
| * // -> { exists: false, error: 'Package not found' } | ||
| * ``` | ||
| */ | ||
| export declare function packagistExists(name: string, namespace?: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Validate Conan package URL. | ||
| * If namespace is present, qualifiers are required. | ||
| * If channel qualifier is present, namespace is required. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| import type { ExistsOptions, ExistsResult } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize Conda package URL. | ||
| * Lowercases name only. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Validate Conda package URL. | ||
| * Conda packages must not have a namespace. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| /** | ||
| * Check if a Conda package exists in Anaconda.org. | ||
| * | ||
| * Queries Anaconda.org at https://api.anaconda.org/package to verify package | ||
| * existence and optionally validate a specific version. Returns the latest | ||
| * version from package metadata. | ||
| * | ||
| * **Note:** Defaults to conda-forge channel. Specify channel parameter for | ||
| * other channels like 'defaults', 'anaconda', etc. | ||
| * | ||
| * **Caching:** Responses can be cached using a TTL cache to reduce registry | ||
| * requests. Pass `{ cache }` option with a cache instance from `createTtlCache()`. | ||
| * | ||
| * @param name - Package name (e.g., 'numpy', 'pandas') | ||
| * @param version - Optional version to validate (e.g., '1.24.3') | ||
| * @param channel - Optional channel name (defaults to 'conda-forge') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if package exists (defaults to conda-forge) | ||
| * const result = await condaExists('numpy') | ||
| * // -> { exists: true, latestVersion: '1.26.3' } | ||
| * | ||
| * // Check with custom channel | ||
| * const result = await condaExists('numpy', undefined, 'defaults') | ||
| * // -> { exists: true, latestVersion: '1.26.3' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await condaExists('pandas', '2.1.4') | ||
| * // -> { exists: true, latestVersion: '2.2.0' } | ||
| * | ||
| * // With caching | ||
| * import { createTtlCache } from '@socketsecurity/lib/cache-with-ttl' | ||
| * const cache = createTtlCache({ ttl: 5 * 60 * 1000, prefix: 'conda' }) | ||
| * const result = await condaExists('numpy', undefined, undefined, { cache }) | ||
| * | ||
| * // Non-existent package | ||
| * const result = await condaExists('this-package-does-not-exist') | ||
| * // -> { exists: false, error: 'Package not found' } | ||
| * ``` | ||
| */ | ||
| export declare function condaExists(name: string, version?: string, channel?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| export {}; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Check if a Perl module exists on CPAN. | ||
| * | ||
| * Queries MetaCPAN API to verify module existence and retrieve | ||
| * the latest version. | ||
| * | ||
| * @param name - Module name (e.g., 'Moose') | ||
| * @param version - Optional version to validate (e.g., '2.2206') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if module exists | ||
| * const result = await cpanExists('Moose') | ||
| * // -> { exists: true, latestVersion: '2.2206' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await cpanExists('Moose', '2.2206') | ||
| * // -> { exists: true, latestVersion: '2.2206' } | ||
| * | ||
| * // Non-existent module | ||
| * const result = await cpanExists('FakeModule') | ||
| * // -> { exists: false, error: 'Module not found' } | ||
| * ``` | ||
| */ | ||
| export declare function cpanExists(name: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| /** | ||
| * Validate CPAN package URL. | ||
| * CPAN namespace (author/publisher ID) must be uppercase when present. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Check if an R package exists on CRAN. | ||
| * | ||
| * Queries CRAN database to verify package existence and retrieve | ||
| * the latest version. Note: CRAN provides a list of all packages | ||
| * via their packages.rds file. | ||
| * | ||
| * @param name - Package name (e.g., 'ggplot2') | ||
| * @param version - Optional version to validate (e.g., '3.4.4') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if package exists | ||
| * const result = await cranExists('ggplot2') | ||
| * // -> { exists: true, latestVersion: '3.4.4' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await cranExists('ggplot2', '3.4.4') | ||
| * // -> { exists: true, latestVersion: '3.4.4' } | ||
| * | ||
| * // Non-existent package | ||
| * const result = await cranExists('FakePackage') | ||
| * // -> { exists: false, error: 'Package not found' } | ||
| * ``` | ||
| */ | ||
| export declare function cranExists(name: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| /** | ||
| * Validate CRAN package URL. | ||
| * CRAN packages require a version. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize Debian package URL. | ||
| * Lowercases both namespace and name. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| import type { ExistsOptions, ExistsResult } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize Docker package URL. | ||
| * Lowercases name only (namespace is case-sensitive for registry hosts). | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Check if a Docker image exists in Docker Hub. | ||
| * | ||
| * Queries Docker Hub API at https://hub.docker.com/v2/repositories to verify | ||
| * image existence and optionally validate a specific tag. Returns the latest | ||
| * tag if no specific tag is requested. | ||
| * | ||
| * **Note:** Docker Hub has rate limits for unauthenticated requests. | ||
| * | ||
| * **Caching:** Responses can be cached using a TTL cache to reduce registry | ||
| * requests. Pass `{ cache }` option with a cache instance from `createTtlCache()`. | ||
| * | ||
| * @param name - Image name (e.g., 'nginx', 'redis') | ||
| * @param namespace - Optional namespace/repository (e.g., 'library' for official images) | ||
| * @param version - Optional tag to validate (e.g., 'latest', '1.25.3') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest tag | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if official image exists | ||
| * const result = await dockerExists('nginx', 'library') | ||
| * // -> { exists: true, latestVersion: 'latest' } | ||
| * | ||
| * // Check user image | ||
| * const result = await dockerExists('myapp', 'myuser') | ||
| * // -> { exists: true, latestVersion: 'v1.0.0' } | ||
| * | ||
| * // Validate specific tag | ||
| * const result = await dockerExists('nginx', 'library', '1.25.3') | ||
| * // -> { exists: true, latestVersion: 'latest' } | ||
| * | ||
| * // With caching | ||
| * import { createTtlCache } from '@socketsecurity/lib/cache-with-ttl' | ||
| * const cache = createTtlCache({ ttl: 5 * 60 * 1000, prefix: 'docker' }) | ||
| * const result = await dockerExists('nginx', 'library', undefined, { cache }) | ||
| * | ||
| * // Non-existent image | ||
| * const result = await dockerExists('this-image-does-not-exist', 'library') | ||
| * // -> { exists: false, error: 'Image not found' } | ||
| * ``` | ||
| */ | ||
| export declare function dockerExists(name: string, namespace?: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| export {}; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Check if a Ruby gem exists in rubygems.org. | ||
| * | ||
| * Queries rubygems.org at https://rubygems.org/api/v1/versions to verify gem | ||
| * existence and optionally validate a specific version. Returns the latest | ||
| * version from the versions array. | ||
| * | ||
| * **Caching:** Responses can be cached using a TTL cache to reduce registry | ||
| * requests. Pass `{ cache }` option with a cache instance from `createTtlCache()`. | ||
| * | ||
| * @param name - Gem name (e.g., 'rails', 'rake') | ||
| * @param version - Optional version to validate (e.g., '7.0.0') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if gem exists | ||
| * const result = await gemExists('rails') | ||
| * // -> { exists: true, latestVersion: '7.1.3' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await gemExists('rake', '13.0.0') | ||
| * // -> { exists: true, latestVersion: '13.1.0' } | ||
| * | ||
| * // With caching | ||
| * import { createTtlCache } from '@socketsecurity/lib/cache-with-ttl' | ||
| * const cache = createTtlCache({ ttl: 5 * 60 * 1000, prefix: 'gem' }) | ||
| * const result = await gemExists('rails', undefined, { cache }) | ||
| * | ||
| * // Non-existent gem | ||
| * const result = await gemExists('this-gem-does-not-exist') | ||
| * // -> { exists: false, error: 'Gem not found' } | ||
| * ``` | ||
| */ | ||
| export declare function gemExists(name: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| /** | ||
| * Validate RubyGem package URL. | ||
| * Gem packages must not have a namespace. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| /** | ||
| * @fileoverview Generic PURL type (minimal implementation). | ||
| * https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#generic | ||
| * | ||
| * The generic type is used when no specific package type applies. | ||
| * It has no specific normalization or validation rules beyond the base PURL spec. | ||
| */ | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize generic package URL. | ||
| * No type-specific normalization for generic packages. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize GitHub package URL. | ||
| * Lowercases both namespace and name. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize GitLab package URL. | ||
| * Lowercases both namespace and name. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Check if a Go module exists in the Go module proxy. | ||
| * | ||
| * Queries proxy.golang.org to verify module existence and retrieve | ||
| * the latest version. Go module names are typically full import paths | ||
| * like 'github.com/user/repo'. | ||
| * | ||
| * @param name - Full module path (e.g., 'github.com/gorilla/mux') | ||
| * @param namespace - Optional namespace (combined with name if provided) | ||
| * @param version - Optional version to validate (e.g., 'v1.8.0') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if module exists | ||
| * const result = await golangExists('github.com/gorilla/mux') | ||
| * // -> { exists: true, latestVersion: 'v1.8.0' } | ||
| * | ||
| * // With namespace (constructs full path) | ||
| * const result = await golangExists('mux', 'github.com/gorilla') | ||
| * // -> { exists: true, latestVersion: 'v1.8.0' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await golangExists('github.com/gorilla/mux', undefined, 'v1.8.0') | ||
| * // -> { exists: true, latestVersion: 'v1.8.0' } | ||
| * | ||
| * // Non-existent module | ||
| * const result = await golangExists('github.com/fake/module') | ||
| * // -> { exists: false, error: 'Module not found' } | ||
| * ``` | ||
| */ | ||
| export declare function golangExists(name: string, namespace?: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| /** | ||
| * Validate Golang package URL. | ||
| * If version starts with "v", it must be followed by a valid semver version. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| /** | ||
| * Check if a Haskell package exists on Hackage. | ||
| * | ||
| * Queries Hackage API to verify package existence and retrieve | ||
| * the latest version. | ||
| * | ||
| * @param name - Package name (e.g., 'aeson') | ||
| * @param version - Optional version to validate (e.g., '2.2.0.0') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if package exists | ||
| * const result = await hackageExists('aeson') | ||
| * // -> { exists: true, latestVersion: '2.2.0.0' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await hackageExists('aeson', '2.2.0.0') | ||
| * // -> { exists: true, latestVersion: '2.2.0.0' } | ||
| * | ||
| * // Non-existent package | ||
| * const result = await hackageExists('fake-package') | ||
| * // -> { exists: false, error: 'Package not found' } | ||
| * ``` | ||
| */ | ||
| export declare function hackageExists(name: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Check if an Elixir/Erlang package exists on hex.pm. | ||
| * | ||
| * Queries hex.pm API to verify package existence and retrieve | ||
| * the latest version. | ||
| * | ||
| * @param name - Package name (e.g., 'phoenix') | ||
| * @param version - Optional version to validate (e.g., '1.7.10') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if package exists | ||
| * const result = await hexExists('phoenix') | ||
| * // -> { exists: true, latestVersion: '1.7.10' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await hexExists('phoenix', '1.7.10') | ||
| * // -> { exists: true, latestVersion: '1.7.10' } | ||
| * | ||
| * // Non-existent package | ||
| * const result = await hexExists('fake_package') | ||
| * // -> { exists: false, error: 'Package not found' } | ||
| * ``` | ||
| */ | ||
| export declare function hexExists(name: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| /** | ||
| * Normalize Hex package URL. | ||
| * Lowercases both namespace and name. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize Hugging Face package URL. | ||
| * Lowercases version only. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize Julia package URL. | ||
| * No normalization - Julia package names are case-sensitive. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Validate Julia package URL. | ||
| * Julia packages must not have a namespace. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize LuaRocks package URL. | ||
| * Lowercases version only. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Check if a Maven package exists in Maven Central. | ||
| * | ||
| * Queries search.maven.org API to verify package existence and retrieve | ||
| * the latest version. Maven packages are identified by group ID (namespace) | ||
| * and artifact ID (name). | ||
| * | ||
| * @param name - Artifact ID (e.g., 'commons-lang3') | ||
| * @param namespace - Group ID (e.g., 'org.apache.commons') | ||
| * @param version - Optional version to validate (e.g., '3.12.0') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if package exists | ||
| * const result = await mavenExists('commons-lang3', 'org.apache.commons') | ||
| * // -> { exists: true, latestVersion: '3.12.0' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await mavenExists('commons-lang3', 'org.apache.commons', '3.12.0') | ||
| * // -> { exists: true, latestVersion: '3.12.0' } | ||
| * | ||
| * // Non-existent package | ||
| * const result = await mavenExists('fake-artifact', 'com.example') | ||
| * // -> { exists: false, error: 'Package not found' } | ||
| * ``` | ||
| */ | ||
| export declare function mavenExists(name: string, namespace?: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| /** | ||
| * Validate Maven package URL. | ||
| * Maven packages require a namespace (groupId). | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize MLflow package URL. | ||
| * Lowercases name only if repository_url qualifier contains 'databricks'. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Validate MLflow package URL. | ||
| * MLflow packages must not have a namespace. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| import type { TtlCache } from '@socketsecurity/lib/cache-with-ttl'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Result of package existence check. | ||
| */ | ||
| export type ExistsResult = { | ||
| exists: boolean; | ||
| latestVersion?: string; | ||
| error?: string; | ||
| }; | ||
| /** | ||
| * Options for registry existence checks. | ||
| */ | ||
| export type ExistsOptions = { | ||
| /** | ||
| * Optional TTL cache instance for caching registry responses. | ||
| * If provided, responses will be cached with configured TTL. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { createTtlCache } from '@socketsecurity/lib/cache-with-ttl' | ||
| * import { npmExists } from '@socketregistry/packageurl-js' | ||
| * | ||
| * const cache = createTtlCache({ ttl: 5 * 60 * 1000, prefix: 'npm-registry' }) | ||
| * const result = await npmExists('lodash', undefined, undefined, { cache }) | ||
| * ``` | ||
| */ | ||
| cache?: TtlCache; | ||
| }; | ||
| /** | ||
| * Components parsed from npm package specifier. | ||
| * Includes namespace (for scoped packages), name, and version. | ||
| */ | ||
| export type NpmPackageComponents = { | ||
| namespace: string | undefined; | ||
| name: string; | ||
| version: string | undefined; | ||
| }; | ||
| /** | ||
| * Normalize npm package URL. | ||
| * https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#npm | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Check if an npm package exists in the registry. | ||
| * | ||
| * Queries the npm registry at https://registry.npmjs.org to verify package | ||
| * existence and optionally validate a specific version. Returns the latest | ||
| * version from dist-tags. | ||
| * | ||
| * **Caching:** Responses can be cached using a TTL cache to reduce registry | ||
| * requests. Pass `{ cache }` option with a cache instance from `createTtlCache()`. | ||
| * | ||
| * @param name - Package name (e.g., 'lodash', 'core' for scoped packages) | ||
| * @param namespace - Optional namespace/scope (e.g., '@babel') | ||
| * @param version - Optional version to validate (e.g., '4.17.21') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if package exists | ||
| * const result = await npmExists('lodash') | ||
| * // -> { exists: true, latestVersion: '4.17.21' } | ||
| * | ||
| * // Check scoped package | ||
| * const result = await npmExists('core', '@babel') | ||
| * // -> { exists: true, latestVersion: '7.23.0' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await npmExists('lodash', undefined, '4.17.21') | ||
| * // -> { exists: true, latestVersion: '4.17.21' } | ||
| * | ||
| * // With caching | ||
| * import { createTtlCache } from '@socketsecurity/lib/cache-with-ttl' | ||
| * const cache = createTtlCache({ ttl: 5 * 60 * 1000, prefix: 'npm' }) | ||
| * const result = await npmExists('lodash', undefined, undefined, { cache }) | ||
| * | ||
| * // Non-existent package | ||
| * const result = await npmExists('this-package-does-not-exist') | ||
| * // -> { exists: false, error: 'Package not found' } | ||
| * ``` | ||
| */ | ||
| export declare function npmExists(name: string, namespace?: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| /** | ||
| * Parse npm package specifier into component data. | ||
| * | ||
| * Parses npm package specifiers into namespace, name, and version components. | ||
| * Handles scoped packages, version ranges, and normalizes version strings. | ||
| * | ||
| * **Supported formats:** | ||
| * - Basic packages: `lodash`, `lodash@4.17.21` | ||
| * - Scoped packages: `@babel/core`, `@babel/core@7.0.0` | ||
| * - Version ranges: `^4.17.21`, `~1.2.3`, `>=1.0.0` (prefixes stripped) | ||
| * - Dist-tags: `latest`, `next`, `beta` (passed through as version) | ||
| * | ||
| * **Not supported:** | ||
| * - Git URLs: `git+https://...` | ||
| * - File paths: `file:../package.tgz` | ||
| * - GitHub shortcuts: `user/repo#branch` | ||
| * - Aliases: `npm:package@version` | ||
| * | ||
| * **Note:** Dist-tags like `latest` are mutable and should be resolved to | ||
| * concrete versions for reproducible builds. This method passes them through | ||
| * as-is for convenience. | ||
| * | ||
| * @param specifier - npm package specifier (e.g., 'lodash@4.17.21', '@babel/core@^7.0.0') | ||
| * @returns Object with namespace, name, and version components | ||
| * @throws {Error} If specifier is not a string or is empty | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Basic packages | ||
| * parseNpmSpecifier('lodash@4.17.21') | ||
| * // -> { namespace: undefined, name: 'lodash', version: '4.17.21' } | ||
| * | ||
| * // Scoped packages | ||
| * parseNpmSpecifier('@babel/core@^7.0.0') | ||
| * // -> { namespace: '@babel', name: 'core', version: '7.0.0' } | ||
| * | ||
| * // Dist-tags (passed through) | ||
| * parseNpmSpecifier('react@latest') | ||
| * // -> { namespace: undefined, name: 'react', version: 'latest' } | ||
| * | ||
| * // No version | ||
| * parseNpmSpecifier('express') | ||
| * // -> { namespace: undefined, name: 'express', version: undefined } | ||
| * ``` | ||
| */ | ||
| export declare function parseNpmSpecifier(specifier: unknown): NpmPackageComponents; | ||
| /** | ||
| * Validate npm package URL. | ||
| * Validation based on https://github.com/npm/validate-npm-package-name/tree/v6.0.0 | ||
| * ISC License | ||
| * Copyright (c) 2015, npm, Inc | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Check if a NuGet package exists in NuGet.org. | ||
| * | ||
| * Queries the NuGet V3 API to verify package existence and retrieve | ||
| * the latest version. | ||
| * | ||
| * @param name - Package name (e.g., 'Newtonsoft.Json') | ||
| * @param version - Optional version to validate (e.g., '13.0.3') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if package exists | ||
| * const result = await nugetExists('Newtonsoft.Json') | ||
| * // -> { exists: true, latestVersion: '13.0.3' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await nugetExists('Newtonsoft.Json', '13.0.3') | ||
| * // -> { exists: true, latestVersion: '13.0.3' } | ||
| * | ||
| * // Non-existent package | ||
| * const result = await nugetExists('fake-package-xyz') | ||
| * // -> { exists: false, error: 'Package not found' } | ||
| * ``` | ||
| */ | ||
| export declare function nugetExists(name: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| /** | ||
| * Validate NuGet package URL. | ||
| * NuGet packages must not have a namespace. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize OCI package URL. | ||
| * Lowercases name and version per spec. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Validate OCI package URL. | ||
| * OCI packages must not have a namespace. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Validate OPAM package URL. | ||
| * OPAM packages must not have a namespace. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize OTP package URL. | ||
| * Lowercases name. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Validate OTP package URL. | ||
| * OTP packages must not have a namespace. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize Pub package URL. | ||
| * Lowercases name and replaces dashes with underscores. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Check if a Dart/Flutter package exists on pub.dev. | ||
| * | ||
| * Queries pub.dev API to verify package existence and retrieve | ||
| * the latest version. | ||
| * | ||
| * @param name - Package name (e.g., 'flutter_bloc') | ||
| * @param version - Optional version to validate (e.g., '8.1.3') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if package exists | ||
| * const result = await pubExists('flutter_bloc') | ||
| * // -> { exists: true, latestVersion: '8.1.3' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await pubExists('flutter_bloc', '8.1.3') | ||
| * // -> { exists: true, latestVersion: '8.1.3' } | ||
| * | ||
| * // Non-existent package | ||
| * const result = await pubExists('fake_package') | ||
| * // -> { exists: false, error: 'Package not found' } | ||
| * ``` | ||
| */ | ||
| export declare function pubExists(name: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| /** | ||
| * Validate Pub package URL. | ||
| * Name may only contain [a-z0-9_] characters. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| import type { ExistsResult, ExistsOptions } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize PyPI package URL. | ||
| * Lowercases namespace, name, and version, replaces underscores with dashes in name. | ||
| * Spec: namespace, name, and version are all case-insensitive. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Check if a PyPI package exists in the registry. | ||
| * | ||
| * Queries PyPI at https://pypi.org/pypi to verify package existence and | ||
| * optionally validate a specific version. Returns the latest version from | ||
| * package metadata. | ||
| * | ||
| * **Caching:** Responses can be cached using a TTL cache to reduce registry | ||
| * requests. Pass `{ cache }` option with a cache instance from `createTtlCache()`. | ||
| * | ||
| * @param name - Package name (e.g., 'requests', 'django') | ||
| * @param version - Optional version to validate (e.g., '2.28.1') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if package exists | ||
| * const result = await pypiExists('requests') | ||
| * // -> { exists: true, latestVersion: '2.31.0' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await pypiExists('django', '4.2.0') | ||
| * // -> { exists: true, latestVersion: '5.0.0' } | ||
| * | ||
| * // With caching | ||
| * import { createTtlCache } from '@socketsecurity/lib/cache-with-ttl' | ||
| * const cache = createTtlCache({ ttl: 5 * 60 * 1000, prefix: 'pypi' }) | ||
| * const result = await pypiExists('requests', undefined, { cache }) | ||
| * | ||
| * // Non-existent package | ||
| * const result = await pypiExists('this-package-does-not-exist') | ||
| * // -> { exists: false, error: 'Package not found' } | ||
| * ``` | ||
| */ | ||
| export declare function pypiExists(name: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize QPKG package URL. | ||
| * Lowercases namespace only. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize RPM package URL. | ||
| * Lowercases namespace only. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| /** | ||
| * @fileoverview Socket-specific PURL type (minimal implementation). | ||
| * | ||
| * The socket type is a non-standard type used internally by Socket.dev | ||
| * for package identification. It has no specific normalization or validation | ||
| * rules beyond the base PURL spec. | ||
| */ | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize socket package URL. | ||
| * No type-specific normalization for socket packages. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Validate SWID package URL. | ||
| * SWID requires a tag_id qualifier that must not be empty. | ||
| * If tag_id is a GUID, it must be lowercase. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Validate Swift package URL. | ||
| * Swift packages require both namespace and version. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| /** | ||
| * @fileoverview Unknown PURL type (minimal implementation). | ||
| * | ||
| * The unknown type is used when the package type cannot be determined. | ||
| * It has no specific normalization or validation rules beyond the base PURL spec. | ||
| */ | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize unknown package URL. | ||
| * No type-specific normalization for unknown packages. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| export {}; |
| import type { ExistsOptions, ExistsResult } from './npm.js'; | ||
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize VSCode extension package URL. | ||
| * Lowercases namespace (publisher), name (extension), and version per spec. | ||
| * Spec: namespace, name, and version are all case-insensitive. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Validate VSCode extension package URL. | ||
| * Checks namespace (publisher) and name (extension) for injection characters, | ||
| * and validates version as semver when present. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| /** | ||
| * Check if a VSCode extension exists in the Visual Studio Marketplace. | ||
| * | ||
| * Queries the VS Marketplace API to verify extension existence and optionally | ||
| * validate a specific version. Returns the latest version from extension metadata. | ||
| * | ||
| * **Note:** VS Marketplace requires specific headers for API access. | ||
| * | ||
| * **Caching:** Responses can be cached using a TTL cache to reduce registry | ||
| * requests. Pass `{ cache }` option with a cache instance from `createTtlCache()`. | ||
| * | ||
| * @param name - Extension name (e.g., 'vscode-eslint') | ||
| * @param namespace - Publisher name (e.g., 'dbaeumer') | ||
| * @param version - Optional version to validate (e.g., '2.4.2') | ||
| * @param options - Optional configuration including cache | ||
| * @returns Promise resolving to existence result with latest version | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Check if extension exists | ||
| * const result = await vscodeExtensionExists('vscode-eslint', 'dbaeumer') | ||
| * // -> { exists: true, latestVersion: '2.4.2' } | ||
| * | ||
| * // Validate specific version | ||
| * const result = await vscodeExtensionExists('vscode-eslint', 'dbaeumer', '2.4.0') | ||
| * // -> { exists: true, latestVersion: '2.4.2' } | ||
| * | ||
| * // With caching | ||
| * import { createTtlCache } from '@socketsecurity/lib/cache-with-ttl' | ||
| * const cache = createTtlCache({ ttl: 5 * 60 * 1000, prefix: 'vscode' }) | ||
| * const result = await vscodeExtensionExists('vscode-eslint', 'dbaeumer', undefined, { cache }) | ||
| * | ||
| * // Non-existent extension | ||
| * const result = await vscodeExtensionExists('non-existent', 'publisher') | ||
| * // -> { exists: false, error: 'Extension not found' } | ||
| * ``` | ||
| */ | ||
| export declare function vscodeExtensionExists(name: string, namespace?: string, version?: string, options?: ExistsOptions): Promise<ExistsResult>; | ||
| export {}; |
| interface PurlObject { | ||
| name: string; | ||
| namespace?: string | undefined; | ||
| qualifiers?: Record<string, string> | undefined; | ||
| subpath?: string | undefined; | ||
| type?: string | undefined; | ||
| version?: string | undefined; | ||
| } | ||
| /** | ||
| * Normalize Yocto package URL. | ||
| * Lowercases name. | ||
| */ | ||
| export declare function normalize(purl: PurlObject): PurlObject; | ||
| /** | ||
| * Validate Yocto package URL. | ||
| * Yocto packages must not have a namespace. | ||
| */ | ||
| export declare function validate(purl: PurlObject, throws: boolean): boolean; | ||
| export {}; |
| import type { PackageURL } from './package-url.js'; | ||
| /** | ||
| * Convert PackageURL instance to spec string (without scheme and type). | ||
| * | ||
| * Returns the package identity portion: namespace/name@version?qualifiers#subpath | ||
| * This is the purl equivalent of an npm "spec" — the package identity without | ||
| * the ecosystem prefix. | ||
| * | ||
| * @param purl - PackageURL instance to stringify | ||
| * @returns Spec string (e.g., '%40babel/core@7.0.0' for pkg:npm/%40babel/core@7.0.0) | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const purl = new PackageURL('npm', '@babel', 'core', '7.0.0') | ||
| * stringifySpec(purl) | ||
| * // -> '%40babel/core@7.0.0' | ||
| * ``` | ||
| */ | ||
| export declare function stringifySpec(purl: PackageURL): string; | ||
| /** | ||
| * Convert PackageURL instance to canonical PURL string. | ||
| * | ||
| * Serializes a PackageURL object into its canonical string representation | ||
| * according to the PURL specification. | ||
| * | ||
| * @param purl - PackageURL instance to stringify | ||
| * @returns Canonical PURL string (e.g., 'pkg:npm/lodash@4.17.21') | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const purl = new PackageURL('npm', undefined, 'lodash', '4.17.21') | ||
| * stringify(purl) | ||
| * // -> 'pkg:npm/lodash@4.17.21' | ||
| * ``` | ||
| */ | ||
| export declare function stringify(purl: PackageURL): string; |
| /** | ||
| * Valid VERS comparator operators. | ||
| */ | ||
| type VersComparator = '=' | '!=' | '<' | '<=' | '>' | '>='; | ||
| /** | ||
| * Special wildcard comparator matching all versions. | ||
| */ | ||
| type VersWildcard = '*'; | ||
| /** | ||
| * A single version constraint within a VERS range. | ||
| */ | ||
| type VersConstraint = { | ||
| comparator: VersComparator | VersWildcard; | ||
| version: string; | ||
| }; | ||
| /** | ||
| * VERS (VErsion Range Specifier) parser and evaluator. | ||
| * | ||
| * **Early adoption:** The VERS spec is pre-standard draft. This implementation | ||
| * supports semver-based schemes (npm, cargo, golang, gem, etc.). Additional | ||
| * version schemes may be added as the spec matures. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const range = Vers.parse('vers:npm/>=1.0.0|<2.0.0') | ||
| * range.contains('1.5.0') // true | ||
| * range.contains('2.0.0') // false | ||
| * range.toString() // 'vers:npm/>=1.0.0|<2.0.0' | ||
| * | ||
| * // Wildcard matches all versions | ||
| * Vers.parse('vers:semver/*').contains('999.0.0') // true | ||
| * ``` | ||
| */ | ||
| declare class Vers { | ||
| readonly scheme: string; | ||
| readonly constraints: readonly VersConstraint[]; | ||
| private constructor(); | ||
| /** | ||
| * Parse a VERS string. | ||
| * | ||
| * @param versStr - VERS string (e.g., 'vers:npm/>=1.0.0|<2.0.0') | ||
| * @returns Vers instance | ||
| * @throws {PurlError} If the string is not a valid VERS | ||
| */ | ||
| static parse(versStr: string): Vers; | ||
| /** | ||
| * Parse a VERS string. | ||
| * | ||
| * @param versStr - VERS string (e.g., 'vers:npm/>=1.0.0|<2.0.0') | ||
| * @returns Vers instance | ||
| * @throws {PurlError} If the string is not a valid VERS | ||
| */ | ||
| static fromString(versStr: string): Vers; | ||
| /** | ||
| * Check if a version is contained within this VERS range. | ||
| * | ||
| * Implements the VERS containment algorithm for semver-based schemes. | ||
| * | ||
| * @param version - Version string to check | ||
| * @returns true if the version matches the range | ||
| * @throws {PurlError} If the scheme is not supported | ||
| */ | ||
| contains(version: string): boolean; | ||
| /** | ||
| * Serialize to canonical VERS string. | ||
| */ | ||
| toString(): string; | ||
| } | ||
| export { Vers }; | ||
| export type { VersComparator, VersConstraint, VersWildcard }; |
+61
-0
@@ -7,5 +7,43 @@ # Changelog | ||
| ## [1.4.0](https://github.com/SocketDev/socket-packageurl-js/releases/tag/v1.4.0) - 2026-03-28 | ||
| ### Added | ||
| - **VERS parser**: First JavaScript implementation of the VERS (VErsion Range Specifier) companion spec to PURL. Supports parsing, serialization, and containment checking for semver-based schemes (npm, cargo, golang, gem, hex, pub, cran, swift) | ||
| - **URL-to-PURL conversion**: `UrlConverter.fromUrl()` converts registry URLs to PackageURLs across 27 hostnames and 17 purl types (npm, pypi, maven, cargo, nuget, github, gitlab, bitbucket, docker, hex, pub, cocoapods, hackage, conda, cpan, luarocks, huggingface, swift, cran, vscode) | ||
| - **`toSpec()` method**: Returns the package identity without the `pkg:type/` prefix (the npm "spec" equivalent) | ||
| - **`isValid()` static method**: Quick validation without throwing | ||
| - **`fromUrl()` static method**: Convenience wrapper for `UrlConverter.fromUrl()` | ||
| - **Immutable copy methods**: `withVersion()`, `withNamespace()`, `withQualifier()`, `withQualifiers()`, `withSubpath()` return new instances | ||
| - **PurlBuilder factories**: Added 18 new type factories (bitbucket, cocoapods, conan, conda, cran, deb, docker, github, gitlab, hackage, hex, huggingface, luarocks, oci, pub, rpm, swift, vscode-extension) | ||
| - **Injection character detection**: `containsInjectionCharacters()` utility for shell metacharacter detection | ||
| - **`vers` qualifier**: Added 6th standard qualifier per purl spec | ||
| - **`./exists` entry point**: Registry existence checks available via `@socketregistry/packageurl-js/exists` | ||
| ### Changed | ||
| - **Bundle size reduced 95%**: Core bundle is 178 KB (was 3.3 MB). Exists functions moved to separate entry point to avoid bundling HTTP dependencies | ||
| - **Primordials module**: All 43 built-in references captured at module load time via `uncurryThis` pattern (mirrors Node.js internals). Zero raw prototype method calls remain | ||
| - **Frozen constants**: Module-level Maps, Sets, regex patterns, and arrays are frozen | ||
| - **Null prototype objects**: All user-facing object literals use `__proto__: null` | ||
| - **Flyweight cache**: `fromString()` caches up to 1024 instances; `toString()` memoized | ||
| - **Version lowercasing**: Added for oci, pypi, and vscode-extension per upstream spec | ||
| ### Fixed | ||
| - **ReDoS prevention**: Consecutive `.*` groups collapsed in wildcard regex | ||
| - **Null byte rejection**: All string components reject `\x00` to prevent truncation in C-based consumers | ||
| - **VERS resource limits**: 1000 constraint maximum, MAX_SAFE_INTEGER validation | ||
| - **vscode-extension validation**: Rejects illegal characters in namespace, name, version, and platform qualifier | ||
| ### Security | ||
| - Prototype pollution resilience via primordials (captured String, Array, RegExp, Object, Reflect methods) | ||
| - Global tampering protection verified (replacing `global.URL` after import has no effect) | ||
| - Inline regex patterns hoisted to frozen module-scope constants | ||
| ## [1.3.5](https://github.com/SocketDev/socket-packageurl-js/releases/tag/v1.3.5) - 2025-11-02 | ||
| ### Changed | ||
| - Updated @socketsecurity/lib to 3.1.2 | ||
@@ -16,2 +54,3 @@ | ||
| ### Changed | ||
| - Bundled @socketsecurity/lib internally to reduce consumer dependencies | ||
@@ -21,2 +60,3 @@ - Improved build output with shortened module identifiers for better readability | ||
| ### Added | ||
| - Internal validation for bundle dependency configuration | ||
@@ -28,2 +68,3 @@ - Pre-commit and pre-push git hooks | ||
| ### Fixed | ||
| - Fixed reference to external file in build | ||
@@ -34,2 +75,3 @@ | ||
| ### Changed | ||
| - Disabled minification in build output for improved readability and debugging | ||
@@ -40,2 +82,3 @@ | ||
| ### Changed | ||
| - Use @socketsecurity/lib under the hood | ||
@@ -46,2 +89,3 @@ | ||
| ### Added | ||
| - Re-exported `PURL_Type` enum from `@socketsecurity/registry` for type-safe package ecosystem identifiers | ||
@@ -54,2 +98,3 @@ - Re-exported `EcosystemString` type for type annotations requiring valid PURL type strings | ||
| ### Added | ||
| - Type coverage configuration with 100% coverage requirement | ||
@@ -59,2 +104,3 @@ - Comprehensive backward compatibility tests for validation functions | ||
| ### Changed | ||
| - Converted validation functions to options pattern with backward compatibility | ||
@@ -65,2 +111,3 @@ - Renamed normalizePath to normalizePurlPath with options pattern | ||
| ### Fixed | ||
| - Fixed error handling and concurrency issues in test suite | ||
@@ -72,2 +119,3 @@ - Improved type safety with typed arrays replacing any[] | ||
| ### Changed | ||
| - Enhanced TypeScript strictness with explicit `| undefined` for optional properties and parameters | ||
@@ -80,2 +128,3 @@ - Added comprehensive JSDoc documentation for core classes | ||
| ### Added | ||
| - Type-specific validation for cocoapods package names | ||
@@ -93,2 +142,3 @@ - Name cannot contain whitespace | ||
| ### Fixed | ||
| - Error message formatting in validateStrings function | ||
@@ -99,2 +149,3 @@ | ||
| ### Fixed | ||
| - Fixed publishing workflow to ensure dist folder is built before npm publish | ||
@@ -106,2 +157,3 @@ - Changed prepublishOnly script to prevent accidental local publishing | ||
| ### Fixed | ||
| - Fixed tsgo transpilation bug that produced incorrect `exports.encodeComponent = void 0;` output | ||
@@ -112,2 +164,3 @@ | ||
| ### Changed | ||
| - Enhanced build performance and reliability | ||
@@ -119,2 +172,3 @@ - Improved package stability | ||
| ### Changed | ||
| - Removed pnpm engine requirement from package.json | ||
@@ -125,2 +179,3 @@ | ||
| ### Added | ||
| - **PackageURLBuilder**: Fluent API for constructing PackageURL instances with method chaining | ||
@@ -141,2 +196,3 @@ - Static factory methods for common package types (npm, pypi, maven, gem, golang, cargo, nuget, composer) | ||
| ### Changed | ||
| - Enhanced documentation with improved structure and readability | ||
@@ -146,2 +202,3 @@ - Added features section highlighting key benefits | ||
| ### Fixed | ||
| - Various improvements and fixes | ||
@@ -152,2 +209,3 @@ | ||
| ### Changed | ||
| - Updated implementation for PackageURL specification changes | ||
@@ -158,2 +216,3 @@ | ||
| ### Fixed | ||
| - Bug fixes and stability improvements | ||
@@ -164,2 +223,3 @@ | ||
| ### Added | ||
| - Initial Socket.dev optimized package override implementation | ||
@@ -170,4 +230,5 @@ | ||
| ### Added | ||
| - Initial release of @socketregistry/packageurl-js | ||
| - Socket.dev optimized package override for packageurl-js | ||
| - Full compatibility with original packageurl-js API |
@@ -1149,4 +1149,2 @@ [ | ||
| "Jody", | ||
| "joi-dataURI", | ||
| "joi-string-dataURI", | ||
| "jordenAngular", | ||
@@ -1153,0 +1151,0 @@ "jordenAngular2", |
@@ -1,5 +0,1 @@ | ||
| /** | ||
| * @fileoverview Shared constants used across the PURL library. | ||
| * Includes loop sentinels and reusable URL search parameter utilities. | ||
| */ | ||
| declare const LOOP_SENTINEL = 1000000; | ||
@@ -6,0 +2,0 @@ declare const REUSED_SEARCH_PARAMS: import("url").URLSearchParams; |
+1
-1
@@ -1,2 +0,2 @@ | ||
| declare const encodeComponent: typeof encodeURIComponent; | ||
| import { encodeComponent } from './primordials.js'; | ||
| /** | ||
@@ -3,0 +3,0 @@ * Encode package name component for URL. |
| /** | ||
| * @fileoverview Helper function for creating namespace objects. | ||
| * Organizes helper functions by property names with configurable defaults and sorting. | ||
| */ | ||
| /** | ||
| * Create namespace object organizing helpers by property names. | ||
@@ -7,0 +3,0 @@ */ |
+14
-3
@@ -31,3 +31,3 @@ /*! | ||
| * - PackageURL: Main class for parsing and constructing package URLs | ||
| * - PackageURLBuilder: Builder pattern for constructing package URLs | ||
| * - PurlBuilder: Builder pattern for constructing package URLs | ||
| * - PurlType: Type-specific normalization and validation rules | ||
@@ -40,7 +40,18 @@ * - PurlComponent: Component encoding/decoding utilities | ||
| * - Result utilities: Functional error handling with Ok/Err pattern | ||
| * - Parsers: Modular parsers for ecosystem-specific package specifiers | ||
| */ | ||
| export type { PURLString } from '@socketsecurity/lib/types'; | ||
| export { PURL_Type } from '@socketsecurity/lib/types'; | ||
| export type { DownloadUrl, RepositoryUrl, Result, } from './package-url.js'; | ||
| export type { DownloadUrl, PackageURLComponentValue, PackageURLObject, ParsedPurlComponents, RepositoryUrl, Result, } from './package-url.js'; | ||
| export type { ComponentEncoder, ComponentNormalizer, ComponentValidator, QualifiersObject, QualifiersValue, } from './purl-component.js'; | ||
| export type { NpmPackageComponents } from './purl-types/npm.js'; | ||
| export { Err, err, Ok, ok, PackageURL, PurlComponent, PurlQualifierNames, PurlType, ResultUtils, UrlConverter, } from './package-url.js'; | ||
| export { PackageURLBuilder } from './package-url-builder.js'; | ||
| export { PurlBuilder } from './package-url-builder.js'; | ||
| export { PurlError } from './error.js'; | ||
| export { compare, createMatcher, equals, matches } from './compare.js'; | ||
| export { parseNpmSpecifier } from './purl-types/npm.js'; | ||
| export type { ExistsOptions, ExistsResult } from './purl-types/npm.js'; | ||
| export { containsInjectionCharacters } from './strings.js'; | ||
| export { stringify, stringifySpec } from './stringify.js'; | ||
| export { Vers } from './vers.js'; | ||
| export type { VersComparator, VersConstraint, VersWildcard } from './vers.js'; |
| /** | ||
| * @fileoverview Object utility functions for type checking and immutable object creation. | ||
| * Provides object validation and recursive freezing utilities. | ||
| */ | ||
| import { isObject } from '@socketsecurity/lib/objects'; | ||
| /** | ||
| * Recursively freeze an object and all nested objects. | ||
@@ -12,2 +7,10 @@ * Uses breadth-first traversal with a queue for memory efficiency. | ||
| declare function recursiveFreeze<T>(value_: T): T; | ||
| /** | ||
| * Check if value is a non-null object. | ||
| * Inlined to avoid importing @socketsecurity/lib/objects which transitively | ||
| * pulls in sorts → semver → npm-pack (2.5 MB). | ||
| */ | ||
| declare function isObject(value: unknown): value is { | ||
| [key: PropertyKey]: unknown; | ||
| }; | ||
| export { isObject, recursiveFreeze }; |
@@ -30,3 +30,3 @@ /*! | ||
| * | ||
| * When using PackageURLBuilder in environments that mix ESM and CommonJS modules | ||
| * When using PurlBuilder in environments that mix ESM and CommonJS modules | ||
| * (such as Vitest tests importing CommonJS-compiled code as ESM), the instanceof | ||
@@ -37,3 +37,3 @@ * operator may not work reliably for checking if the built objects are instances | ||
| * This occurs because: | ||
| * - PackageURLBuilder internally imports PackageURL using CommonJS require() | ||
| * - PurlBuilder internally imports PackageURL using CommonJS require() | ||
| * - External code may import PackageURL using ESM import | ||
@@ -59,3 +59,3 @@ * - Node.js creates different wrapper objects for the same class | ||
| * ```typescript | ||
| * const purl = PackageURLBuilder | ||
| * const purl = PurlBuilder | ||
| * .npm() | ||
@@ -67,3 +67,3 @@ * .name('lodash') | ||
| */ | ||
| export declare class PackageURLBuilder { | ||
| export declare class PurlBuilder { | ||
| /** The package type (e.g., 'npm', 'pypi', 'maven'). */ | ||
@@ -144,23 +144,63 @@ private _type?; | ||
| /** | ||
| * Create a builder with the bitbucket package type preset. | ||
| * | ||
| * @example `PurlBuilder.bitbucket().namespace('owner').name('repo').build()` | ||
| */ | ||
| static bitbucket(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the cargo package type preset. | ||
| * | ||
| * This convenience method creates a new builder instance with the type | ||
| * already set to 'cargo', ready for building Rust crate URLs. | ||
| * @example `PurlBuilder.cargo().name('serde').version('1.0.0').build()` | ||
| */ | ||
| static cargo(): PackageURLBuilder; | ||
| static cargo(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the cocoapods package type preset. | ||
| * | ||
| * @example `PurlBuilder.cocoapods().name('Alamofire').version('5.9.1').build()` | ||
| */ | ||
| static cocoapods(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the composer package type preset. | ||
| * | ||
| * This convenience method creates a new builder instance with the type | ||
| * already set to 'composer', ready for building Composer package URLs. | ||
| * @example `PurlBuilder.composer().namespace('laravel').name('framework').build()` | ||
| */ | ||
| static composer(): PackageURLBuilder; | ||
| static composer(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the conan package type preset. | ||
| * | ||
| * @example `PurlBuilder.conan().name('zlib').version('1.3.1').build()` | ||
| */ | ||
| static conan(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the conda package type preset. | ||
| * | ||
| * @example `PurlBuilder.conda().name('numpy').version('1.26.4').build()` | ||
| */ | ||
| static conda(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the cran package type preset. | ||
| * | ||
| * @example `PurlBuilder.cran().name('ggplot2').version('3.5.0').build()` | ||
| */ | ||
| static cran(): PurlBuilder; | ||
| /** | ||
| * Create a new empty builder instance. | ||
| * | ||
| * This is a convenience factory method that returns a new PackageURLBuilder | ||
| * This is a convenience factory method that returns a new PurlBuilder | ||
| * instance ready for configuration. | ||
| */ | ||
| static create(): PackageURLBuilder; | ||
| static create(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the deb package type preset. | ||
| * | ||
| * @example `PurlBuilder.deb().namespace('debian').name('curl').version('8.5.0').build()` | ||
| */ | ||
| static deb(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the docker package type preset. | ||
| * | ||
| * @example `PurlBuilder.docker().namespace('library').name('nginx').version('latest').build()` | ||
| */ | ||
| static docker(): PurlBuilder; | ||
| /** | ||
| * Create a builder from an existing PackageURL instance. | ||
@@ -171,45 +211,99 @@ * | ||
| */ | ||
| static from(purl: PackageURL): PackageURLBuilder; | ||
| static from(purl: PackageURL): PurlBuilder; | ||
| /** | ||
| * Create a builder with the gem package type preset. | ||
| * | ||
| * This convenience method creates a new builder instance with the type | ||
| * already set to 'gem', ready for building Ruby gem URLs. | ||
| * @example `PurlBuilder.gem().name('rails').version('7.0.0').build()` | ||
| */ | ||
| static gem(): PackageURLBuilder; | ||
| static gem(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the github package type preset. | ||
| * | ||
| * @example `PurlBuilder.github().namespace('socketdev').name('socket-cli').build()` | ||
| */ | ||
| static github(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the gitlab package type preset. | ||
| * | ||
| * @example `PurlBuilder.gitlab().namespace('owner').name('project').build()` | ||
| */ | ||
| static gitlab(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the golang package type preset. | ||
| * | ||
| * This convenience method creates a new builder instance with the type | ||
| * already set to 'golang', ready for building Go package URLs. | ||
| * @example `PurlBuilder.golang().namespace('github.com/go').name('text').build()` | ||
| */ | ||
| static golang(): PackageURLBuilder; | ||
| static golang(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the hackage package type preset. | ||
| * | ||
| * @example `PurlBuilder.hackage().name('aeson').version('2.2.1.0').build()` | ||
| */ | ||
| static hackage(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the hex package type preset. | ||
| * | ||
| * @example `PurlBuilder.hex().name('phoenix').version('1.7.12').build()` | ||
| */ | ||
| static hex(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the huggingface package type preset. | ||
| * | ||
| * @example `PurlBuilder.huggingface().name('bert-base-uncased').build()` | ||
| */ | ||
| static huggingface(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the luarocks package type preset. | ||
| * | ||
| * @example `PurlBuilder.luarocks().name('luasocket').version('3.1.0').build()` | ||
| */ | ||
| static luarocks(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the maven package type preset. | ||
| * | ||
| * This convenience method creates a new builder instance with the type | ||
| * already set to 'maven', ready for building Maven package URLs. | ||
| * @example `PurlBuilder.maven().namespace('org.apache').name('commons-lang3').build()` | ||
| */ | ||
| static maven(): PackageURLBuilder; | ||
| static maven(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the npm package type preset. | ||
| * | ||
| * This convenience method creates a new builder instance with the type | ||
| * already set to 'npm', ready for building npm package URLs. | ||
| * @example `PurlBuilder.npm().name('lodash').version('4.17.21').build()` | ||
| */ | ||
| static npm(): PackageURLBuilder; | ||
| static npm(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the nuget package type preset. | ||
| * | ||
| * This convenience method creates a new builder instance with the type | ||
| * already set to 'nuget', ready for building NuGet package URLs. | ||
| * @example `PurlBuilder.nuget().name('Newtonsoft.Json').version('13.0.3').build()` | ||
| */ | ||
| static nuget(): PackageURLBuilder; | ||
| static nuget(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the oci package type preset. | ||
| * | ||
| * @example `PurlBuilder.oci().name('nginx').version('sha256:abc123').build()` | ||
| */ | ||
| static oci(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the pub package type preset. | ||
| * | ||
| * @example `PurlBuilder.pub().name('flutter').version('3.19.0').build()` | ||
| */ | ||
| static pub(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the pypi package type preset. | ||
| * | ||
| * This convenience method creates a new builder instance with the type | ||
| * already set to 'pypi', ready for building Python package URLs. | ||
| * @example `PurlBuilder.pypi().name('requests').version('2.31.0').build()` | ||
| */ | ||
| static pypi(): PackageURLBuilder; | ||
| static pypi(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the rpm package type preset. | ||
| * | ||
| * @example `PurlBuilder.rpm().namespace('fedora').name('curl').version('8.5.0').build()` | ||
| */ | ||
| static rpm(): PurlBuilder; | ||
| /** | ||
| * Create a builder with the swift package type preset. | ||
| * | ||
| * @example `PurlBuilder.swift().namespace('apple').name('swift-nio').version('2.64.0').build()` | ||
| */ | ||
| static swift(): PurlBuilder; | ||
| } |
+220
-13
@@ -1,9 +0,1 @@ | ||
| /** | ||
| * @fileoverview Package URL parsing and construction utilities. | ||
| * | ||
| * Note on instanceof checks: | ||
| * When this module is compiled to CommonJS and imported from ESM contexts, | ||
| * instanceof checks may fail due to module system interoperability issues. | ||
| * See package-url-builder.ts for detailed explanation and workarounds. | ||
| */ | ||
| import { PurlComponent } from './purl-component.js'; | ||
@@ -35,2 +27,15 @@ import { PurlQualifierNames } from './purl-qualifier-names.js'; | ||
| /** | ||
| * Type representing parsed PURL components as a tuple. | ||
| * Returned by PackageURL.parseString() in the order: | ||
| * [type, namespace, name, version, qualifiers, subpath] | ||
| */ | ||
| export type ParsedPurlComponents = [ | ||
| type: string | undefined, | ||
| namespace: string | undefined, | ||
| name: string | undefined, | ||
| version: string | undefined, | ||
| qualifiers: URLSearchParams | undefined, | ||
| subpath: string | undefined | ||
| ]; | ||
| /** | ||
| * Package URL parser and constructor implementing the PURL specification. | ||
@@ -43,9 +48,12 @@ * Provides methods to parse, construct, and manipulate Package URLs with validation and normalization. | ||
| __proto__: null; | ||
| Checksum: string; | ||
| DownloadUrl: string; | ||
| FileName: string; | ||
| RepositoryUrl: string; | ||
| DownloadUrl: string; | ||
| VcsUrl: string; | ||
| FileName: string; | ||
| Checksum: string; | ||
| Vers: string; | ||
| }; | ||
| static Type: Record<string, Record<string, unknown>>; | ||
| /** @internal Cached canonical string representation. */ | ||
| _cachedString?: string | undefined; | ||
| name?: string | undefined; | ||
@@ -59,3 +67,3 @@ namespace?: string | undefined; | ||
| /** | ||
| * Convert PackageURL to object for JSON.stringify compatibility. | ||
| * Convert PackageURL to object for JSONStringify compatibility. | ||
| */ | ||
@@ -71,4 +79,100 @@ toJSON(): PackageURLObject; | ||
| toObject(): PackageURLObject; | ||
| /** | ||
| * Get the package specifier string without the scheme and type prefix. | ||
| * | ||
| * Returns `namespace/name@version?qualifiers#subpath` — the package identity | ||
| * without the `pkg:type/` prefix. | ||
| * | ||
| * @returns Spec string (e.g., '@babel/core@7.0.0' for pkg:npm/%40babel/core@7.0.0) | ||
| */ | ||
| toSpec(): string; | ||
| toString(): string; | ||
| /** | ||
| * Create a new PackageURL with a different version. | ||
| * Returns a new instance — the original is unchanged. | ||
| * | ||
| * @param version - New version string | ||
| * @returns New PackageURL with the updated version | ||
| */ | ||
| withVersion(version: string | undefined): PackageURL; | ||
| /** | ||
| * Create a new PackageURL with a different namespace. | ||
| * Returns a new instance — the original is unchanged. | ||
| * | ||
| * @param namespace - New namespace string | ||
| * @returns New PackageURL with the updated namespace | ||
| */ | ||
| withNamespace(namespace: string | undefined): PackageURL; | ||
| /** | ||
| * Create a new PackageURL with a single qualifier added or updated. | ||
| * Returns a new instance — the original is unchanged. | ||
| * | ||
| * @param key - Qualifier key | ||
| * @param value - Qualifier value | ||
| * @returns New PackageURL with the qualifier set | ||
| */ | ||
| withQualifier(key: string, value: string): PackageURL; | ||
| /** | ||
| * Create a new PackageURL with all qualifiers replaced. | ||
| * Returns a new instance — the original is unchanged. | ||
| * | ||
| * @param qualifiers - New qualifiers object (or undefined to remove all) | ||
| * @returns New PackageURL with the updated qualifiers | ||
| */ | ||
| withQualifiers(qualifiers: Record<string, string> | undefined): PackageURL; | ||
| /** | ||
| * Create a new PackageURL with a different subpath. | ||
| * Returns a new instance — the original is unchanged. | ||
| * | ||
| * @param subpath - New subpath string | ||
| * @returns New PackageURL with the updated subpath | ||
| */ | ||
| withSubpath(subpath: string | undefined): PackageURL; | ||
| /** | ||
| * Compare this PackageURL with another for equality. | ||
| * | ||
| * Two PURLs are considered equal if their canonical string representations match. | ||
| * This comparison is case-sensitive after normalization. | ||
| * | ||
| * @param other - The PackageURL to compare with | ||
| * @returns true if the PURLs are equal, false otherwise | ||
| */ | ||
| equals(other: PackageURL): boolean; | ||
| /** | ||
| * Compare two PackageURLs for equality. | ||
| * | ||
| * Two PURLs are considered equal if their canonical string representations match. | ||
| * | ||
| * @param a - First PackageURL to compare | ||
| * @param b - Second PackageURL to compare | ||
| * @returns true if the PURLs are equal, false otherwise | ||
| */ | ||
| static equals(a: PackageURL, b: PackageURL): boolean; | ||
| /** | ||
| * Compare this PackageURL with another for sorting. | ||
| * | ||
| * Returns a number indicating sort order: | ||
| * - Negative if this comes before other | ||
| * - Zero if they are equal | ||
| * - Positive if this comes after other | ||
| * | ||
| * @param other - The PackageURL to compare with | ||
| * @returns -1, 0, or 1 for sort ordering | ||
| */ | ||
| compare(other: PackageURL): -1 | 0 | 1; | ||
| /** | ||
| * Compare two PackageURLs for sorting. | ||
| * | ||
| * Compares PURLs using their canonical string representations. | ||
| * Returns a number indicating sort order: | ||
| * - Negative if a comes before b | ||
| * - Zero if they are equal | ||
| * - Positive if a comes after b | ||
| * | ||
| * @param a - First PackageURL to compare | ||
| * @param b - Second PackageURL to compare | ||
| * @returns -1, 0, or 1 for sort ordering | ||
| */ | ||
| static compare(a: PackageURL, b: PackageURL): -1 | 0 | 1; | ||
| /** | ||
| * Create PackageURL from JSON string. | ||
@@ -82,3 +186,106 @@ */ | ||
| static fromString(purlStr: unknown): PackageURL; | ||
| static parseString(purlStr: unknown): unknown[]; | ||
| /** | ||
| * Create PackageURL from npm package specifier. | ||
| * | ||
| * Parses npm package specifiers and converts them to PackageURL format. | ||
| * Handles scoped packages, version ranges, and normalizes version strings. | ||
| * | ||
| * **Supported formats:** | ||
| * - Basic packages: `lodash`, `lodash@4.17.21` | ||
| * - Scoped packages: `@babel/core`, `@babel/core@7.0.0` | ||
| * - Version ranges: `^4.17.21`, `~1.2.3`, `>=1.0.0` (prefixes stripped) | ||
| * - Dist-tags: `latest`, `next`, `beta` (passed through as version) | ||
| * | ||
| * **Not supported:** | ||
| * - Git URLs: `git+https://...` (use PackageURL constructor directly) | ||
| * - File paths: `file:../package.tgz` | ||
| * - GitHub shortcuts: `user/repo#branch` | ||
| * - Aliases: `npm:package@version` | ||
| * | ||
| * **Note:** Dist-tags like `latest` are mutable and should be resolved to | ||
| * concrete versions for reproducible builds. This method passes them through | ||
| * as-is for convenience. | ||
| * | ||
| * @param specifier - npm package specifier (e.g., 'lodash@4.17.21', '@babel/core@^7.0.0') | ||
| * @returns PackageURL instance for the npm package | ||
| * @throws {Error} If specifier is not a string or is empty | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Basic packages | ||
| * PackageURL.fromNpm('lodash@4.17.21') | ||
| * // -> pkg:npm/lodash@4.17.21 | ||
| * | ||
| * // Scoped packages | ||
| * PackageURL.fromNpm('@babel/core@^7.0.0') | ||
| * // -> pkg:npm/%40babel/core@7.0.0 | ||
| * | ||
| * // Dist-tags (passed through) | ||
| * PackageURL.fromNpm('react@latest') | ||
| * // -> pkg:npm/react@latest | ||
| * | ||
| * // No version | ||
| * PackageURL.fromNpm('express') | ||
| * // -> pkg:npm/express | ||
| * ``` | ||
| */ | ||
| static fromNpm(specifier: unknown): PackageURL; | ||
| /** | ||
| * Create PackageURL from ecosystem-specific package specifier. | ||
| * | ||
| * This is a convenience wrapper that delegates to type-specific parsers. | ||
| * Each ecosystem has its own specifier format and parsing rules. | ||
| * | ||
| * **Supported types:** | ||
| * - `npm`: npm package specifiers (e.g., 'lodash@4.17.21', '@babel/core@^7.0.0') | ||
| * | ||
| * @param type - Package ecosystem type (e.g., 'npm', 'pypi', 'maven') | ||
| * @param specifier - Ecosystem-specific package specifier string | ||
| * @returns PackageURL instance for the package | ||
| * @throws {Error} If type is not supported or specifier is invalid | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // npm packages | ||
| * PackageURL.fromSpec('npm', 'lodash@4.17.21') | ||
| * // -> pkg:npm/lodash@4.17.21 | ||
| * | ||
| * PackageURL.fromSpec('npm', '@babel/core@^7.0.0') | ||
| * // -> pkg:npm/%40babel/core@7.0.0 | ||
| * ``` | ||
| */ | ||
| static fromSpec(type: string, specifier: unknown): PackageURL; | ||
| static parseString(purlStr: unknown): ParsedPurlComponents; | ||
| /** | ||
| * Check if a string is a valid PURL without throwing. | ||
| * | ||
| * @param purlStr - String to validate | ||
| * @returns true if the string is a valid PURL | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * PackageURL.isValid('pkg:npm/lodash@4.17.21') // true | ||
| * PackageURL.isValid('not a purl') // false | ||
| * ``` | ||
| */ | ||
| static isValid(purlStr: unknown): boolean; | ||
| /** | ||
| * Create PackageURL from a registry or repository URL. | ||
| * | ||
| * Convenience wrapper for UrlConverter.fromUrl(). Supports 27 hostnames | ||
| * across 17 package types including npm, pypi, maven, github, and more. | ||
| * | ||
| * @param urlStr - Registry or repository URL | ||
| * @returns PackageURL instance or undefined if URL is not recognized | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * PackageURL.fromUrl('https://www.npmjs.com/package/lodash') | ||
| * // -> pkg:npm/lodash | ||
| * | ||
| * PackageURL.fromUrl('https://github.com/lodash/lodash') | ||
| * // -> pkg:github/lodash/lodash | ||
| * ``` | ||
| */ | ||
| static fromUrl(urlStr: string): PackageURL | undefined; | ||
| static tryFromJSON(json: unknown): Result<PackageURL, Error>; | ||
@@ -85,0 +292,0 @@ static tryFromObject(obj: unknown): Result<PackageURL, Error>; |
@@ -7,8 +7,9 @@ /** | ||
| __proto__: null; | ||
| Checksum: string; | ||
| DownloadUrl: string; | ||
| FileName: string; | ||
| RepositoryUrl: string; | ||
| DownloadUrl: string; | ||
| VcsUrl: string; | ||
| FileName: string; | ||
| Checksum: string; | ||
| Vers: string; | ||
| }; | ||
| export { PurlQualifierNames }; |
+0
-21
@@ -1,22 +0,1 @@ | ||
| /*! | ||
| Copyright (c) the purl authors | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| */ | ||
| /** | ||
@@ -23,0 +2,0 @@ * @fileoverview Result type for functional error handling without exceptions. |
| /** | ||
| * @fileoverview String utility functions for PURL processing. | ||
| * Includes whitespace detection, semver validation, locale comparison, and character replacement. | ||
| */ | ||
| /** | ||
| * Check if string contains only whitespace characters. | ||
@@ -48,5 +44,12 @@ */ | ||
| /** | ||
| * Check if string contains characters commonly used in shell/URL injection attacks. | ||
| * Detects shell metacharacters (|, &, ;, `, $, <, >, {, }, #, \, newlines) | ||
| * and whitespace that could be used to break out of command or URL contexts. | ||
| * Uses charCode scanning for performance in hot paths. | ||
| */ | ||
| declare function containsInjectionCharacters(str: string): boolean; | ||
| /** | ||
| * Remove leading slashes from string. | ||
| */ | ||
| declare function trimLeadingSlashes(str: string): string; | ||
| export { isBlank, isNonEmptyString, isSemverString, localeCompare, lowerName, lowerNamespace, lowerVersion, replaceDashesWithUnderscores, replaceUnderscoresWithDashes, trimLeadingSlashes, }; | ||
| export { containsInjectionCharacters, isBlank, isNonEmptyString, isSemverString, localeCompare, lowerName, lowerNamespace, lowerVersion, replaceDashesWithUnderscores, replaceUnderscoresWithDashes, trimLeadingSlashes, }; |
+30
-42
@@ -1,26 +0,4 @@ | ||
| /*! | ||
| Copyright (c) the purl authors | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| */ | ||
| /** | ||
| * @fileoverview URL conversion utilities for converting Package URLs to repository and download URLs. | ||
| */ | ||
| import type { PackageURL } from './package-url.js'; | ||
| /** @internal Register the PackageURL class for fromUrl construction. */ | ||
| export declare function _registerPackageURLForUrlConverter(ctor: typeof PackageURL): void; | ||
| /** | ||
@@ -50,18 +28,28 @@ * Repository URL conversion results. | ||
| } | ||
| /** | ||
| * URL conversion utilities for Package URLs. | ||
| * | ||
| * This class provides static methods for converting PackageURL instances into | ||
| * various types of URLs, including repository URLs for source code access and | ||
| * download URLs for package artifacts. It supports many popular package ecosystems. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const purl = PackageURL.fromString('pkg:npm/lodash@4.17.21') | ||
| * const repoUrl = UrlConverter.toRepositoryUrl(purl) | ||
| * const downloadUrl = UrlConverter.toDownloadUrl(purl) | ||
| * ``` | ||
| */ | ||
| export declare class UrlConverter { | ||
| /** | ||
| * Convert a URL string to a PackageURL if the URL is recognized. | ||
| * | ||
| * Dispatches to type-specific parsers based on the URL hostname. | ||
| * Returns undefined for unrecognized hosts, invalid URLs, or URLs | ||
| * without enough path information to construct a valid PackageURL. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * UrlConverter.fromUrl('https://www.npmjs.com/package/lodash') | ||
| * // -> PackageURL for pkg:npm/lodash | ||
| * | ||
| * UrlConverter.fromUrl('https://github.com/lodash/lodash') | ||
| * // -> PackageURL for pkg:github/lodash/lodash | ||
| * ``` | ||
| */ | ||
| static fromUrl(urlStr: string): PackageURL | undefined; | ||
| /** | ||
| * Check if a URL string is recognized for conversion to a PackageURL. | ||
| * | ||
| * Returns true if the URL's hostname has a registered parser, | ||
| * false for invalid URLs or unrecognized hosts. | ||
| */ | ||
| static supportsFromUrl(urlStr: string): boolean; | ||
| /** | ||
| * Get all available URLs for a PackageURL. | ||
@@ -73,4 +61,4 @@ * | ||
| static getAllUrls(purl: PackageURL): { | ||
| download: DownloadUrl | null; | ||
| repository: RepositoryUrl | null; | ||
| download: DownloadUrl | undefined; | ||
| repository: RepositoryUrl | undefined; | ||
| }; | ||
@@ -98,3 +86,3 @@ /** | ||
| */ | ||
| static toDownloadUrl(purl: PackageURL): DownloadUrl | null; | ||
| static toDownloadUrl(purl: PackageURL): DownloadUrl | undefined; | ||
| /** | ||
@@ -107,3 +95,3 @@ * Convert a PackageURL to a repository URL if possible. | ||
| */ | ||
| static toRepositoryUrl(purl: PackageURL): RepositoryUrl | null; | ||
| static toRepositoryUrl(purl: PackageURL): RepositoryUrl | undefined; | ||
| } |
+45
-44
| { | ||
| "name": "@socketregistry/packageurl-js", | ||
| "version": "1.3.5", | ||
| "version": "1.4.0", | ||
| "packageManager": "pnpm@10.33.0", | ||
| "license": "MIT", | ||
@@ -22,40 +23,50 @@ "description": "Socket.dev optimized package override for packageurl-js", | ||
| }, | ||
| "./exists": { | ||
| "types": "./dist/exists.d.ts", | ||
| "default": "./dist/exists.js" | ||
| }, | ||
| "./data/npm/builtin-names.json": "./data/npm/builtin-names.json", | ||
| "./data/npm/legacy-names.json": "./data/npm/legacy-names.json", | ||
| "./dist/*": { | ||
| "types": "./dist/*.d.ts", | ||
| "default": "./dist/*.js" | ||
| }, | ||
| "./package.json": "./package.json" | ||
| }, | ||
| "files": [ | ||
| "dist/**/*", | ||
| "data/**/*.json", | ||
| "CHANGELOG.md" | ||
| ], | ||
| "engines": { | ||
| "node": ">=18.20.4", | ||
| "pnpm": ">=10.25.0" | ||
| }, | ||
| "sideEffects": false, | ||
| "scripts": { | ||
| "build": "node scripts/load.cjs build", | ||
| "bump": "node scripts/load.cjs bump", | ||
| "check": "node scripts/load.cjs check", | ||
| "clean": "node scripts/load.cjs clean", | ||
| "cover": "node scripts/load.cjs cover", | ||
| "fix": "node scripts/load.cjs fix", | ||
| "lint": "node scripts/load.cjs lint", | ||
| "build": "node scripts/build.mjs", | ||
| "bump": "node scripts/bump.mjs", | ||
| "check": "node scripts/check.mjs", | ||
| "ci:validate": "node scripts/ci-validate.mjs", | ||
| "clean": "node scripts/clean.mjs", | ||
| "cover": "node scripts/cover.mjs", | ||
| "fix": "node scripts/fix.mjs", | ||
| "lint": "node scripts/lint.mjs", | ||
| "precommit": "pnpm run check --lint --staged", | ||
| "prepare": "husky", | ||
| "prepublishOnly": "echo 'ERROR: Use GitHub Actions workflow for publishing' && exit 1", | ||
| "publish": "node scripts/load.cjs publish", | ||
| "claude": "node scripts/load.cjs claude", | ||
| "test": "node scripts/load.cjs test", | ||
| "publish": "node scripts/publish.mjs", | ||
| "publish:ci": "node scripts/publish.mjs --tag ${DIST_TAG:-latest}", | ||
| "claude": "node scripts/claude.mjs", | ||
| "test": "node scripts/test.mjs", | ||
| "type": "tsgo --noEmit -p .config/tsconfig.check.json", | ||
| "update": "node scripts/load.cjs update", | ||
| "update:data:npm": "node scripts/load.cjs update-data-npm" | ||
| "update": "node scripts/update.mjs", | ||
| "update:data:npm": "node scripts/update-data-npm.mjs" | ||
| }, | ||
| "devDependencies": { | ||
| "@babel/parser": "^7.28.5", | ||
| "@biomejs/biome": "2.2.4", | ||
| "@dotenvx/dotenvx": "1.49.0", | ||
| "@eslint/compat": "1.3.2", | ||
| "@eslint/js": "9.35.0", | ||
| "@socketsecurity/lib": "3.1.2", | ||
| "@socketsecurity/registry": "1.5.3", | ||
| "@babel/parser": "7.29.0", | ||
| "@dotenvx/dotenvx": "1.52.0", | ||
| "@oxlint/migrate": "1.51.0", | ||
| "@socketsecurity/lib": "5.11.4", | ||
| "@socketsecurity/registry": "2.0.2", | ||
| "@types/node": "24.9.2", | ||
| "@types/picomatch": "4.0.2", | ||
| "@typescript/native-preview": "7.0.0-dev.20250926.1", | ||
| "@vitest/coverage-v8": "3.2.4", | ||
| "@vitest/coverage-v8": "4.0.3", | ||
| "all-the-package-names": "2.0.0", | ||
@@ -66,31 +77,18 @@ "all-the-package-names-v1.3905.0": "npm:all-the-package-names@1.3905.0", | ||
| "esbuild": "0.25.11", | ||
| "eslint": "9.35.0", | ||
| "eslint-plugin-import-x": "4.16.1", | ||
| "eslint-plugin-n": "17.23.1", | ||
| "eslint-plugin-sort-destructure-keys": "2.0.0", | ||
| "eslint-plugin-unicorn": "56.0.1", | ||
| "fast-glob": "3.3.3", | ||
| "globals": "16.4.0", | ||
| "husky": "9.1.7", | ||
| "magic-string": "^0.30.21", | ||
| "npm-run-all2": "8.0.4", | ||
| "magic-string": "0.30.21", | ||
| "nock": "14.0.10", | ||
| "oxfmt": "0.37.0", | ||
| "oxlint": "1.52.0", | ||
| "pacote": "21.0.1", | ||
| "semver": "7.7.2", | ||
| "taze": "19.6.0", | ||
| "taze": "19.9.2", | ||
| "type-coverage": "2.29.7", | ||
| "typescript": "5.9.2", | ||
| "typescript-eslint": "8.44.1", | ||
| "validate-npm-package-name": "6.0.2", | ||
| "vitest": "3.2.4", | ||
| "vitest": "4.0.3", | ||
| "yoctocolors-cjs": "2.1.3" | ||
| }, | ||
| "engines": { | ||
| "node": ">=18", | ||
| "pnpm": ">=10.16.0" | ||
| }, | ||
| "files": [ | ||
| "dist/**/*", | ||
| "data/**/*.json", | ||
| "CHANGELOG.md" | ||
| ], | ||
| "pnpm": { | ||
@@ -120,3 +118,6 @@ "ignoredBuiltDependencies": [ | ||
| "strict": true | ||
| }, | ||
| "dependencies": { | ||
| "picomatch": "4.0.3" | ||
| } | ||
| } |
+125
-44
@@ -5,2 +5,3 @@ # @socketregistry/packageurl-js | ||
| [](https://github.com/SocketDev/socket-packageurl-js/actions/workflows/ci.yml) | ||
|  | ||
@@ -10,3 +11,4 @@ [](https://twitter.com/SocketSecurity) | ||
| TypeScript Package URL (purl) parser and builder. Drop-in replacement for [`packageurl-js`](https://socket.dev/npm/package/packageurl-js) with full type safety, zero dependencies, and spec compliance with the [Package URL specification](https://github.com/package-url/purl-spec). | ||
| TypeScript Package URL (purl) parser and builder. | ||
| Drop-in replacement for [`packageurl-js`](https://socket.dev/npm/package/packageurl-js) with full type safety, zero dependencies, and spec compliance with the [Package URL specification](https://github.com/package-url/purl-spec). | ||
@@ -24,2 +26,3 @@ ## What is a PURL? | ||
| **Format breakdown**: | ||
| ``` | ||
@@ -39,4 +42,15 @@ pkg:type/namespace/name@version?qualifiers#subpath | ||
| ## Installation | ||
| ## Features | ||
| - ✅ **Modular & tree-shakeable** - Import only what you need | ||
| - ✅ **Full TypeScript support** - Comprehensive type exports | ||
| - ✅ **Zero dependencies** - Lightweight and secure | ||
| - ✅ **Spec compliant** - Follows [purl-spec](https://github.com/package-url/purl-spec) | ||
| - ✅ **100% test coverage** - Over 1,000 passing tests | ||
| - ✅ **Multiple APIs** - Functional, class-based, and builder patterns | ||
| - ✅ **URL conversion** - Convert to repository and download URLs | ||
| - ✅ **Registry checks** - Verify package existence across 14 registries | ||
| ## Install | ||
| ```sh | ||
@@ -47,2 +61,3 @@ pnpm install @socketregistry/packageurl-js | ||
| **Drop-in replacement** via package override: | ||
| ```json | ||
@@ -62,46 +77,66 @@ { | ||
| **Parse purls:** | ||
| ### Modular Functions (Tree-shakeable) | ||
| **Parse npm specifiers:** | ||
| ```javascript | ||
| import { PackageURL } from '@socketregistry/packageurl-js' | ||
| import { parseNpmSpecifier } from '@socketregistry/packageurl-js' | ||
| const purl = PackageURL.fromString('pkg:npm/lodash@4.17.21') | ||
| console.log(purl.name) // 'lodash' | ||
| console.log(purl.version) // '4.17.21' | ||
| parseNpmSpecifier('lodash@4.17.21') | ||
| // -> { namespace: undefined, name: 'lodash', version: '4.17.21' } | ||
| parseNpmSpecifier('@babel/core@^7.0.0') | ||
| // -> { namespace: '@babel', name: 'core', version: '7.0.0' } | ||
| ``` | ||
| **Build purls:** | ||
| **Stringify PURLs:** | ||
| ```javascript | ||
| import { PackageURLBuilder } from '@socketregistry/packageurl-js' | ||
| import { stringify } from '@socketregistry/packageurl-js' | ||
| // npm packages | ||
| PackageURLBuilder.npm().name('lodash').version('4.17.21').build() | ||
| stringify(purl) | ||
| // -> 'pkg:npm/lodash@4.17.21' | ||
| ``` | ||
| // Python packages | ||
| PackageURLBuilder.pypi().name('requests').version('2.28.1').build() | ||
| // -> 'pkg:pypi/requests@2.28.1' | ||
| **Compare PURLs:** | ||
| // Maven with namespace and qualifiers | ||
| PackageURLBuilder.maven() | ||
| .namespace('org.springframework') | ||
| .name('spring-core') | ||
| .version('5.3.21') | ||
| .qualifier('classifier', 'sources') | ||
| .build() | ||
| // -> 'pkg:maven/org.springframework/spring-core@5.3.21?classifier=sources' | ||
| ```javascript | ||
| import { equals, compare } from '@socketregistry/packageurl-js' | ||
| equals(purl1, purl2) // -> boolean | ||
| compare(purl1, purl2) // -> -1 | 0 | 1 | ||
| ``` | ||
| **Constructor API:** | ||
| ### Class API | ||
| **Parse and build:** | ||
| ```javascript | ||
| import { PackageURL } from '@socketregistry/packageurl-js' | ||
| // Parse strings | ||
| const purl = PackageURL.fromString('pkg:npm/lodash@4.17.21') | ||
| console.log(purl.name) // 'lodash' | ||
| console.log(purl.version) // '4.17.21' | ||
| // Parse npm specifiers | ||
| PackageURL.fromNpm('lodash@4.17.21') | ||
| PackageURL.fromNpm('@babel/core@^7.0.0') | ||
| // Constructor | ||
| new PackageURL('npm', null, 'express', '4.18.2') | ||
| // -> 'pkg:npm/express@4.18.2' | ||
| ``` | ||
| // With namespace and subpath | ||
| new PackageURL('npm', '@babel', 'runtime', '7.18.6', null, 'helpers/typeof.js') | ||
| // -> 'pkg:npm/%40babel/runtime@7.18.6#helpers/typeof.js' | ||
| **Builder pattern:** | ||
| ```javascript | ||
| import { PurlBuilder } from '@socketregistry/packageurl-js' | ||
| PurlBuilder.npm().name('lodash').version('4.17.21').build() | ||
| // -> 'pkg:npm/lodash@4.17.21' | ||
| ``` | ||
| **Convert to URLs:** | ||
| **URL conversion:** | ||
| ```javascript | ||
@@ -117,28 +152,70 @@ import { UrlConverter } from '@socketregistry/packageurl-js' | ||
| **Use type-safe PURL types:** | ||
| **Registry existence checks:** | ||
| ```javascript | ||
| import { PURL_Type, EcosystemString } from '@socketregistry/packageurl-js' | ||
| import { purlExists, npmExists } from '@socketregistry/packageurl-js' | ||
| // Type-safe enum values | ||
| console.log(PURL_Type.NPM) // 'npm' | ||
| console.log(PURL_Type.PYPI) // 'pypi' | ||
| console.log(PURL_Type.MAVEN) // 'maven' | ||
| // Check if package exists in its registry | ||
| await purlExists(purl) | ||
| // -> { exists: true, latestVersion: '4.17.21' } | ||
| // Use in type annotations | ||
| function processPurl(type: EcosystemString) { | ||
| // type is constrained to valid PURL type strings | ||
| } | ||
| // Type-specific checks (modular) | ||
| await npmExists('lodash') | ||
| await npmExists('core', '@babel') // scoped package | ||
| await npmExists('lodash', undefined, '4.17.21') // validate version | ||
| // Supported registries: | ||
| // npmExists, pypiExists, cargoExists, gemExists, | ||
| // mavenExists, nugetExists, golangExists, packagistExists, | ||
| // cocoapodsExists, pubExists, hexExists, cpanExists, | ||
| // cranExists, hackageExists | ||
| ``` | ||
| ## Documentation | ||
| ### TypeScript Types | ||
| | Doc | Description | | ||
| |-----|-------------| | ||
| | **[Getting Started](./docs/getting-started.md)** | Quick setup guide for contributors | | ||
| | **[API Reference](./docs/api-reference.md)** | Complete API documentation | | ||
| | **[Examples](./docs/usage-examples.md)** | Common use cases and patterns | | ||
| | **[Builder Pattern](./docs/builder-pattern.md)** | Fluent builder guide | | ||
| All types are exported for maximum flexibility: | ||
| ```typescript | ||
| import type { | ||
| PackageURLObject, | ||
| NpmPackageComponents, | ||
| ParsedPurlComponents, | ||
| QualifiersObject, | ||
| ComponentEncoder, | ||
| DownloadUrl, | ||
| RepositoryUrl, | ||
| } from '@socketregistry/packageurl-js' | ||
| // Type-safe npm package parsing | ||
| const components: NpmPackageComponents = parseNpmSpecifier('lodash@4.17.21') | ||
| // Type-safe PURL objects | ||
| const obj: PackageURLObject = purl.toObject() | ||
| ``` | ||
| **Constants:** | ||
| ```typescript | ||
| import { PurlQualifierNames, PURL_Type } from '@socketregistry/packageurl-js' | ||
| // Standard qualifier keys | ||
| PurlQualifierNames.Checksum // 'checksum' | ||
| PurlQualifierNames.RepositoryUrl // 'repository_url' | ||
| // Package types | ||
| PURL_Type.NPM // 'npm' | ||
| PURL_Type.PYPI // 'pypi' | ||
| ``` | ||
| See [docs/types.md](docs/types.md) for complete type reference. | ||
| ## API Reference | ||
| - **[docs/api.md](docs/api.md)** - Complete API documentation | ||
| - **[docs/types.md](docs/types.md)** - TypeScript type reference | ||
| ## Development | ||
| **Quick commands:** | ||
| ```bash | ||
@@ -150,1 +227,5 @@ pnpm install # Install dependencies | ||
| ``` | ||
| ## License | ||
| MIT |
Sorry, the diff of this file is too big to display
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
3686971
1156.14%29
-14.71%74
184.62%94245
821.89%224
56.64%12
-20%1
Infinity%1
Infinity%+ Added
+ Added