Skip to content

Commit a4bef2b

Browse files
committed
Apply consistent bracket notation for index signature access
Converts dot notation to bracket notation for type safety: - PurlComponent.type → PurlComponent['type'] - Improves TypeScript strictness with exactOptionalPropertyTypes - Ensures consistent index signature access patterns
1 parent 2e6b7bf commit a4bef2b

File tree

5 files changed

+51
-38
lines changed

5 files changed

+51
-38
lines changed

biome.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@
5959
"linter": {
6060
"rules": {
6161
"complexity": {
62-
"noStaticOnlyClass": "off"
62+
"noStaticOnlyClass": "off",
63+
"useLiteralKeys": "off"
6364
},
6465
"style": {
6566
"noNonNullAssertion": "off",

src/normalize.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ function qualifiersToEntries(
134134
if (isObject(rawQualifiers)) {
135135
// URLSearchParams instances have an "entries" method that returns an iterator
136136
const rawQualifiersObj = rawQualifiers as QualifiersObject | URLSearchParams
137-
const entriesProperty = (rawQualifiersObj as QualifiersObject).entries
137+
const entriesProperty = (rawQualifiersObj as QualifiersObject)['entries']
138138
return typeof entriesProperty === 'function'
139139
? (ReflectApply(entriesProperty, rawQualifiersObj, []) as Iterable<
140140
[string, string]

src/package-url.ts

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -99,47 +99,57 @@ class PackageURL {
9999
rawSubpath: unknown,
100100
) {
101101
const type = isNonEmptyString(rawType)
102-
? (PurlComponent.type?.normalize as ComponentNormalizer)?.(rawType)
102+
? (PurlComponent['type']?.['normalize'] as ComponentNormalizer)?.(rawType)
103103
: rawType
104-
;(PurlComponent.type?.validate as ComponentValidator)?.(type, true)
104+
;(PurlComponent['type']?.['validate'] as ComponentValidator)?.(type, true)
105105

106106
const namespace = isNonEmptyString(rawNamespace)
107-
? (PurlComponent.namespace?.normalize as ComponentNormalizer)?.(
107+
? (PurlComponent['namespace']?.['normalize'] as ComponentNormalizer)?.(
108108
rawNamespace,
109109
)
110110
: rawNamespace
111-
;(PurlComponent.namespace?.validate as ComponentValidator)?.(
111+
;(PurlComponent['namespace']?.['validate'] as ComponentValidator)?.(
112112
namespace,
113113
true,
114114
)
115115

116116
const name = isNonEmptyString(rawName)
117-
? (PurlComponent.name?.normalize as ComponentNormalizer)?.(rawName)
117+
? (PurlComponent['name']?.['normalize'] as ComponentNormalizer)?.(rawName)
118118
: rawName
119-
;(PurlComponent.name?.validate as ComponentValidator)?.(name, true)
119+
;(PurlComponent['name']?.['validate'] as ComponentValidator)?.(name, true)
120120

121121
const version = isNonEmptyString(rawVersion)
122-
? (PurlComponent.version?.normalize as ComponentNormalizer)?.(rawVersion)
122+
? (PurlComponent['version']?.['normalize'] as ComponentNormalizer)?.(
123+
rawVersion,
124+
)
123125
: rawVersion
124-
;(PurlComponent.version?.validate as ComponentValidator)?.(version, true)
126+
;(PurlComponent['version']?.['validate'] as ComponentValidator)?.(
127+
version,
128+
true,
129+
)
125130

126131
const qualifiers =
127132
typeof rawQualifiers === 'string' || isObject(rawQualifiers)
128133
? (
129-
PurlComponent.qualifiers?.normalize as (
134+
PurlComponent['qualifiers']?.['normalize'] as (
130135
_value: string | QualifiersObject,
131136
) => Record<string, string> | undefined
132137
)?.(rawQualifiers as string | QualifiersObject)
133138
: rawQualifiers
134-
;(PurlComponent.qualifiers?.validate as ComponentValidator)?.(
139+
;(PurlComponent['qualifiers']?.['validate'] as ComponentValidator)?.(
135140
qualifiers,
136141
true,
137142
)
138143

139144
const subpath = isNonEmptyString(rawSubpath)
140-
? (PurlComponent.subpath?.normalize as ComponentNormalizer)?.(rawSubpath)
145+
? (PurlComponent['subpath']?.['normalize'] as ComponentNormalizer)?.(
146+
rawSubpath,
147+
)
141148
: rawSubpath
142-
;(PurlComponent.subpath?.validate as ComponentValidator)?.(subpath, true)
149+
;(PurlComponent['subpath']?.['validate'] as ComponentValidator)?.(
150+
subpath,
151+
true,
152+
)
143153

144154
this.type = type as string
145155
this.name = name as string
@@ -156,9 +166,9 @@ class PackageURL {
156166

157167
const typeHelpers = PurlType[type as string]
158168
if (typeHelpers) {
159-
;(typeHelpers?.normalize as (_purl: PackageURL) => void)?.(this)
169+
;(typeHelpers?.['normalize'] as (_purl: PackageURL) => void)?.(this)
160170
;(
161-
typeHelpers?.validate as (
171+
typeHelpers?.['validate'] as (
162172
_purl: PackageURL,
163173
_throws: boolean,
164174
) => boolean
@@ -222,19 +232,19 @@ class PackageURL {
222232
type?: string | undefined
223233
version?: string | undefined
224234
} = this
225-
/* c8 ignore next - Type encoder uses default PurlComponentEncoder, never returns null/undefined. */ let purlStr = `pkg:${(PurlComponent.type?.encode as ComponentEncoder)?.(type) ?? ''}/`
235+
/* c8 ignore next - Type encoder uses default PurlComponentEncoder, never returns null/undefined. */ let purlStr = `pkg:${(PurlComponent['type']?.['encode'] as ComponentEncoder)?.(type) ?? ''}/`
226236
if (namespace) {
227-
/* c8 ignore next - Namespace encoder always returns string, never null/undefined. */ purlStr = `${purlStr}${(PurlComponent.namespace?.encode as ComponentEncoder)?.(namespace) ?? ''}/`
237+
/* c8 ignore next - Namespace encoder always returns string, never null/undefined. */ purlStr = `${purlStr}${(PurlComponent['namespace']?.['encode'] as ComponentEncoder)?.(namespace) ?? ''}/`
228238
}
229-
/* c8 ignore next - Name encoder always returns string, never null/undefined. */ purlStr = `${purlStr}${(PurlComponent.name?.encode as ComponentEncoder)?.(name) ?? ''}`
239+
/* c8 ignore next - Name encoder always returns string, never null/undefined. */ purlStr = `${purlStr}${(PurlComponent['name']?.['encode'] as ComponentEncoder)?.(name) ?? ''}`
230240
if (version) {
231-
/* c8 ignore next - Version encoder always returns string, never null/undefined. */ purlStr = `${purlStr}@${(PurlComponent.version?.encode as ComponentEncoder)?.(version) ?? ''}`
241+
/* c8 ignore next - Version encoder always returns string, never null/undefined. */ purlStr = `${purlStr}@${(PurlComponent['version']?.['encode'] as ComponentEncoder)?.(version) ?? ''}`
232242
}
233243
if (qualifiers) {
234-
/* c8 ignore next - Qualifiers encoder always returns string, never null/undefined. */ purlStr = `${purlStr}?${(PurlComponent.qualifiers?.encode as ComponentEncoder)?.(qualifiers) ?? ''}`
244+
/* c8 ignore next - Qualifiers encoder always returns string, never null/undefined. */ purlStr = `${purlStr}?${(PurlComponent['qualifiers']?.['encode'] as ComponentEncoder)?.(qualifiers) ?? ''}`
235245
}
236246
if (subpath) {
237-
/* c8 ignore next - Subpath encoder always returns string, never null/undefined. */ purlStr = `${purlStr}#${(PurlComponent.subpath?.encode as ComponentEncoder)?.(subpath) ?? ''}`
247+
/* c8 ignore next - Subpath encoder always returns string, never null/undefined. */ purlStr = `${purlStr}#${(PurlComponent['subpath']?.['encode'] as ComponentEncoder)?.(subpath) ?? ''}`
238248
}
239249
return purlStr
240250
}
@@ -278,12 +288,14 @@ class PackageURL {
278288
// Create a safe object without prototype chain to prevent prototype pollution
279289
const safeObject: PackageURLObject = {
280290
__proto__: null,
281-
type: parsedRecord.type as string | undefined,
282-
namespace: parsedRecord.namespace as string | undefined,
283-
name: parsedRecord.name as string | undefined,
284-
version: parsedRecord.version as string | undefined,
285-
qualifiers: parsedRecord.qualifiers as Record<string, string> | undefined,
286-
subpath: parsedRecord.subpath as string | undefined,
291+
type: parsedRecord['type'] as string | undefined,
292+
namespace: parsedRecord['namespace'] as string | undefined,
293+
name: parsedRecord['name'] as string | undefined,
294+
version: parsedRecord['version'] as string | undefined,
295+
qualifiers: parsedRecord['qualifiers'] as
296+
| Record<string, string>
297+
| undefined,
298+
subpath: parsedRecord['subpath'] as string | undefined,
287299
} as PackageURLObject
288300

289301
return PackageURL.fromObject(safeObject)
@@ -298,12 +310,12 @@ class PackageURL {
298310
}
299311
const typedObj = obj as Record<string, unknown>
300312
return new PackageURL(
301-
typedObj.type,
302-
typedObj.namespace,
303-
typedObj.name,
304-
typedObj.version,
305-
typedObj.qualifiers,
306-
typedObj.subpath,
313+
typedObj['type'],
314+
typedObj['namespace'],
315+
typedObj['name'],
316+
typedObj['version'],
317+
typedObj['qualifiers'],
318+
typedObj['subpath'],
307319
)
308320
}
309321

src/purl-type.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ const PurlType = createHelpersNamespaceObject(
224224
},
225225
// https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#mlflow
226226
mlflow(purl: PurlObject) {
227-
if (purl.qualifiers?.repository_url?.includes('databricks')) {
227+
if (purl.qualifiers?.['repository_url']?.includes('databricks')) {
228228
lowerName(purl)
229229
}
230230
return purl
@@ -306,7 +306,7 @@ const PurlType = createHelpersNamespaceObject(
306306
// https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#conan
307307
conan(purl: PurlObject, throws: boolean) {
308308
if (isNullishOrEmptyString(purl.namespace)) {
309-
if (purl.qualifiers?.channel) {
309+
if (purl.qualifiers?.['channel']) {
310310
if (throws) {
311311
throw new PurlError(
312312
'conan requires a "namespace" component when a "channel" qualifier is present',
@@ -542,7 +542,7 @@ const PurlType = createHelpersNamespaceObject(
542542
swid(purl: PurlObject, throws: boolean) {
543543
const { qualifiers } = purl
544544
// SWID requires a tag_id qualifier
545-
const tagId = qualifiers?.tag_id
545+
const tagId = qualifiers?.['tag_id']
546546
if (!tagId) {
547547
if (throws) {
548548
throw new PurlError('swid requires a "tag_id" qualifier')

src/validate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ function validateQualifiers(
170170
return false
171171
}
172172
const qualifiersObj = qualifiers as QualifiersObject | URLSearchParams
173-
const keysProperty = (qualifiersObj as QualifiersObject).keys
173+
const keysProperty = (qualifiersObj as QualifiersObject)['keys']
174174
// type-coverage:ignore-next-line -- TypeScript correctly infers this type through the ternary and cast
175175
const keysIterable: Iterable<string> =
176176
// URLSearchParams instances have a "keys" method that returns an iterator

0 commit comments

Comments
 (0)