@jsenv/package-publish 1.9.0 → 1.10.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/package.json +1 -1
- package/src/internal/publish.js +133 -139
package/package.json
CHANGED
package/src/internal/publish.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { fileURLToPath } from "node:url"
|
|
2
2
|
import { readFileSync, writeFileSync } from "node:fs"
|
|
3
3
|
import { exec } from "node:child_process"
|
|
4
|
+
import { createTaskLog } from "@jsenv/log"
|
|
4
5
|
import { removeEntry } from "@jsenv/filesystem"
|
|
5
|
-
import { UNICODE } from "@jsenv/log"
|
|
6
6
|
|
|
7
7
|
import { setNpmConfig } from "./setNpmConfig.js"
|
|
8
8
|
|
|
@@ -14,158 +14,152 @@ export const publish = async ({
|
|
|
14
14
|
registryUrl,
|
|
15
15
|
token,
|
|
16
16
|
}) => {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
writeFileSync(
|
|
40
|
-
rootPackageFileUrl,
|
|
41
|
-
JSON.stringify(packageObject, null, " "),
|
|
42
|
-
)
|
|
43
|
-
}
|
|
44
|
-
// updating .npmrc to add the token
|
|
45
|
-
const npmConfigFileUrl = new URL("./.npmrc", rootDirectoryUrl)
|
|
46
|
-
let restoreNpmConfigFile
|
|
47
|
-
let npmConfigFileContent
|
|
48
|
-
try {
|
|
49
|
-
npmConfigFileContent = String(readFileSync(npmConfigFileUrl))
|
|
50
|
-
restoreNpmConfigFile = () =>
|
|
51
|
-
writeFileSync(npmConfigFileUrl, npmConfigFileContent)
|
|
52
|
-
} catch (e) {
|
|
53
|
-
if (e.code === "ENOENT") {
|
|
54
|
-
restoreNpmConfigFile = () => removeEntry(npmConfigFileUrl)
|
|
55
|
-
npmConfigFileContent = ""
|
|
56
|
-
} else {
|
|
57
|
-
throw e
|
|
58
|
-
}
|
|
59
|
-
}
|
|
17
|
+
const publishTask = createTaskLog(`publish ${packageSlug} on ${registryUrl}`)
|
|
18
|
+
try {
|
|
19
|
+
// process.env.NODE_AUTH_TOKEN
|
|
20
|
+
const previousValue = process.env.NODE_AUTH_TOKEN
|
|
21
|
+
const restoreProcessEnv = () => {
|
|
22
|
+
process.env.NODE_AUTH_TOKEN = previousValue
|
|
23
|
+
}
|
|
24
|
+
process.env.NODE_AUTH_TOKEN = token
|
|
25
|
+
// updating package.json to publish on the correct registry
|
|
26
|
+
let restorePackageFile = () => {}
|
|
27
|
+
const rootPackageFileUrl = new URL("./package.json", rootDirectoryUrl)
|
|
28
|
+
const rootPackageFileContent = readFileSync(rootPackageFileUrl)
|
|
29
|
+
const packageObject = JSON.parse(String(rootPackageFileContent))
|
|
30
|
+
const { publishConfig } = packageObject
|
|
31
|
+
const registerUrlFromPackage = publishConfig
|
|
32
|
+
? publishConfig.registry || "https://registry.npmjs.org"
|
|
33
|
+
: "https://registry.npmjs.org"
|
|
34
|
+
if (registryUrl !== registerUrlFromPackage) {
|
|
35
|
+
restorePackageFile = () =>
|
|
36
|
+
writeFileSync(rootPackageFileUrl, rootPackageFileContent)
|
|
37
|
+
packageObject.publishConfig = packageObject.publishConfig || {}
|
|
38
|
+
packageObject.publishConfig.registry = registryUrl
|
|
60
39
|
writeFileSync(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
[computeRegistryTokenKey(registryUrl)]: token,
|
|
64
|
-
[computeRegistryKey(packageObject.name)]: registryUrl,
|
|
65
|
-
}),
|
|
40
|
+
rootPackageFileUrl,
|
|
41
|
+
JSON.stringify(packageObject, null, " "),
|
|
66
42
|
)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
43
|
+
}
|
|
44
|
+
// updating .npmrc to add the token
|
|
45
|
+
const npmConfigFileUrl = new URL("./.npmrc", rootDirectoryUrl)
|
|
46
|
+
let restoreNpmConfigFile
|
|
47
|
+
let npmConfigFileContent
|
|
48
|
+
try {
|
|
49
|
+
npmConfigFileContent = String(readFileSync(npmConfigFileUrl))
|
|
50
|
+
restoreNpmConfigFile = () =>
|
|
51
|
+
writeFileSync(npmConfigFileUrl, npmConfigFileContent)
|
|
52
|
+
} catch (e) {
|
|
53
|
+
if (e.code === "ENOENT") {
|
|
54
|
+
restoreNpmConfigFile = () => removeEntry(npmConfigFileUrl)
|
|
55
|
+
npmConfigFileContent = ""
|
|
56
|
+
} else {
|
|
57
|
+
throw e
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
writeFileSync(
|
|
61
|
+
npmConfigFileUrl,
|
|
62
|
+
setNpmConfig(npmConfigFileContent, {
|
|
63
|
+
[computeRegistryTokenKey(registryUrl)]: token,
|
|
64
|
+
[computeRegistryKey(packageObject.name)]: registryUrl,
|
|
65
|
+
}),
|
|
66
|
+
)
|
|
67
|
+
try {
|
|
68
|
+
const reason = await new Promise((resolve, reject) => {
|
|
69
|
+
const command = exec(
|
|
70
|
+
"npm publish --no-workspaces",
|
|
71
|
+
{
|
|
72
|
+
cwd: fileURLToPath(rootDirectoryUrl),
|
|
73
|
+
stdio: "silent",
|
|
74
|
+
},
|
|
75
|
+
(error) => {
|
|
76
|
+
if (error) {
|
|
77
|
+
// publish conflict generally occurs because servers
|
|
78
|
+
// returns 200 after npm publish
|
|
79
|
+
// but returns previous version if asked immediatly
|
|
80
|
+
// after for the last published version.
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
// TODO: ideally we should catch 404 error returned from npm
|
|
83
|
+
// it happens it the token is not allowed to publish
|
|
84
|
+
// a repository. And when we detect this we display a more useful message
|
|
85
|
+
// suggesting the token rights are insufficient to publish the package
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
resolve({
|
|
106
|
-
success: true,
|
|
107
|
-
reason: "already-published",
|
|
108
|
-
})
|
|
109
|
-
}
|
|
110
|
-
// github publish conflict
|
|
111
|
-
else if (
|
|
112
|
-
error.message.includes(
|
|
113
|
-
"ambiguous package version in package.json",
|
|
114
|
-
)
|
|
115
|
-
) {
|
|
116
|
-
resolve({
|
|
117
|
-
success: true,
|
|
118
|
-
reason: "already-published",
|
|
119
|
-
})
|
|
120
|
-
} else {
|
|
121
|
-
reject(error)
|
|
122
|
-
}
|
|
123
|
-
} else {
|
|
87
|
+
// npm publish conclit
|
|
88
|
+
if (error.message.includes("EPUBLISHCONFLICT")) {
|
|
89
|
+
resolve({
|
|
90
|
+
success: true,
|
|
91
|
+
reason: "already-published",
|
|
92
|
+
})
|
|
93
|
+
} else if (
|
|
94
|
+
error.message.includes("Cannot publish over existing version")
|
|
95
|
+
) {
|
|
96
|
+
resolve({
|
|
97
|
+
success: true,
|
|
98
|
+
reason: "already-published",
|
|
99
|
+
})
|
|
100
|
+
} else if (
|
|
101
|
+
error.message.includes(
|
|
102
|
+
"You cannot publish over the previously published versions",
|
|
103
|
+
)
|
|
104
|
+
) {
|
|
124
105
|
resolve({
|
|
125
106
|
success: true,
|
|
126
|
-
reason: "published",
|
|
107
|
+
reason: "already-published",
|
|
127
108
|
})
|
|
128
109
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
110
|
+
// github publish conflict
|
|
111
|
+
else if (
|
|
112
|
+
error.message.includes(
|
|
113
|
+
"ambiguous package version in package.json",
|
|
114
|
+
)
|
|
115
|
+
) {
|
|
116
|
+
resolve({
|
|
117
|
+
success: true,
|
|
118
|
+
reason: "already-published",
|
|
119
|
+
})
|
|
120
|
+
} else {
|
|
121
|
+
reject(error)
|
|
122
|
+
}
|
|
123
|
+
} else {
|
|
124
|
+
resolve({
|
|
125
|
+
success: true,
|
|
126
|
+
reason: "published",
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
)
|
|
131
|
+
if (logNpmPublishOutput) {
|
|
132
|
+
command.stdout.on("data", (data) => {
|
|
133
|
+
logger.debug(data)
|
|
134
|
+
})
|
|
135
|
+
command.stderr.on("data", (data) => {
|
|
136
|
+
// debug because this output is part of
|
|
137
|
+
// the error message generated by a failing npm publish
|
|
138
|
+
logger.debug(data)
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
if (reason === "already-published") {
|
|
143
|
+
publishTask.setRightText(`(already published)`)
|
|
146
144
|
}
|
|
147
|
-
|
|
145
|
+
publishTask.done()
|
|
148
146
|
return {
|
|
149
|
-
success:
|
|
150
|
-
reason
|
|
147
|
+
success: true,
|
|
148
|
+
reason,
|
|
151
149
|
}
|
|
150
|
+
} finally {
|
|
151
|
+
restoreProcessEnv()
|
|
152
|
+
restorePackageFile()
|
|
153
|
+
restoreNpmConfigFile()
|
|
152
154
|
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
)
|
|
160
|
-
} else {
|
|
161
|
-
logger.info(`${UNICODE.OK} ${packageSlug} published on ${registryUrl}`)
|
|
155
|
+
} catch (e) {
|
|
156
|
+
publishTask.fail()
|
|
157
|
+
console.error(e.stack)
|
|
158
|
+
return {
|
|
159
|
+
success: false,
|
|
160
|
+
reason: e,
|
|
162
161
|
}
|
|
163
|
-
} else {
|
|
164
|
-
logger.error(`${UNICODE.FAILURE} error when publishing ${packageSlug} in ${registryUrl}
|
|
165
|
-
--- error stack ---
|
|
166
|
-
${reason.stack}`)
|
|
167
162
|
}
|
|
168
|
-
return { success, reason }
|
|
169
163
|
}
|
|
170
164
|
|
|
171
165
|
const computeRegistryTokenKey = (registryUrl) => {
|