Skip to content

Commit 36dedc9

Browse files
committed
Add JSDoc documentation to core components
1 parent 327709f commit 36dedc9

File tree

9 files changed

+378
-237
lines changed

9 files changed

+378
-237
lines changed

src/normalize.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,25 @@ import { isBlank } from './strings.js'
77

88
import type { QualifiersObject } from './purl-component.js'
99

10+
/**
11+
* Normalize package name by trimming whitespace.
12+
*/
1013
function normalizeName(rawName: unknown): string | undefined {
1114
return typeof rawName === 'string' ? rawName.trim() : undefined
1215
}
1316

17+
/**
18+
* Normalize package namespace by trimming and collapsing path separators.
19+
*/
1420
function normalizeNamespace(rawNamespace: unknown): string | undefined {
1521
return typeof rawNamespace === 'string'
1622
? normalizePath(rawNamespace, undefined)
1723
: undefined
1824
}
1925

26+
/**
27+
* Normalize path by collapsing separators and filtering segments.
28+
*/
2029
function normalizePath(
2130
pathname: string,
2231
callback?: (_segment: string) => boolean,
@@ -55,6 +64,9 @@ function normalizePath(
5564
return collapsed
5665
}
5766

67+
/**
68+
* Normalize qualifiers by trimming values and lowercasing keys.
69+
*/
5870
function normalizeQualifiers(
5971
rawQualifiers: unknown,
6072
): Record<string, string> | undefined {
@@ -77,18 +89,27 @@ function normalizeQualifiers(
7789
return qualifiers
7890
}
7991

92+
/**
93+
* Normalize subpath by filtering invalid segments.
94+
*/
8095
function normalizeSubpath(rawSubpath: unknown): string | undefined {
8196
return typeof rawSubpath === 'string'
8297
? normalizePath(rawSubpath, subpathFilter)
8398
: undefined
8499
}
85100

101+
/**
102+
* Normalize package type to lowercase.
103+
*/
86104
function normalizeType(rawType: unknown): string | undefined {
87105
// The type must NOT be percent-encoded.
88106
// The type is case insensitive. The canonical form is lowercase.
89107
return typeof rawType === 'string' ? rawType.trim().toLowerCase() : undefined
90108
}
91109

110+
/**
111+
* Normalize package version by trimming whitespace.
112+
*/
92113
function normalizeVersion(rawVersion: unknown): string | undefined {
93114
return typeof rawVersion === 'string' ? rawVersion.trim() : undefined
94115
}
@@ -99,6 +120,9 @@ function normalizeVersion(rawVersion: unknown): string | undefined {
99120
// See: https://github.com/SocketDev/socket-packageurl-js/issues/3
100121
const ReflectApply = Reflect.apply
101122

123+
/**
124+
* Convert qualifiers to iterable entries.
125+
*/
102126
function qualifiersToEntries(
103127
rawQualifiers: unknown,
104128
): Iterable<[string, string]> {
@@ -119,6 +143,9 @@ function qualifiersToEntries(
119143
: Object.entries({})
120144
}
121145

146+
/**
147+
* Filter invalid subpath segments.
148+
*/
122149
function subpathFilter(segment: string): boolean {
123150
// When percent-decoded, a segment
124151
// - must not be any of '.' or '..'

src/objects.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,17 @@
44
*/
55
import { LOOP_SENTINEL } from './constants.js'
66

7+
/**
8+
* Check if value is an object type.
9+
*/
710
function isObject(value: unknown): value is object {
811
return value !== null && typeof value === 'object'
912
}
1013

14+
/**
15+
* Recursively freeze an object and all nested objects.
16+
* @throws {Error} When infinite loop detected.
17+
*/
1118
function recursiveFreeze<T>(value_: T): T {
1219
if (
1320
value_ === null ||

src/package-url-builder.ts

Lines changed: 84 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -86,24 +86,23 @@ export class PackageURLBuilder {
8686
private _subpath?: string
8787

8888
/**
89-
* Set the package type for the PackageURL.
90-
*/
91-
type(type: string): this {
92-
this._type = type
93-
return this
94-
}
95-
96-
/**
97-
* Set the package namespace for the PackageURL.
89+
* Build and return the final PackageURL instance.
9890
*
99-
* The namespace represents different concepts depending on the package type:
100-
* - npm: organization or scope (e.g., '@angular' for '@angular/core')
101-
* - maven: groupId (e.g., 'org.apache.commons')
102-
* - pypi: typically unused
91+
* This method creates a new PackageURL instance using all the properties
92+
* set on this builder. The PackageURL constructor will handle validation
93+
* and normalization of the provided values.
94+
*
95+
* @throws {Error} If the configuration results in an invalid PackageURL
10396
*/
104-
namespace(namespace: string): this {
105-
this._namespace = namespace
106-
return this
97+
build(): PackageURL {
98+
return new PackageURL(
99+
this._type,
100+
this._namespace,
101+
this._name,
102+
this._version,
103+
this._qualifiers,
104+
this._subpath,
105+
)
107106
}
108107

109108
/**
@@ -119,26 +118,15 @@ export class PackageURLBuilder {
119118
}
120119

121120
/**
122-
* Set the package version for the PackageURL.
123-
*
124-
* The version string should match the format used by the package repository.
125-
* Some package types may normalize version formats (e.g., removing leading 'v').
126-
*/
127-
version(version: string): this {
128-
this._version = version
129-
return this
130-
}
131-
132-
/**
133-
* Set all qualifiers at once, replacing any existing qualifiers.
121+
* Set the package namespace for the PackageURL.
134122
*
135-
* Qualifiers provide additional metadata about the package such as:
136-
* - arch: target architecture
137-
* - os: target operating system
138-
* - classifier: additional classifier for the package
123+
* The namespace represents different concepts depending on the package type:
124+
* - npm: organization or scope (e.g., '@angular' for '@angular/core')
125+
* - maven: groupId (e.g., 'org.apache.commons')
126+
* - pypi: typically unused
139127
*/
140-
qualifiers(qualifiers: Record<string, string>): this {
141-
this._qualifiers = { ...qualifiers }
128+
namespace(namespace: string): this {
129+
this._namespace = namespace
142130
return this
143131
}
144132

@@ -156,6 +144,19 @@ export class PackageURLBuilder {
156144
return this
157145
}
158146

147+
/**
148+
* Set all qualifiers at once, replacing any existing qualifiers.
149+
*
150+
* Qualifiers provide additional metadata about the package such as:
151+
* - arch: target architecture
152+
* - os: target operating system
153+
* - classifier: additional classifier for the package
154+
*/
155+
qualifiers(qualifiers: Record<string, string>): this {
156+
this._qualifiers = { ...qualifiers }
157+
return this
158+
}
159+
159160
/**
160161
* Set the subpath for the PackageURL.
161162
*
@@ -169,23 +170,42 @@ export class PackageURLBuilder {
169170
}
170171

171172
/**
172-
* Build and return the final PackageURL instance.
173+
* Set the package type for the PackageURL.
174+
*/
175+
type(type: string): this {
176+
this._type = type
177+
return this
178+
}
179+
180+
/**
181+
* Set the package version for the PackageURL.
173182
*
174-
* This method creates a new PackageURL instance using all the properties
175-
* set on this builder. The PackageURL constructor will handle validation
176-
* and normalization of the provided values.
183+
* The version string should match the format used by the package repository.
184+
* Some package types may normalize version formats (e.g., removing leading 'v').
185+
*/
186+
version(version: string): this {
187+
this._version = version
188+
return this
189+
}
190+
191+
/**
192+
* Create a builder with the cargo package type preset.
177193
*
178-
* @throws {Error} If the configuration results in an invalid PackageURL
194+
* This convenience method creates a new builder instance with the type
195+
* already set to 'cargo', ready for building Rust crate URLs.
179196
*/
180-
build(): PackageURL {
181-
return new PackageURL(
182-
this._type,
183-
this._namespace,
184-
this._name,
185-
this._version,
186-
this._qualifiers,
187-
this._subpath,
188-
)
197+
static cargo(): PackageURLBuilder {
198+
return new PackageURLBuilder().type('cargo')
199+
}
200+
201+
/**
202+
* Create a builder with the composer package type preset.
203+
*
204+
* This convenience method creates a new builder instance with the type
205+
* already set to 'composer', ready for building Composer package URLs.
206+
*/
207+
static composer(): PackageURLBuilder {
208+
return new PackageURLBuilder().type('composer')
189209
}
190210

191211
/**
@@ -234,23 +254,23 @@ export class PackageURLBuilder {
234254
}
235255

236256
/**
237-
* Create a builder with the npm package type preset.
257+
* Create a builder with the gem package type preset.
238258
*
239259
* This convenience method creates a new builder instance with the type
240-
* already set to 'npm', ready for building npm package URLs.
260+
* already set to 'gem', ready for building Ruby gem URLs.
241261
*/
242-
static npm(): PackageURLBuilder {
243-
return new PackageURLBuilder().type('npm')
262+
static gem(): PackageURLBuilder {
263+
return new PackageURLBuilder().type('gem')
244264
}
245265

246266
/**
247-
* Create a builder with the pypi package type preset.
267+
* Create a builder with the golang package type preset.
248268
*
249269
* This convenience method creates a new builder instance with the type
250-
* already set to 'pypi', ready for building Python package URLs.
270+
* already set to 'golang', ready for building Go package URLs.
251271
*/
252-
static pypi(): PackageURLBuilder {
253-
return new PackageURLBuilder().type('pypi')
272+
static golang(): PackageURLBuilder {
273+
return new PackageURLBuilder().type('golang')
254274
}
255275

256276
/**
@@ -264,33 +284,13 @@ export class PackageURLBuilder {
264284
}
265285

266286
/**
267-
* Create a builder with the gem package type preset.
268-
*
269-
* This convenience method creates a new builder instance with the type
270-
* already set to 'gem', ready for building Ruby gem URLs.
271-
*/
272-
static gem(): PackageURLBuilder {
273-
return new PackageURLBuilder().type('gem')
274-
}
275-
276-
/**
277-
* Create a builder with the golang package type preset.
278-
*
279-
* This convenience method creates a new builder instance with the type
280-
* already set to 'golang', ready for building Go package URLs.
281-
*/
282-
static golang(): PackageURLBuilder {
283-
return new PackageURLBuilder().type('golang')
284-
}
285-
286-
/**
287-
* Create a builder with the cargo package type preset.
287+
* Create a builder with the npm package type preset.
288288
*
289289
* This convenience method creates a new builder instance with the type
290-
* already set to 'cargo', ready for building Rust crate URLs.
290+
* already set to 'npm', ready for building npm package URLs.
291291
*/
292-
static cargo(): PackageURLBuilder {
293-
return new PackageURLBuilder().type('cargo')
292+
static npm(): PackageURLBuilder {
293+
return new PackageURLBuilder().type('npm')
294294
}
295295

296296
/**
@@ -304,12 +304,12 @@ export class PackageURLBuilder {
304304
}
305305

306306
/**
307-
* Create a builder with the composer package type preset.
307+
* Create a builder with the pypi package type preset.
308308
*
309309
* This convenience method creates a new builder instance with the type
310-
* already set to 'composer', ready for building Composer package URLs.
310+
* already set to 'pypi', ready for building Python package URLs.
311311
*/
312-
static composer(): PackageURLBuilder {
313-
return new PackageURLBuilder().type('composer')
312+
static pypi(): PackageURLBuilder {
313+
return new PackageURLBuilder().type('pypi')
314314
}
315315
}

0 commit comments

Comments
 (0)