@jsdevtools/npm-publish 3.1.1 → 4.0.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/README.md +39 -25
- package/bin/npm-publish.js +17 -7
- package/lib/action/core.d.ts +1 -1
- package/lib/action/core.js +16 -25
- package/lib/action/core.js.map +1 -1
- package/lib/action/main.js +5 -32
- package/lib/action/main.js.map +1 -1
- package/lib/cli/index.js +7 -11
- package/lib/cli/index.js.map +1 -1
- package/lib/cli/parse-cli-arguments.js +3 -10
- package/lib/cli/parse-cli-arguments.js.map +1 -1
- package/lib/compare-and-publish/compare-and-publish.d.ts +1 -1
- package/lib/compare-and-publish/compare-and-publish.js +16 -18
- package/lib/compare-and-publish/compare-and-publish.js.map +1 -1
- package/lib/compare-and-publish/compare-versions.d.ts +1 -1
- package/lib/compare-and-publish/compare-versions.js +12 -19
- package/lib/compare-and-publish/compare-versions.js.map +1 -1
- package/lib/compare-and-publish/get-arguments.js +6 -8
- package/lib/compare-and-publish/get-arguments.js.map +1 -1
- package/lib/compare-and-publish/index.js +1 -17
- package/lib/compare-and-publish/index.js.map +1 -1
- package/lib/errors.js +22 -41
- package/lib/errors.js.map +1 -1
- package/lib/format-publish-result.d.ts +1 -1
- package/lib/format-publish-result.js +3 -10
- package/lib/format-publish-result.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +4 -22
- package/lib/index.js.map +1 -1
- package/lib/normalize-options.d.ts +1 -1
- package/lib/normalize-options.js +18 -44
- package/lib/normalize-options.js.map +1 -1
- package/lib/npm/call-npm-cli.d.ts +1 -0
- package/lib/npm/call-npm-cli.js +15 -42
- package/lib/npm/call-npm-cli.js.map +1 -1
- package/lib/npm/index.js +2 -18
- package/lib/npm/index.js.map +1 -1
- package/lib/npm/use-npm-environment.d.ts +1 -1
- package/lib/npm/use-npm-environment.js +9 -16
- package/lib/npm/use-npm-environment.js.map +1 -1
- package/lib/npm-publish.js +10 -14
- package/lib/npm-publish.js.map +1 -1
- package/lib/options.js +4 -7
- package/lib/options.js.map +1 -1
- package/lib/read-manifest.js +27 -53
- package/lib/read-manifest.js.map +1 -1
- package/lib/results.d.ts +1 -1
- package/lib/results.js +2 -5
- package/lib/results.js.map +1 -1
- package/package.json +39 -42
- package/src/action/core.ts +7 -8
- package/src/action/main.ts +4 -4
- package/src/cli/index.ts +1 -1
- package/src/cli/parse-cli-arguments.ts +1 -0
- package/src/compare-and-publish/compare-and-publish.ts +12 -7
- package/src/compare-and-publish/compare-versions.ts +2 -2
- package/src/compare-and-publish/get-arguments.ts +4 -1
- package/src/errors.ts +1 -1
- package/src/format-publish-result.ts +1 -1
- package/src/index.ts +1 -1
- package/src/normalize-options.ts +13 -8
- package/src/npm/call-npm-cli.ts +14 -12
- package/src/npm/use-npm-environment.ts +1 -1
- package/src/npm-publish.ts +3 -3
- package/src/read-manifest.ts +16 -9
- package/src/results.ts +2 -1
- package/src/tar.d.ts +0 -3
package/src/normalize-options.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import os from "node:os";
|
|
2
2
|
|
|
3
3
|
import * as errors from "./errors.js";
|
|
4
|
-
import type { PackageManifest } from "./read-manifest.js";
|
|
5
4
|
import {
|
|
5
|
+
type Access,
|
|
6
6
|
ACCESS_PUBLIC,
|
|
7
7
|
ACCESS_RESTRICTED,
|
|
8
|
-
STRATEGY_UPGRADE,
|
|
9
|
-
STRATEGY_ALL,
|
|
10
|
-
type Access,
|
|
11
|
-
type Strategy,
|
|
12
|
-
type Options,
|
|
13
8
|
type Logger,
|
|
9
|
+
type Options,
|
|
10
|
+
type Strategy,
|
|
11
|
+
STRATEGY_ALL,
|
|
12
|
+
STRATEGY_UPGRADE,
|
|
14
13
|
} from "./options.js";
|
|
14
|
+
import type { PackageManifest } from "./read-manifest.js";
|
|
15
15
|
|
|
16
16
|
const REGISTRY_NPM = "https://registry.npmjs.org/";
|
|
17
17
|
export const TAG_LATEST = "latest";
|
|
@@ -97,8 +97,13 @@ const validateRegistry = (value: unknown): URL => {
|
|
|
97
97
|
};
|
|
98
98
|
|
|
99
99
|
const validateTag = (value: unknown): string => {
|
|
100
|
-
if (typeof value === "string"
|
|
101
|
-
|
|
100
|
+
if (typeof value === "string") {
|
|
101
|
+
const trimmedValue = value.trim();
|
|
102
|
+
const encodedValue = encodeURIComponent(trimmedValue);
|
|
103
|
+
|
|
104
|
+
if (trimmedValue.length > 0 && trimmedValue === encodedValue) {
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
102
107
|
}
|
|
103
108
|
|
|
104
109
|
throw new errors.InvalidTagError(value);
|
package/src/npm/call-npm-cli.ts
CHANGED
|
@@ -36,9 +36,11 @@ export const VIEW = "view";
|
|
|
36
36
|
export const PUBLISH = "publish";
|
|
37
37
|
|
|
38
38
|
export const E404 = "E404";
|
|
39
|
+
export const E409 = "E409";
|
|
39
40
|
export const EPUBLISHCONFLICT = "EPUBLISHCONFLICT";
|
|
40
41
|
|
|
41
|
-
const
|
|
42
|
+
const IS_WINDOWS = os.platform() === "win32";
|
|
43
|
+
const NPM = IS_WINDOWS ? "npm.cmd" : "npm";
|
|
42
44
|
const JSON_MATCH_RE = /(\{[\s\S]*\})/mu;
|
|
43
45
|
|
|
44
46
|
const baseArguments = (options: NpmCliOptions) =>
|
|
@@ -68,15 +70,14 @@ export async function callNpmCli<CommandT extends string>(
|
|
|
68
70
|
let error;
|
|
69
71
|
|
|
70
72
|
if (exitCode === 0) {
|
|
71
|
-
successData = parseJson
|
|
73
|
+
successData = parseJson(stdout) as SuccessData<CommandT> | undefined;
|
|
72
74
|
} else {
|
|
73
|
-
const errorPayload = parseJson
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
);
|
|
75
|
+
const errorPayload = parseJson(stdout, stderr) as
|
|
76
|
+
| { error?: { code?: unknown } }
|
|
77
|
+
| undefined;
|
|
77
78
|
|
|
78
|
-
if (errorPayload?.error?.code) {
|
|
79
|
-
errorCode =
|
|
79
|
+
if (typeof errorPayload?.error?.code === "string") {
|
|
80
|
+
errorCode = errorPayload.error.code.toUpperCase();
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
error = new errors.NpmCallError(command, exitCode, stderr);
|
|
@@ -106,10 +107,11 @@ async function execNpm(
|
|
|
106
107
|
|
|
107
108
|
const npm = childProcess.spawn(NPM, commandArguments, {
|
|
108
109
|
env: { ...process.env, ...environment },
|
|
110
|
+
shell: IS_WINDOWS,
|
|
109
111
|
});
|
|
110
112
|
|
|
111
|
-
npm.stdout.on("data", (data) => (stdout += data));
|
|
112
|
-
npm.stderr.on("data", (data) => (stderr += data));
|
|
113
|
+
npm.stdout.on("data", (data: string) => (stdout += data));
|
|
114
|
+
npm.stderr.on("data", (data: string) => (stderr += data));
|
|
113
115
|
npm.on("close", (code) => {
|
|
114
116
|
logger?.debug?.(`Received stdout: ${stdout}`);
|
|
115
117
|
logger?.debug?.(`Received stderr: ${stderr}`);
|
|
@@ -132,13 +134,13 @@ async function execNpm(
|
|
|
132
134
|
* @param values CLI outputs to check
|
|
133
135
|
* @returns Parsed JSON, if able to parse.
|
|
134
136
|
*/
|
|
135
|
-
function parseJson
|
|
137
|
+
function parseJson(...values: string[]): unknown {
|
|
136
138
|
for (const value of values) {
|
|
137
139
|
const jsonValue = JSON_MATCH_RE.exec(value)?.[1];
|
|
138
140
|
|
|
139
141
|
if (jsonValue) {
|
|
140
142
|
try {
|
|
141
|
-
return JSON.parse(jsonValue)
|
|
143
|
+
return JSON.parse(jsonValue);
|
|
142
144
|
} catch {
|
|
143
145
|
return undefined;
|
|
144
146
|
}
|
|
@@ -2,8 +2,8 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
|
|
5
|
-
import type { PackageManifest } from "../read-manifest.js";
|
|
6
5
|
import type { NormalizedOptions } from "../normalize-options.js";
|
|
6
|
+
import type { PackageManifest } from "../read-manifest.js";
|
|
7
7
|
|
|
8
8
|
export type NpmCliEnvironment = Record<string, string>;
|
|
9
9
|
|
package/src/npm-publish.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { readManifest } from "./read-manifest.js";
|
|
2
|
-
import { normalizeOptions } from "./normalize-options.js";
|
|
3
|
-
import { useNpmEnvironment } from "./npm/index.js";
|
|
4
1
|
import { compareAndPublish } from "./compare-and-publish/index.js";
|
|
5
2
|
import { formatPublishResult } from "./format-publish-result.js";
|
|
3
|
+
import { normalizeOptions } from "./normalize-options.js";
|
|
4
|
+
import { useNpmEnvironment } from "./npm/index.js";
|
|
6
5
|
import type { Options } from "./options.js";
|
|
6
|
+
import { readManifest } from "./read-manifest.js";
|
|
7
7
|
import type { Results } from "./results.js";
|
|
8
8
|
|
|
9
9
|
/**
|
package/src/read-manifest.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
|
|
3
4
|
import semverValid from "semver/functions/valid.js";
|
|
4
|
-
import tarList from "tar/lib/list.js";
|
|
5
5
|
import type { ReadEntry } from "tar";
|
|
6
|
+
import { list as tarList } from "tar/list";
|
|
7
|
+
import validatePackageName from "validate-npm-package-name";
|
|
8
|
+
|
|
6
9
|
import * as errors from "./errors.js";
|
|
7
10
|
|
|
8
11
|
/** A package manifest (package.json) and associated details. */
|
|
@@ -39,10 +42,14 @@ const isTarball = (file: unknown): file is string => {
|
|
|
39
42
|
return typeof file === "string" && path.extname(file) === TARBALL_EXTNAME;
|
|
40
43
|
};
|
|
41
44
|
|
|
42
|
-
const
|
|
45
|
+
const normalizeVersion = (version: unknown): string | undefined => {
|
|
43
46
|
return semverValid(version as string) ?? undefined;
|
|
44
47
|
};
|
|
45
48
|
|
|
49
|
+
const validateName = (name: unknown): name is string => {
|
|
50
|
+
return validatePackageName(name as string).validForNewPackages;
|
|
51
|
+
};
|
|
52
|
+
|
|
46
53
|
const readPackageJson = async (...pathSegments: string[]): Promise<string> => {
|
|
47
54
|
const file = path.resolve(...pathSegments);
|
|
48
55
|
|
|
@@ -55,14 +62,14 @@ const readPackageJson = async (...pathSegments: string[]): Promise<string> => {
|
|
|
55
62
|
|
|
56
63
|
const readTarballPackageJson = async (file: string): Promise<string> => {
|
|
57
64
|
const data: Buffer[] = [];
|
|
58
|
-
const
|
|
65
|
+
const onReadEntry = (entry: ReadEntry) => {
|
|
59
66
|
if (entry.path === "package/package.json") {
|
|
60
67
|
entry.on("data", (chunk) => data.push(chunk));
|
|
61
68
|
}
|
|
62
69
|
};
|
|
63
70
|
|
|
64
71
|
try {
|
|
65
|
-
await tarList({ file,
|
|
72
|
+
await tarList({ file, onReadEntry });
|
|
66
73
|
|
|
67
74
|
if (data.length === 0) {
|
|
68
75
|
throw new Error("package.json not found inside archive");
|
|
@@ -109,19 +116,19 @@ export async function readManifest(
|
|
|
109
116
|
|
|
110
117
|
try {
|
|
111
118
|
manifestJson = JSON.parse(manifestContents) as Record<string, unknown>;
|
|
112
|
-
name = manifestJson
|
|
113
|
-
version =
|
|
114
|
-
publishConfig = manifestJson
|
|
119
|
+
name = manifestJson.name;
|
|
120
|
+
version = normalizeVersion(manifestJson.version);
|
|
121
|
+
publishConfig = manifestJson.publishConfig ?? {};
|
|
115
122
|
} catch (error) {
|
|
116
123
|
throw new errors.PackageJsonParseError(packageSpec, error);
|
|
117
124
|
}
|
|
118
125
|
|
|
119
|
-
if (
|
|
126
|
+
if (!validateName(name)) {
|
|
120
127
|
throw new errors.InvalidPackageNameError(name);
|
|
121
128
|
}
|
|
122
129
|
|
|
123
130
|
if (typeof version !== "string") {
|
|
124
|
-
throw new errors.InvalidPackageVersionError(manifestJson
|
|
131
|
+
throw new errors.InvalidPackageVersionError(manifestJson.version);
|
|
125
132
|
}
|
|
126
133
|
|
|
127
134
|
if (
|
package/src/results.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { Access, Strategy } from "./options.js";
|
|
2
1
|
import type { ReleaseType as SemverReleaseType } from "semver";
|
|
3
2
|
|
|
3
|
+
import type { Access, Strategy } from "./options.js";
|
|
4
|
+
|
|
4
5
|
/** Release type */
|
|
5
6
|
export type ReleaseType = SemverReleaseType | typeof INITIAL | typeof DIFFERENT;
|
|
6
7
|
|
package/src/tar.d.ts
DELETED