@jsenv/package-publish 1.5.2 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{license → LICENSE} +0 -0
- package/README.md +64 -0
- package/main.js +8 -0
- package/package.json +32 -36
- package/src/internal/fetchLatestInRegistry.js +7 -6
- package/src/internal/needsPublish.js +22 -17
- package/src/internal/publish.js +39 -15
- package/src/internal/readProjectPackage.js +1 -3
- package/src/publishPackage.js +156 -150
- package/dist/commonjs/main.cjs +0 -505
- package/dist/commonjs/main.cjs.map +0 -174
- package/index.js +0 -1
- package/readme.md +0 -72
package/src/publishPackage.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
|
|
1
2
|
import { createLogger } from "@jsenv/logger"
|
|
2
|
-
|
|
3
|
-
import { assertAndNormalizeDirectoryUrl } from "@jsenv/util"
|
|
3
|
+
|
|
4
4
|
import { fetchLatestInRegistry } from "./internal/fetchLatestInRegistry.js"
|
|
5
5
|
import { publish } from "./internal/publish.js"
|
|
6
6
|
import { readProjectPackage } from "./internal/readProjectPackage.js"
|
|
@@ -14,180 +14,186 @@ import {
|
|
|
14
14
|
} from "../src/internal/needsPublish.js"
|
|
15
15
|
|
|
16
16
|
export const publishPackage = async ({
|
|
17
|
-
cancellationToken = createCancellationTokenForProcess(),
|
|
18
17
|
logLevel,
|
|
19
18
|
projectDirectoryUrl,
|
|
20
19
|
registriesConfig,
|
|
21
20
|
logNpmPublishOutput = true,
|
|
22
21
|
updateProcessExitCode = true,
|
|
23
22
|
} = {}) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
projectDirectoryUrl = assertAndNormalizeDirectoryUrl(projectDirectoryUrl)
|
|
35
|
-
assertRegistriesConfig(registriesConfig)
|
|
36
|
-
|
|
37
|
-
logger.debug(`reading project package.json`)
|
|
38
|
-
const packageInProject = await readProjectPackage({
|
|
39
|
-
projectDirectoryUrl,
|
|
40
|
-
})
|
|
41
|
-
const { name: packageName, version: packageVersion } = packageInProject
|
|
42
|
-
logger.info(`${packageName}@${packageVersion} found in package.json`)
|
|
43
|
-
|
|
44
|
-
const report = {}
|
|
45
|
-
await Promise.all(
|
|
46
|
-
Object.keys(registriesConfig).map(async (registryUrl) => {
|
|
47
|
-
const registryReport = {
|
|
48
|
-
packageName,
|
|
49
|
-
packageVersion,
|
|
50
|
-
registryLatestVersion: undefined,
|
|
51
|
-
action: undefined,
|
|
52
|
-
actionReason: undefined,
|
|
53
|
-
actionResult: undefined,
|
|
54
|
-
}
|
|
55
|
-
report[registryUrl] = registryReport
|
|
56
|
-
|
|
57
|
-
logger.debug(`check latest version for ${packageName} in ${registryUrl}`)
|
|
58
|
-
const registryConfig = registriesConfig[registryUrl]
|
|
59
|
-
|
|
60
|
-
try {
|
|
61
|
-
const latestPackageInRegistry = await fetchLatestInRegistry({
|
|
62
|
-
registryUrl,
|
|
63
|
-
packageName,
|
|
64
|
-
...registryConfig,
|
|
65
|
-
})
|
|
66
|
-
const registryLatestVersion =
|
|
67
|
-
latestPackageInRegistry === null ? null : latestPackageInRegistry.version
|
|
68
|
-
registryReport.registryLatestVersion = registryLatestVersion
|
|
69
|
-
|
|
70
|
-
const needs = needsPublish({ packageVersion, registryLatestVersion })
|
|
71
|
-
registryReport.action =
|
|
72
|
-
needs === PUBLISH_BECAUSE_NEVER_PUBLISHED ||
|
|
73
|
-
needs === PUBLISH_BECAUSE_LATEST_LOWER ||
|
|
74
|
-
needs === PUBLISH_BECAUSE_TAG_DIFFERS
|
|
75
|
-
? "publish"
|
|
76
|
-
: "nothing"
|
|
77
|
-
registryReport.actionReason = needs
|
|
78
|
-
} catch (e) {
|
|
79
|
-
registryReport.action = "nothing"
|
|
80
|
-
registryReport.actionReason = e
|
|
81
|
-
if (updateProcessExitCode) {
|
|
82
|
-
process.exitCode = 1
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
cancellationToken.throwIfRequested()
|
|
87
|
-
}),
|
|
88
|
-
)
|
|
23
|
+
const logger = createLogger({ logLevel })
|
|
24
|
+
logger.debug(
|
|
25
|
+
`publishPackage(${JSON.stringify(
|
|
26
|
+
{ projectDirectoryUrl, logLevel, registriesConfig },
|
|
27
|
+
null,
|
|
28
|
+
" ",
|
|
29
|
+
)})`,
|
|
30
|
+
)
|
|
31
|
+
projectDirectoryUrl = assertAndNormalizeDirectoryUrl(projectDirectoryUrl)
|
|
32
|
+
assertRegistriesConfig(registriesConfig)
|
|
89
33
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
34
|
+
logger.debug(`reading project package.json`)
|
|
35
|
+
const packageInProject = await readProjectPackage({
|
|
36
|
+
projectDirectoryUrl,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const { name: packageName, version: packageVersion } = packageInProject
|
|
40
|
+
logger.info(`${packageName}@${packageVersion} found in package.json`)
|
|
41
|
+
|
|
42
|
+
const report = {}
|
|
43
|
+
await Promise.all(
|
|
44
|
+
Object.keys(registriesConfig).map(async (registryUrl) => {
|
|
45
|
+
const registryReport = {
|
|
46
|
+
packageName,
|
|
47
|
+
packageVersion,
|
|
48
|
+
registryLatestVersion: undefined,
|
|
49
|
+
action: undefined,
|
|
50
|
+
actionReason: undefined,
|
|
51
|
+
actionResult: undefined,
|
|
52
|
+
}
|
|
53
|
+
report[registryUrl] = registryReport
|
|
54
|
+
|
|
55
|
+
if (packageInProject.private) {
|
|
56
|
+
registryReport.action = "nothing"
|
|
57
|
+
registryReport.actionReason = "package is private"
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
logger.debug(`check latest version for ${packageName} in ${registryUrl}`)
|
|
62
|
+
const registryConfig = registriesConfig[registryUrl]
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const latestPackageInRegistry = await fetchLatestInRegistry({
|
|
66
|
+
registryUrl,
|
|
67
|
+
packageName,
|
|
68
|
+
...registryConfig,
|
|
69
|
+
})
|
|
70
|
+
const registryLatestVersion =
|
|
71
|
+
latestPackageInRegistry === null
|
|
72
|
+
? null
|
|
73
|
+
: latestPackageInRegistry.version
|
|
74
|
+
registryReport.registryLatestVersion = registryLatestVersion
|
|
75
|
+
|
|
76
|
+
const needs = needsPublish({ packageVersion, registryLatestVersion })
|
|
77
|
+
registryReport.action =
|
|
78
|
+
needs === PUBLISH_BECAUSE_NEVER_PUBLISHED ||
|
|
79
|
+
needs === PUBLISH_BECAUSE_LATEST_LOWER ||
|
|
80
|
+
needs === PUBLISH_BECAUSE_TAG_DIFFERS
|
|
81
|
+
? "publish"
|
|
82
|
+
: "nothing"
|
|
83
|
+
registryReport.actionReason = needs
|
|
84
|
+
} catch (e) {
|
|
85
|
+
registryReport.action = "nothing"
|
|
86
|
+
registryReport.actionReason = e
|
|
87
|
+
if (updateProcessExitCode) {
|
|
88
|
+
process.exitCode = 1
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
// we have to publish in serie because we don't fully control
|
|
95
|
+
// npm publish, we have to enforce where the package gets published
|
|
96
|
+
await Object.keys(report).reduce(async (previous, registryUrl) => {
|
|
97
|
+
await previous
|
|
98
|
+
|
|
99
|
+
const registryReport = report[registryUrl]
|
|
100
|
+
const { action, actionReason, registryLatestVersion } = registryReport
|
|
101
|
+
|
|
102
|
+
if (action === "nothing") {
|
|
103
|
+
if (actionReason === NOTHING_BECAUSE_ALREADY_PUBLISHED) {
|
|
104
|
+
logger.info(
|
|
105
|
+
`skip ${packageName}@${packageVersion} publish on ${registryUrl} because already published`,
|
|
106
|
+
)
|
|
107
|
+
} else if (actionReason === NOTHING_BECAUSE_LATEST_HIGHER) {
|
|
108
|
+
logger.info(
|
|
109
|
+
`skip ${packageName}@${packageVersion} publish on ${registryUrl} because latest version is higher (${registryLatestVersion})`,
|
|
110
|
+
)
|
|
111
|
+
} else if (actionReason === "package is private") {
|
|
112
|
+
logger.info(
|
|
113
|
+
`skip ${packageName}@${packageVersion} publish on ${registryUrl} because found private: true in package.json`,
|
|
114
|
+
)
|
|
115
|
+
} else {
|
|
116
|
+
logger.error(`skip ${packageName}@${packageVersion} publish on ${registryUrl} due to error while fetching latest version.
|
|
110
117
|
--- error stack ---
|
|
111
118
|
${actionReason.stack}`)
|
|
112
|
-
|
|
119
|
+
}
|
|
113
120
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
121
|
+
registryReport.actionResult = { success: true, reason: "nothing-to-do" }
|
|
122
|
+
return
|
|
123
|
+
}
|
|
117
124
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
125
|
+
if (actionReason === PUBLISH_BECAUSE_NEVER_PUBLISHED) {
|
|
126
|
+
logger.info(
|
|
127
|
+
`publish ${packageName}@${packageVersion} on ${registryUrl} because it was never published`,
|
|
128
|
+
)
|
|
129
|
+
} else if (actionReason === PUBLISH_BECAUSE_LATEST_LOWER) {
|
|
130
|
+
logger.info(
|
|
131
|
+
`publish ${packageName}@${packageVersion} on ${registryUrl} because latest version is lower (${registryLatestVersion})`,
|
|
132
|
+
)
|
|
133
|
+
} else if (actionReason === PUBLISH_BECAUSE_TAG_DIFFERS) {
|
|
134
|
+
logger.info(
|
|
135
|
+
`publish ${packageName}@${packageVersion} on ${registryUrl} because latest tag differs (${registryLatestVersion})`,
|
|
136
|
+
)
|
|
137
|
+
}
|
|
131
138
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
139
|
+
const { success, reason } = await publish({
|
|
140
|
+
logger,
|
|
141
|
+
logNpmPublishOutput,
|
|
142
|
+
projectDirectoryUrl,
|
|
143
|
+
registryUrl,
|
|
144
|
+
...registriesConfig[registryUrl],
|
|
145
|
+
})
|
|
146
|
+
registryReport.actionResult = { success, reason }
|
|
147
|
+
if (success) {
|
|
148
|
+
if (reason === "already-published") {
|
|
149
|
+
logger.info(
|
|
150
|
+
`${packageName}@${packageVersion} was already published on ${registryUrl}`,
|
|
151
|
+
)
|
|
152
|
+
} else {
|
|
153
|
+
logger.info(
|
|
154
|
+
`${packageName}@${packageVersion} published on ${registryUrl}`,
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
logger.error(`error when publishing ${packageName}@${packageVersion} in ${registryUrl}
|
|
148
159
|
--- error stack ---
|
|
149
160
|
${reason.stack}`)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
161
|
+
if (updateProcessExitCode) {
|
|
162
|
+
process.exitCode = 1
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}, Promise.resolve())
|
|
155
166
|
|
|
156
|
-
|
|
157
|
-
},
|
|
158
|
-
{ catchCancellation: true, considerUnhandledRejectionsAsExceptions: true },
|
|
159
|
-
)
|
|
167
|
+
return report
|
|
160
168
|
}
|
|
161
169
|
|
|
162
170
|
const assertRegistriesConfig = (value) => {
|
|
163
|
-
if (typeof value !== "object") {
|
|
164
|
-
throw new TypeError(`registriesConfig must be an object
|
|
165
|
-
--- registryMap ---
|
|
166
|
-
${value}`)
|
|
171
|
+
if (typeof value !== "object" || value === null) {
|
|
172
|
+
throw new TypeError(`registriesConfig must be an object, got ${value}`)
|
|
167
173
|
}
|
|
168
174
|
|
|
169
175
|
Object.keys(value).forEach((registryUrl) => {
|
|
170
176
|
const registryMapValue = value[registryUrl]
|
|
171
|
-
if (typeof registryMapValue !== "object") {
|
|
172
|
-
throw new TypeError(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
--- registryMap key ---
|
|
176
|
-
${registryUrl}`)
|
|
177
|
+
if (typeof registryMapValue !== "object" || value === null) {
|
|
178
|
+
throw new TypeError(
|
|
179
|
+
`Unexpected value in registriesConfig for ${registryUrl}. It must be an object, got ${registryMapValue}`,
|
|
180
|
+
)
|
|
177
181
|
}
|
|
178
182
|
|
|
179
|
-
if (
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
+
if (
|
|
184
|
+
`token` in registryMapValue === false ||
|
|
185
|
+
registryMapValue.token === ""
|
|
186
|
+
) {
|
|
187
|
+
throw new TypeError(
|
|
188
|
+
`Missing token in registriesConfig for ${registryUrl}.`,
|
|
189
|
+
)
|
|
183
190
|
}
|
|
184
191
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
${
|
|
189
|
-
|
|
190
|
-
${registryUrl}`)
|
|
192
|
+
const { token } = registryMapValue
|
|
193
|
+
if (typeof token !== "string") {
|
|
194
|
+
throw new TypeError(
|
|
195
|
+
`Unexpected token in registriesConfig for ${registryUrl}. It must be a string, got ${token}.`,
|
|
196
|
+
)
|
|
191
197
|
}
|
|
192
198
|
})
|
|
193
199
|
}
|