forked from JS-DevTools/npm-publish
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnpm.ts
146 lines (126 loc) · 4.14 KB
/
npm.ts
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
import * as ezSpawn from "@jsdevtools/ez-spawn";
import { ono } from "@jsdevtools/ono";
import { StdioOptions } from "child_process";
import { dirname, resolve } from "path";
import { SemVer } from "semver";
import { NormalizedOptions } from "./normalize-options";
import {
getNpmConfigPath,
readNpmConfig,
setUpdatedNpmConfig,
writeNpmConfig,
} from "./npm-config";
import { getNpmEnvironment } from "./npm-env";
import { Manifest } from "./read-manifest";
/**
* Runs NPM commands.
* @internal
*/
export const npm = {
/**
* Gets the latest published version of the specified package.
*/
async getLatestVersion(
name: string,
options: NormalizedOptions
): Promise<SemVer> {
// Update the NPM config with the specified registry and token
const configPath = await getNpmConfigPath(options);
const initialConfig = await readNpmConfig(configPath, options);
// Update the NPM config with the specified registry and token
await setUpdatedNpmConfig(initialConfig, configPath, options);
try {
let command = ["npm", "view"];
if (options.tag === "latest") {
command.push(name);
} else {
command.push(`${name}@${options.tag}`);
}
command.push("version");
// Get the environment variables to pass to NPM
let env = getNpmEnvironment(options);
// Run NPM to get the latest published version of the package
options.debug(`Running command: npm view ${name} version`, {
command,
env,
});
let result;
try {
result = await ezSpawn.async(command, { env });
} catch (err) {
// In case ezSpawn.async throws, it still has stdout and stderr properties.
result = err as ezSpawn.ProcessError;
}
let version = result.stdout.trim();
let error = result.stderr.trim();
let status = result.status || 0;
// If the package was not previously published, return version 0.0.0.
if ((status === 0 && !version) || error.includes("E404")) {
options.debug(
`The latest version of ${name} is at v0.0.0, as it was never published.`
);
return new SemVer("0.0.0");
} else if (result instanceof Error) {
// NPM failed for some reason
throw result;
}
// Parse/validate the version number
let semver = new SemVer(version);
options.debug(`The latest version of ${name} is at v${semver}`);
return semver;
} catch (error) {
throw ono(
error,
`Unable to determine the current version of ${name} on NPM.`
);
} finally {
await writeNpmConfig(configPath, initialConfig, options.debug);
}
},
/**
* Publishes the specified package to NPM
*/
async publish(
{ name, version }: Manifest,
options: NormalizedOptions
): Promise<void> {
const configPath = await getNpmConfigPath(options);
const initialConfig = await readNpmConfig(configPath, options);
// Update the NPM config with the specified registry and token
await setUpdatedNpmConfig(initialConfig, configPath, options);
try {
let command = ["npm", "publish"];
if (options.tag !== "latest") {
command.push("--tag", options.tag);
}
if (options.access) {
command.push("--access", options.access);
}
if (options.dryRun) {
command.push("--dry-run");
}
// Run "npm publish" in the package.json directory
let cwd = resolve(dirname(options.package));
// Determine whether to suppress NPM's output
let stdio: StdioOptions = options.quiet ? "pipe" : "inherit";
// Get the environment variables to pass to NPM
let env = getNpmEnvironment(options);
// Run NPM to publish the package
options.debug("Running command: npm publish", {
command,
stdio,
cwd,
env,
});
await ezSpawn.async(command, { cwd, stdio, env });
} catch (error) {
throw ono(
error,
`Unable to publish ${name} v${version} to ${options.registry}.`
);
} finally {
// Restore the npm config
await writeNpmConfig(configPath, initialConfig, options.debug);
}
},
};