@jsenv/package-publish 1.7.5 → 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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/package-publish",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Publish package to one or many registry.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -17,33 +17,26 @@
|
|
|
17
17
|
"node": ">=16.13.0"
|
|
18
18
|
},
|
|
19
19
|
"publishConfig": {
|
|
20
|
-
"access": "public"
|
|
21
|
-
"registry": "https://registry.npmjs.org"
|
|
20
|
+
"access": "public"
|
|
22
21
|
},
|
|
23
22
|
"type": "module",
|
|
24
23
|
"exports": {
|
|
25
24
|
".": {
|
|
26
|
-
"import": "./main.js"
|
|
25
|
+
"import": "./src/main.js"
|
|
27
26
|
},
|
|
28
27
|
"./*": "./*"
|
|
29
28
|
},
|
|
30
|
-
"main": "./main.js",
|
|
29
|
+
"main": "./src/main.js",
|
|
31
30
|
"files": [
|
|
32
|
-
"/src/"
|
|
33
|
-
"/main.js"
|
|
31
|
+
"/src/"
|
|
34
32
|
],
|
|
35
33
|
"scripts": {
|
|
36
|
-
"
|
|
37
|
-
"test": "node --experimental-json-modules ./script/test/test.mjs",
|
|
38
|
-
"test-with-coverage": "npm run test -- --coverage",
|
|
39
|
-
"prettier": "prettier --write ."
|
|
34
|
+
"test": "node --experimental-json-modules ./scripts/test.mjs"
|
|
40
35
|
},
|
|
41
36
|
"dependencies": {
|
|
42
|
-
"@jsenv/
|
|
43
|
-
"@jsenv/
|
|
44
|
-
"@jsenv/
|
|
45
|
-
"
|
|
46
|
-
"@jsenv/log": "1.6.3",
|
|
47
|
-
"semver": "7.3.5"
|
|
37
|
+
"@jsenv/fetch": "1.1.3",
|
|
38
|
+
"@jsenv/filesystem": "4.1.0",
|
|
39
|
+
"@jsenv/log": "3.0.0",
|
|
40
|
+
"semver": "7.3.7"
|
|
48
41
|
}
|
|
49
|
-
}
|
|
42
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// https://github.com/npm/registry-issue-archive/issues/34
|
|
3
3
|
// https://stackoverflow.com/questions/53212849/querying-information-about-specific-version-of-scoped-npm-package
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import { fetchUrl } from "@jsenv/fetch"
|
|
6
6
|
|
|
7
7
|
export const fetchLatestInRegistry = async ({
|
|
8
8
|
registryUrl,
|
|
@@ -10,7 +10,7 @@ export const fetchLatestInRegistry = async ({
|
|
|
10
10
|
token,
|
|
11
11
|
}) => {
|
|
12
12
|
const requestUrl = `${registryUrl}/${packageName}`
|
|
13
|
-
const response = await
|
|
13
|
+
const response = await fetchUrl(requestUrl, {
|
|
14
14
|
method: "GET",
|
|
15
15
|
headers: {
|
|
16
16
|
// "user-agent": "jsenv",
|
package/src/internal/publish.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url"
|
|
2
|
+
import { readFileSync, writeFileSync } from "node:fs"
|
|
1
3
|
import { exec } from "node:child_process"
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { UNICODE } from "@jsenv/log"
|
|
4
|
+
import { createTaskLog } from "@jsenv/log"
|
|
5
|
+
import { removeEntry } from "@jsenv/filesystem"
|
|
5
6
|
|
|
6
7
|
import { setNpmConfig } from "./setNpmConfig.js"
|
|
7
8
|
|
|
@@ -13,156 +14,152 @@ export const publish = async ({
|
|
|
13
14
|
registryUrl,
|
|
14
15
|
token,
|
|
15
16
|
}) => {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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)
|
|
29
37
|
packageObject.publishConfig = packageObject.publishConfig || {}
|
|
30
38
|
packageObject.publishConfig.registry = registryUrl
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
JSON.stringify(packageObject, null, " "),
|
|
35
|
-
),
|
|
39
|
+
writeFileSync(
|
|
40
|
+
rootPackageFileUrl,
|
|
41
|
+
JSON.stringify(packageObject, null, " "),
|
|
36
42
|
)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
51
58
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
await Promise
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
// but returns previous version if asked immediatly
|
|
75
|
-
// after for the last published version.
|
|
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.
|
|
76
81
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
81
86
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
resolve({
|
|
101
|
-
success: true,
|
|
102
|
-
reason: "already-published",
|
|
103
|
-
})
|
|
104
|
-
}
|
|
105
|
-
// github publish conflict
|
|
106
|
-
else if (
|
|
107
|
-
error.message.includes(
|
|
108
|
-
"ambiguous package version in package.json",
|
|
109
|
-
)
|
|
110
|
-
) {
|
|
111
|
-
resolve({
|
|
112
|
-
success: true,
|
|
113
|
-
reason: "already-published",
|
|
114
|
-
})
|
|
115
|
-
} else {
|
|
116
|
-
reject(error)
|
|
117
|
-
}
|
|
118
|
-
} 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
|
+
) {
|
|
119
105
|
resolve({
|
|
120
106
|
success: true,
|
|
121
|
-
reason: "published",
|
|
107
|
+
reason: "already-published",
|
|
122
108
|
})
|
|
123
109
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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)`)
|
|
143
144
|
}
|
|
144
|
-
|
|
145
|
+
publishTask.done()
|
|
145
146
|
return {
|
|
146
|
-
success:
|
|
147
|
-
reason
|
|
147
|
+
success: true,
|
|
148
|
+
reason,
|
|
148
149
|
}
|
|
150
|
+
} finally {
|
|
151
|
+
restoreProcessEnv()
|
|
152
|
+
restorePackageFile()
|
|
153
|
+
restoreNpmConfigFile()
|
|
149
154
|
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
)
|
|
157
|
-
} else {
|
|
158
|
-
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,
|
|
159
161
|
}
|
|
160
|
-
} else {
|
|
161
|
-
logger.error(`${UNICODE.FAILURE} error when publishing ${packageSlug} in ${registryUrl}
|
|
162
|
-
--- error stack ---
|
|
163
|
-
${reason.stack}`)
|
|
164
162
|
}
|
|
165
|
-
return { success, reason }
|
|
166
163
|
}
|
|
167
164
|
|
|
168
165
|
const computeRegistryTokenKey = (registryUrl) => {
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { fileURLToPath } from "node:url"
|
|
2
|
+
import { readFileSync } from "node:fs"
|
|
3
3
|
|
|
4
|
-
export const readProjectPackage =
|
|
5
|
-
const
|
|
6
|
-
let
|
|
4
|
+
export const readProjectPackage = ({ rootDirectoryUrl }) => {
|
|
5
|
+
const packageFileUrlObject = new URL("./package.json", rootDirectoryUrl)
|
|
6
|
+
let packageInProject
|
|
7
7
|
try {
|
|
8
|
-
const packageString =
|
|
8
|
+
const packageString = String(readFileSync(packageFileUrlObject))
|
|
9
9
|
try {
|
|
10
|
-
|
|
10
|
+
packageInProject = JSON.parse(packageString)
|
|
11
11
|
} catch (e) {
|
|
12
12
|
if (e.name === "SyntaxError") {
|
|
13
13
|
throw new Error(`syntax error while parsing project package.json
|
|
14
14
|
--- syntax error stack ---
|
|
15
15
|
${e.stack}
|
|
16
16
|
--- package.json path ---
|
|
17
|
-
${
|
|
17
|
+
${fileURLToPath(packageFileUrlObject)}`)
|
|
18
18
|
}
|
|
19
19
|
throw e
|
|
20
20
|
}
|
|
@@ -23,10 +23,10 @@ ${urlToFileSystemPath(packageFileUrl)}`)
|
|
|
23
23
|
throw new Error(
|
|
24
24
|
`cannot find project package.json
|
|
25
25
|
--- package.json path ---
|
|
26
|
-
${
|
|
26
|
+
${fileURLToPath(packageFileUrlObject)}`,
|
|
27
27
|
)
|
|
28
28
|
}
|
|
29
29
|
throw e
|
|
30
30
|
}
|
|
31
|
-
return
|
|
31
|
+
return packageInProject
|
|
32
32
|
}
|
package/{main.js → src/main.js}
RENAMED
package/src/publishPackage.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
|
|
2
|
-
import { createLogger } from "@jsenv/
|
|
2
|
+
import { createLogger } from "@jsenv/log"
|
|
3
3
|
|
|
4
4
|
import { fetchLatestInRegistry } from "./internal/fetchLatestInRegistry.js"
|
|
5
5
|
import { publish } from "./internal/publish.js"
|
|
@@ -32,9 +32,7 @@ export const publishPackage = async ({
|
|
|
32
32
|
assertRegistriesConfig(registriesConfig)
|
|
33
33
|
|
|
34
34
|
logger.debug(`reading project package.json`)
|
|
35
|
-
const packageInProject =
|
|
36
|
-
rootDirectoryUrl,
|
|
37
|
-
})
|
|
35
|
+
const packageInProject = readProjectPackage({ rootDirectoryUrl })
|
|
38
36
|
|
|
39
37
|
const { name: packageName, version: packageVersion } = packageInProject
|
|
40
38
|
logger.info(`${packageName}@${packageVersion} found in package.json`)
|