-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnormalize.ts
More file actions
125 lines (117 loc) · 3.69 KB
/
normalize.ts
File metadata and controls
125 lines (117 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/**
* @fileoverview Package.json normalization utilities.
*/
import {
REGISTRY_SCOPE_DELIMITER,
SOCKET_REGISTRY_SCOPE,
} from '../constants/socket'
import { escapeRegExp } from '../regexps'
import normalizePackageData from '../external/normalize-package-data'
import { merge } from '../objects'
import { findPackageExtensions } from './operations'
import type { NormalizeOptions, PackageJson } from '../packages'
const ArrayIsArray = Array.isArray
const ObjectHasOwn = Object.hasOwn
function getEscapedScopeRegExp(): RegExp {
const firstChar = REGISTRY_SCOPE_DELIMITER[0] as string
return new RegExp(
`^[^${escapeRegExp(firstChar)}]+${escapeRegExp(REGISTRY_SCOPE_DELIMITER)}(?!${escapeRegExp(firstChar)})`,
)
}
/**
* Normalize a package.json object with standard npm package normalization.
*
* @example
* ```typescript
* const pkgJson = { name: 'my-pkg', version: '1.0.0' }
* const normalized = normalizePackageJson(pkgJson)
* ```
*/
/*@__NO_SIDE_EFFECTS__*/
export function normalizePackageJson(
pkgJson: PackageJson,
options?: NormalizeOptions,
): PackageJson {
const { preserve } = { __proto__: null, ...options } as NormalizeOptions
// Add default version if not present.
if (!ObjectHasOwn(pkgJson, 'version')) {
pkgJson.version = '0.0.0'
}
const preserved = [
['_id', undefined],
['readme', undefined],
...(ObjectHasOwn(pkgJson, 'bugs') ? [] : [['bugs', undefined]]),
...(ObjectHasOwn(pkgJson, 'homepage') ? [] : [['homepage', undefined]]),
...(ObjectHasOwn(pkgJson, 'name') ? [] : [['name', undefined]]),
...(ArrayIsArray(preserve)
? preserve.map(k => [
k,
ObjectHasOwn(pkgJson, k) ? pkgJson[k] : undefined,
])
: []),
]
normalizePackageData(pkgJson)
// Apply package extensions if name and version are present.
if (pkgJson.name && pkgJson.version) {
const extensions = findPackageExtensions(pkgJson.name, pkgJson.version)
if (extensions && typeof extensions === 'object') {
merge(pkgJson, extensions)
}
}
// Revert/remove properties we don't care to have normalized.
// Properties with undefined values are omitted when saved as JSON.
for (const { 0: key, 1: value } of preserved) {
pkgJson[key as keyof typeof pkgJson] = value
}
return pkgJson
}
/**
* Extract escaped scope from a Socket registry package name.
*
* @example
* ```typescript
* resolveEscapedScope('babel__core') // 'babel__'
* resolveEscapedScope('lodash') // undefined
* ```
*/
/*@__NO_SIDE_EFFECTS__*/
export function resolveEscapedScope(
sockRegPkgName: string,
): string | undefined {
const escapedScopeRegExp = getEscapedScopeRegExp()
const match = escapedScopeRegExp.exec(sockRegPkgName)?.[0]
return match || undefined
}
/**
* Resolve original package name from Socket registry package name.
*
* @example
* ```typescript
* resolveOriginalPackageName('@socketregistry/is-number') // 'is-number'
* ```
*/
/*@__NO_SIDE_EFFECTS__*/
export function resolveOriginalPackageName(sockRegPkgName: string): string {
const name = sockRegPkgName.startsWith(`${SOCKET_REGISTRY_SCOPE}/`)
? sockRegPkgName.slice(SOCKET_REGISTRY_SCOPE.length + 1)
: sockRegPkgName
const escapedScope = resolveEscapedScope(name)
return escapedScope
? `${unescapeScope(escapedScope)}/${name.slice(escapedScope.length)}`
: name
}
/**
* Convert escaped scope to standard npm scope format.
*
* @example
* ```typescript
* unescapeScope('babel__') // '@babel'
* ```
*/
/*@__NO_SIDE_EFFECTS__*/
export function unescapeScope(escapedScope: string): string {
if (escapedScope.length < REGISTRY_SCOPE_DELIMITER.length) {
return `@${escapedScope}`
}
return `@${escapedScope.slice(0, -REGISTRY_SCOPE_DELIMITER.length)}`
}