This repository has been archived by the owner on Nov 4, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 147
/
Copy pathpkg-info.js
151 lines (120 loc) · 3.79 KB
/
pkg-info.js
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import { basename, dirname, resolve } from "path"
import FastObject from "./fast-object.js"
import NullObject from "./null-object.js"
import createOptions from "./util/create-options.js"
import has from "./util/has.js"
import readJSON from "./fs/read-json.js"
import readdir from "./fs/readdir.js"
import { validRange } from "semver"
import { version } from "./version.js"
const defaultOptions = createOptions({
cache: ".esm-cache",
cjs: false,
debug: false,
esm: "mjs"
})
const infoCache = new FastObject
class PkgInfo {
constructor(dirPath, range, options) {
options = typeof options === "string" ? { esm: options } : options
options = createOptions(options, defaultOptions)
if (! options.esm) {
options.esm = "mjs"
}
const cache = new NullObject
const cacheDir = options.cache
const cachePath = typeof cacheDir === "string" ? resolve(dirPath, cacheDir) : null
const cacheFileNames = cachePath === null ? null : readdir(cachePath)
let i = -1
const nameCount = cacheFileNames ? cacheFileNames.length : 0
while (++i < nameCount) {
// Later, in the ".js" or ".mjs" compiler, we'll change the cached value
// to its associated mocked compiler result, but for now we merely register
// that a cache file exists.
cache[cacheFileNames[i]] = true
}
this.cache = cache
this.cachePath = cachePath
this.dirPath = dirPath
this.options = options
this.range = range
}
static defaultOptions = defaultOptions
static get(dirPath) {
if (dirPath in infoCache) {
return infoCache[dirPath]
}
infoCache[dirPath] = null
if (basename(dirPath) === "node_modules") {
return null
}
let pkgInfo = PkgInfo.read(dirPath)
if (pkgInfo === null) {
const parentPath = dirname(dirPath)
pkgInfo = parentPath === dirPath ? null : PkgInfo.get(parentPath)
}
return infoCache[dirPath] = pkgInfo
}
static read(dirPath, force) {
const pkgPath = resolve(dirPath, "package.json")
let pkgJSON = readJSON(pkgPath)
if (pkgJSON === null) {
if (force) {
pkgJSON = new NullObject
} else {
return null
}
}
let options = null
if (has(pkgJSON, "@std/esm")) {
options = pkgJSON["@std/esm"]
} else if (has(pkgJSON, "@std") && has(pkgJSON["@std"], "esm")) {
options = pkgJSON["@std"].esm
}
if (! force &&
options === false) {
// An explicit "@std/esm": false property in package.json disables esm
// loading even if "@std/esm" is listed as a dependency.
return null
}
// Use case: a package.json file may have "@std/esm" in its "devDependencies"
// object because it expects another package or application to enable esm
// loading in production, but needs its own copy of the "@std/esm" package
// during development. Disabling esm loading in production when it was
// enabled in development would be undesired in this case.
let range =
getRange(pkgJSON, "dependencies") ||
getRange(pkgJSON, "peerDependencies") ||
getRange(pkgJSON, "devDependencies")
if (range === null) {
if (options || force) {
range = "*"
} else {
return null
}
}
const pkgInfo = new PkgInfo(dirPath, range, options)
if (force &&
options === false) {
pkgInfo.options = null
}
return pkgInfo
}
static set(dirPath, pkgInfo) {
infoCache[dirPath] = pkgInfo
}
}
function getRange(json, name) {
const entry = json[name]
return has(entry, "@std/esm")
? validRange(entry["@std/esm"])
: null
}
Object.setPrototypeOf(PkgInfo.prototype, null)
// Enable in-memory caching when compiling without a file path.
infoCache[""] = new PkgInfo("", version, {
cache: false,
cjs: true,
gz: true
})
export default PkgInfo