@jsdevtools/npm-publish 2.0.0 → 2.2.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 +92 -32
- package/lib/action/core.d.ts +2 -2
- package/lib/action/core.js +7 -2
- package/lib/action/core.js.map +1 -1
- package/lib/action/main.js +2 -0
- package/lib/action/main.js.map +1 -1
- package/lib/cli/index.d.ts +1 -1
- package/lib/cli/index.js +7 -1
- package/lib/cli/index.js.map +1 -1
- package/lib/cli/parse-cli-arguments.js +8 -1
- package/lib/cli/parse-cli-arguments.js.map +1 -1
- package/lib/compare-and-publish/compare-and-publish.d.ts +21 -0
- package/lib/compare-and-publish/compare-and-publish.js +53 -0
- package/lib/compare-and-publish/compare-and-publish.js.map +1 -0
- package/lib/compare-and-publish/compare-versions.d.ts +16 -0
- package/lib/compare-and-publish/compare-versions.js +41 -0
- package/lib/compare-and-publish/compare-versions.js.map +1 -0
- package/lib/compare-and-publish/get-arguments.d.ts +21 -0
- package/lib/compare-and-publish/get-arguments.js +50 -0
- package/lib/compare-and-publish/get-arguments.js.map +1 -0
- package/lib/compare-and-publish/index.d.ts +1 -0
- package/lib/compare-and-publish/index.js +18 -0
- package/lib/compare-and-publish/index.js.map +1 -0
- package/lib/errors.d.ts +3 -0
- package/lib/errors.js +8 -1
- package/lib/errors.js.map +1 -1
- package/lib/format-publish-result.d.ts +3 -3
- package/lib/format-publish-result.js +5 -5
- package/lib/format-publish-result.js.map +1 -1
- package/lib/normalize-options.d.ts +5 -2
- package/lib/normalize-options.js +15 -12
- package/lib/normalize-options.js.map +1 -1
- package/lib/npm/call-npm-cli.d.ts +27 -4
- package/lib/npm/call-npm-cli.js +50 -27
- package/lib/npm/call-npm-cli.js.map +1 -1
- package/lib/npm/index.d.ts +2 -29
- package/lib/npm/index.js +16 -38
- package/lib/npm/index.js.map +1 -1
- package/lib/npm/use-npm-environment.d.ts +4 -2
- package/lib/npm/use-npm-environment.js +7 -5
- package/lib/npm/use-npm-environment.js.map +1 -1
- package/lib/npm-publish.js +7 -12
- package/lib/npm-publish.js.map +1 -1
- package/lib/options.d.ts +28 -9
- package/lib/read-manifest.d.ts +4 -7
- package/lib/read-manifest.js +4 -1
- package/lib/read-manifest.js.map +1 -1
- package/lib/results.d.ts +5 -1
- package/lib/results.js +3 -0
- package/lib/results.js.map +1 -1
- package/package.json +18 -14
- package/src/action/core.ts +7 -3
- package/src/action/main.ts +2 -0
- package/src/cli/index.ts +7 -1
- package/src/cli/parse-cli-arguments.ts +11 -1
- package/src/compare-and-publish/compare-and-publish.ts +79 -0
- package/src/compare-and-publish/compare-versions.ts +48 -0
- package/src/compare-and-publish/get-arguments.ts +61 -0
- package/src/compare-and-publish/index.ts +1 -0
- package/src/errors.ts +7 -0
- package/src/format-publish-result.ts +6 -6
- package/src/normalize-options.ts +18 -12
- package/src/npm/call-npm-cli.ts +94 -48
- package/src/npm/index.ts +2 -64
- package/src/npm/use-npm-environment.ts +10 -4
- package/src/npm-publish.ts +11 -18
- package/src/options.ts +30 -9
- package/src/read-manifest.ts +8 -9
- package/src/results.ts +6 -1
- package/lib/compare-versions.d.ts +0 -20
- package/lib/compare-versions.js +0 -36
- package/lib/compare-versions.js.map +0 -1
- package/lib/npm/get-publish-arguments.d.ts +0 -9
- package/lib/npm/get-publish-arguments.js +0 -29
- package/lib/npm/get-publish-arguments.js.map +0 -1
- package/src/compare-versions.ts +0 -52
- package/src/npm/get-publish-arguments.ts +0 -34
package/lib/read-manifest.d.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export interface ManifestReadResult {
|
|
3
|
-
packageSpec: string;
|
|
4
|
-
manifest: PackageManifest;
|
|
5
|
-
}
|
|
6
|
-
/** A package manifest (package.json) */
|
|
1
|
+
/** A package manifest (package.json) and associated details. */
|
|
7
2
|
export interface PackageManifest {
|
|
3
|
+
packageSpec: string;
|
|
8
4
|
name: string;
|
|
9
5
|
version: string;
|
|
10
6
|
scope: string | undefined;
|
|
@@ -15,6 +11,7 @@ export interface PackagePublishConfig {
|
|
|
15
11
|
tag?: string;
|
|
16
12
|
access?: string;
|
|
17
13
|
registry?: string;
|
|
14
|
+
provenance?: boolean;
|
|
18
15
|
}
|
|
19
16
|
/**
|
|
20
17
|
* Reads the package manifest (package.json) and returns its parsed contents.
|
|
@@ -22,4 +19,4 @@ export interface PackagePublishConfig {
|
|
|
22
19
|
* @param packagePath The path to the package being published.
|
|
23
20
|
* @returns The parsed package metadata.
|
|
24
21
|
*/
|
|
25
|
-
export declare function readManifest(packagePath: unknown): Promise<
|
|
22
|
+
export declare function readManifest(packagePath: unknown): Promise<PackageManifest>;
|
package/lib/read-manifest.js
CHANGED
|
@@ -128,7 +128,10 @@ async function readManifest(packagePath) {
|
|
|
128
128
|
}
|
|
129
129
|
return {
|
|
130
130
|
packageSpec,
|
|
131
|
-
|
|
131
|
+
name,
|
|
132
|
+
version,
|
|
133
|
+
publishConfig,
|
|
134
|
+
scope: SCOPE_RE.exec(name)?.[1],
|
|
132
135
|
};
|
|
133
136
|
}
|
|
134
137
|
exports.readManifest = readManifest;
|
package/lib/read-manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-manifest.js","sourceRoot":"","sources":["../src/read-manifest.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gEAAkC;AAClC,0DAA6B;AAC7B,mCAA8C;AAC9C,6BAAsD;AAEtD,oDAAsC;
|
|
1
|
+
{"version":3,"file":"read-manifest.js","sourceRoot":"","sources":["../src/read-manifest.ts"],"names":[],"mappings":"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"}
|
package/lib/results.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { Access, Strategy } from "./options.js";
|
|
2
|
-
import type { ReleaseType } from "
|
|
2
|
+
import type { ReleaseType as SemverReleaseType } from "semver";
|
|
3
|
+
/** Release type */
|
|
4
|
+
export type ReleaseType = SemverReleaseType | typeof INITIAL | typeof DIFFERENT;
|
|
5
|
+
export declare const INITIAL = "initial";
|
|
6
|
+
export declare const DIFFERENT = "different";
|
|
3
7
|
/** Results of the publish */
|
|
4
8
|
export interface Results {
|
|
5
9
|
/**
|
package/lib/results.js
CHANGED
package/lib/results.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"results.js","sourceRoot":"","sources":["../src/results.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"results.js","sourceRoot":"","sources":["../src/results.ts"],"names":[],"mappings":";;;AAKa,QAAA,OAAO,GAAG,SAAS,CAAC;AACpB,QAAA,SAAS,GAAG,WAAW,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsdevtools/npm-publish",
|
|
3
3
|
"description": "Fast, easy publishing to NPM",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.2.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github-action",
|
|
7
7
|
"npm",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"!__tests__"
|
|
32
32
|
],
|
|
33
33
|
"scripts": {
|
|
34
|
-
"all": "npm run clean && npm run build && npm run
|
|
34
|
+
"all": "npm run clean && npm run build && npm run format && npm run coverage",
|
|
35
35
|
"clean": "rimraf coverage lib dist e2e/fixture *.tgz",
|
|
36
36
|
"lint": "npm run _eslint && npm run _prettier -- --check",
|
|
37
37
|
"format": "npm run _eslint -- --fix && npm run _prettier -- --write",
|
|
@@ -41,37 +41,41 @@
|
|
|
41
41
|
"test": "vitest",
|
|
42
42
|
"coverage": "vitest run --coverage",
|
|
43
43
|
"_eslint": "eslint \"**/*.@(js|ts)\"",
|
|
44
|
-
"_prettier": "prettier \"**/*.@(js|ts|json|md|
|
|
44
|
+
"_prettier": "prettier \"**/*.@(js|ts|json|md|yaml)\""
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
47
47
|
"node": ">=16"
|
|
48
48
|
},
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public",
|
|
51
|
+
"provenance": true
|
|
52
|
+
},
|
|
49
53
|
"devDependencies": {
|
|
50
54
|
"@actions/core": "^1.10.0",
|
|
51
55
|
"@types/command-line-args": "^5.0.0",
|
|
52
|
-
"@types/node": "^18.
|
|
56
|
+
"@types/node": "^18.16.3",
|
|
53
57
|
"@types/tar": "^6.1.4",
|
|
54
|
-
"@typescript-eslint/eslint-plugin": "^5.59.
|
|
55
|
-
"@typescript-eslint/parser": "^5.59.
|
|
56
|
-
"@vitest/coverage-istanbul": "^0.
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
|
59
|
+
"@typescript-eslint/parser": "^5.59.2",
|
|
60
|
+
"@vitest/coverage-istanbul": "^0.31.4",
|
|
57
61
|
"concurrently": "^8.0.1",
|
|
58
|
-
"esbuild": "0.17.
|
|
59
|
-
"eslint": "^8.
|
|
62
|
+
"esbuild": "^0.17.18",
|
|
63
|
+
"eslint": "^8.39.0",
|
|
60
64
|
"eslint-config-prettier": "^8.8.0",
|
|
61
65
|
"eslint-import-resolver-typescript": "^3.5.5",
|
|
62
66
|
"eslint-plugin-import": "npm:eslint-plugin-i@^2.27.5-1",
|
|
63
|
-
"eslint-plugin-jsdoc": "^43.
|
|
64
|
-
"eslint-plugin-n": "^
|
|
67
|
+
"eslint-plugin-jsdoc": "^43.1.1",
|
|
68
|
+
"eslint-plugin-n": "^16.0.0",
|
|
65
69
|
"eslint-plugin-promise": "^6.1.1",
|
|
66
70
|
"eslint-plugin-sonarjs": "^0.19.0",
|
|
67
|
-
"eslint-plugin-unicorn": "^46.0.
|
|
68
|
-
"prettier": "^2.8.
|
|
71
|
+
"eslint-plugin-unicorn": "^46.0.1",
|
|
72
|
+
"prettier": "^2.8.8",
|
|
69
73
|
"prettier-plugin-jsdoc": "^0.4.2",
|
|
70
74
|
"rimraf": "^5.0.0",
|
|
71
75
|
"testdouble": "^3.17.2",
|
|
72
76
|
"testdouble-vitest": "^0.1.2",
|
|
73
77
|
"typescript": "^5.0.4",
|
|
74
|
-
"vitest": "^0.
|
|
78
|
+
"vitest": "^0.31.4"
|
|
75
79
|
},
|
|
76
80
|
"dependencies": {
|
|
77
81
|
"@types/semver": "^7.3.13",
|
package/src/action/core.ts
CHANGED
|
@@ -45,10 +45,14 @@ export function getRequiredSecretInput(name: string): string {
|
|
|
45
45
|
* Get a boolean input by name.
|
|
46
46
|
*
|
|
47
47
|
* @param name Input name
|
|
48
|
-
* @returns True if value is "true", false if
|
|
48
|
+
* @returns True if value is "true", false if "false", undefined if unset
|
|
49
49
|
*/
|
|
50
|
-
export function getBooleanInput(name: string): boolean {
|
|
51
|
-
|
|
50
|
+
export function getBooleanInput(name: string): boolean | undefined {
|
|
51
|
+
const inputString = ghGetInput(name).toLowerCase();
|
|
52
|
+
|
|
53
|
+
if (inputString === "true") return true;
|
|
54
|
+
if (inputString === "false") return false;
|
|
55
|
+
return undefined;
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
/**
|
package/src/action/main.ts
CHANGED
|
@@ -10,7 +10,9 @@ async function run(): Promise<void> {
|
|
|
10
10
|
package: core.getInput("package"),
|
|
11
11
|
tag: core.getInput("tag"),
|
|
12
12
|
access: core.getInput("access"),
|
|
13
|
+
provenance: core.getBooleanInput("provenance"),
|
|
13
14
|
strategy: core.getInput("strategy"),
|
|
15
|
+
ignoreScripts: core.getBooleanInput("ignore-scripts"),
|
|
14
16
|
dryRun: core.getBooleanInput("dry-run"),
|
|
15
17
|
logger: core.logger,
|
|
16
18
|
temporaryDirectory: process.env["RUNNER_TEMP"],
|
package/src/cli/index.ts
CHANGED
|
@@ -23,11 +23,17 @@ Options:
|
|
|
23
23
|
Defaults to "latest".
|
|
24
24
|
|
|
25
25
|
--access <access> Package access, may be "public" or "restricted".
|
|
26
|
-
See documentation for details.
|
|
26
|
+
See npm documentation for details.
|
|
27
|
+
|
|
28
|
+
--provenance Publish with provenance statements.
|
|
29
|
+
See npm documentation for details.
|
|
27
30
|
|
|
28
31
|
--strategy <strategy> Publish strategy, may be "all" or "upgrade".
|
|
29
32
|
Defaults to "all", see documentation for details.
|
|
30
33
|
|
|
34
|
+
--ignore-scripts Ignore lifecycle scripts as a security precaution.
|
|
35
|
+
Defaults to true.
|
|
36
|
+
|
|
31
37
|
--dry-run Do not actually publish anything.
|
|
32
38
|
--quiet Only print errors.
|
|
33
39
|
--debug Print debug logs.
|
|
@@ -9,7 +9,9 @@ const ARGUMENTS_OPTIONS = [
|
|
|
9
9
|
{ name: "registry", type: String },
|
|
10
10
|
{ name: "tag", type: String },
|
|
11
11
|
{ name: "access", type: String },
|
|
12
|
+
{ name: "provenance", type: Boolean },
|
|
12
13
|
{ name: "strategy", type: String },
|
|
14
|
+
{ name: "no-ignore-scripts", type: Boolean },
|
|
13
15
|
{ name: "dry-run", type: Boolean },
|
|
14
16
|
{ name: "quiet", type: Boolean },
|
|
15
17
|
{ name: "debug", type: Boolean },
|
|
@@ -33,11 +35,19 @@ export interface ParsedArguments {
|
|
|
33
35
|
* @returns A parsed object of options.
|
|
34
36
|
*/
|
|
35
37
|
export function parseCliArguments(argv: string[]): ParsedArguments {
|
|
36
|
-
const { help, version, quiet, debug, ...
|
|
38
|
+
const { help, version, quiet, debug, ...optionFlags } = commandLineArgs(
|
|
37
39
|
ARGUMENTS_OPTIONS,
|
|
38
40
|
{ argv, camelCase: true }
|
|
39
41
|
);
|
|
40
42
|
|
|
43
|
+
const options = Object.fromEntries(
|
|
44
|
+
Object.entries(optionFlags).map(([key, value]) => {
|
|
45
|
+
return key === "noIgnoreScripts"
|
|
46
|
+
? ["ignoreScripts", !value]
|
|
47
|
+
: [key, value];
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
|
|
41
51
|
return {
|
|
42
52
|
help: Boolean(help),
|
|
43
53
|
version: Boolean(version),
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { PackageManifest } from "../read-manifest.js";
|
|
2
|
+
import type { NormalizedOptions } from "../normalize-options.js";
|
|
3
|
+
import {
|
|
4
|
+
VIEW,
|
|
5
|
+
PUBLISH,
|
|
6
|
+
E404,
|
|
7
|
+
EPUBLISHCONFLICT,
|
|
8
|
+
callNpmCli,
|
|
9
|
+
type NpmCliEnvironment,
|
|
10
|
+
} from "../npm/index.js";
|
|
11
|
+
import { compareVersions, type VersionComparison } from "./compare-versions.js";
|
|
12
|
+
import { getViewArguments, getPublishArguments } from "./get-arguments.js";
|
|
13
|
+
|
|
14
|
+
export interface PublishResult extends VersionComparison {
|
|
15
|
+
id: string | undefined;
|
|
16
|
+
files: PublishFile[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface PublishFile {
|
|
20
|
+
path: string;
|
|
21
|
+
size: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get the currently published versions of a package and publish if needed.
|
|
26
|
+
*
|
|
27
|
+
* @param manifest The package to potentially publish.
|
|
28
|
+
* @param options Configuration options.
|
|
29
|
+
* @param environment Environment variables for the npm cli.
|
|
30
|
+
* @returns Information about the publish, including if it occurred.
|
|
31
|
+
*/
|
|
32
|
+
export async function compareAndPublish(
|
|
33
|
+
manifest: PackageManifest,
|
|
34
|
+
options: NormalizedOptions,
|
|
35
|
+
environment: NpmCliEnvironment
|
|
36
|
+
): Promise<PublishResult> {
|
|
37
|
+
const { name, version, packageSpec } = manifest;
|
|
38
|
+
const cliOptions = {
|
|
39
|
+
environment,
|
|
40
|
+
ignoreScripts: options.ignoreScripts.value,
|
|
41
|
+
logger: options.logger,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const viewArguments = getViewArguments(name, options);
|
|
45
|
+
const publishArguments = getPublishArguments(packageSpec, options);
|
|
46
|
+
let viewCall = await callNpmCli(VIEW, viewArguments, cliOptions);
|
|
47
|
+
|
|
48
|
+
// `npm view` will succeed with no output the package exists in the registry
|
|
49
|
+
// with no `latest` tag. This is only possible with third-party registries.
|
|
50
|
+
// https://github.com/npm/cli/issues/6408
|
|
51
|
+
if (!viewCall.successData && !viewCall.error) {
|
|
52
|
+
// Retry the call to `npm view` with the configured publish tag,
|
|
53
|
+
// to at least try to get something.
|
|
54
|
+
const viewWithTagArguments = getViewArguments(name, options, true);
|
|
55
|
+
viewCall = await callNpmCli(VIEW, viewWithTagArguments, cliOptions);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (viewCall.error && viewCall.errorCode !== E404) {
|
|
59
|
+
throw viewCall.error;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const comparison = compareVersions(version, viewCall.successData, options);
|
|
63
|
+
const publishCall = comparison.type
|
|
64
|
+
? await callNpmCli(PUBLISH, publishArguments, cliOptions)
|
|
65
|
+
: { successData: undefined, errorCode: undefined, error: undefined };
|
|
66
|
+
|
|
67
|
+
if (publishCall.error && publishCall.errorCode !== EPUBLISHCONFLICT) {
|
|
68
|
+
throw publishCall.error;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const { successData: publishData } = publishCall;
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
id: publishData?.id,
|
|
75
|
+
files: publishData?.files ?? [],
|
|
76
|
+
type: publishData ? comparison.type : undefined,
|
|
77
|
+
oldVersion: comparison.oldVersion,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import semverDifference from "semver/functions/diff.js";
|
|
2
|
+
import semverGreaterThan from "semver/functions/gt.js";
|
|
3
|
+
import semverValid from "semver/functions/valid.js";
|
|
4
|
+
|
|
5
|
+
import { STRATEGY_ALL } from "../options.js";
|
|
6
|
+
import type { NormalizedOptions } from "../normalize-options.js";
|
|
7
|
+
import type { ReleaseType } from "../results.js";
|
|
8
|
+
import type { NpmViewData } from "../npm/index.js";
|
|
9
|
+
|
|
10
|
+
export interface VersionComparison {
|
|
11
|
+
type: ReleaseType | undefined;
|
|
12
|
+
oldVersion: string | undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const INITIAL = "initial";
|
|
16
|
+
const DIFFERENT = "different";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Compare previously published versions with the package's current version.
|
|
20
|
+
*
|
|
21
|
+
* @param currentVersion The current package version.
|
|
22
|
+
* @param publishedVersions The versions that have already been published.
|
|
23
|
+
* @param options Configuration options
|
|
24
|
+
* @returns The release type and previous version.
|
|
25
|
+
*/
|
|
26
|
+
export function compareVersions(
|
|
27
|
+
currentVersion: string,
|
|
28
|
+
publishedVersions: NpmViewData | undefined,
|
|
29
|
+
options: NormalizedOptions
|
|
30
|
+
): VersionComparison {
|
|
31
|
+
const { versions, "dist-tags": tags } = publishedVersions ?? {};
|
|
32
|
+
const { strategy, tag: publishTag } = options;
|
|
33
|
+
const oldVersion = semverValid(tags?.[publishTag.value]) ?? undefined;
|
|
34
|
+
const isUnique = !versions?.includes(currentVersion);
|
|
35
|
+
let type: ReleaseType | undefined;
|
|
36
|
+
|
|
37
|
+
if (isUnique) {
|
|
38
|
+
if (!oldVersion) {
|
|
39
|
+
type = INITIAL;
|
|
40
|
+
} else if (semverGreaterThan(currentVersion, oldVersion)) {
|
|
41
|
+
type = semverDifference(currentVersion, oldVersion) ?? DIFFERENT;
|
|
42
|
+
} else if (strategy.value === STRATEGY_ALL) {
|
|
43
|
+
type = DIFFERENT;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return { type, oldVersion };
|
|
48
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { NormalizedOptions } from "../normalize-options.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Given a package name and publish configuration, get the NPM CLI view
|
|
5
|
+
* arguments.
|
|
6
|
+
*
|
|
7
|
+
* @param packageName Package name.
|
|
8
|
+
* @param options Publish configuration.
|
|
9
|
+
* @param retryWithTag Include a non-latest tag in the package spec for a rety
|
|
10
|
+
* attempt.
|
|
11
|
+
* @returns Arguments to pass to the NPM CLI. If `retryWithTag` is true, but the
|
|
12
|
+
* publish config is using the `latest` tag, will return `undefined`.
|
|
13
|
+
*/
|
|
14
|
+
export function getViewArguments(
|
|
15
|
+
packageName: string,
|
|
16
|
+
options: NormalizedOptions,
|
|
17
|
+
retryWithTag = false
|
|
18
|
+
): string[] {
|
|
19
|
+
const packageSpec = retryWithTag
|
|
20
|
+
? `${packageName}@${options.tag.value}`
|
|
21
|
+
: packageName;
|
|
22
|
+
|
|
23
|
+
return [packageSpec, "dist-tags", "versions"];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Given a publish configuration, get the NPM CLI publish arguments.
|
|
28
|
+
*
|
|
29
|
+
* @param packageSpec Package specification path.
|
|
30
|
+
* @param options Publish configuration.
|
|
31
|
+
* @returns Arguments to pass to the NPM CLI.
|
|
32
|
+
*/
|
|
33
|
+
export function getPublishArguments(
|
|
34
|
+
packageSpec: string,
|
|
35
|
+
options: NormalizedOptions
|
|
36
|
+
): string[] {
|
|
37
|
+
const { tag, access, dryRun, provenance } = options;
|
|
38
|
+
const publishArguments = [];
|
|
39
|
+
|
|
40
|
+
if (packageSpec.length > 0) {
|
|
41
|
+
publishArguments.push(packageSpec);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!tag.isDefault) {
|
|
45
|
+
publishArguments.push("--tag", tag.value);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!access.isDefault && access.value) {
|
|
49
|
+
publishArguments.push("--access", access.value);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!provenance.isDefault && provenance.value) {
|
|
53
|
+
publishArguments.push("--provenance");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!dryRun.isDefault && dryRun.value) {
|
|
57
|
+
publishArguments.push("--dry-run");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return publishArguments;
|
|
61
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./compare-and-publish.js";
|
package/src/errors.ts
CHANGED
|
@@ -95,6 +95,13 @@ export class InvalidTokenError extends TypeError {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
export class InvalidTagError extends TypeError {
|
|
99
|
+
public constructor(value: unknown) {
|
|
100
|
+
super(`Tag must be a non-empty string, got "${String(value)}".`);
|
|
101
|
+
this.name = "InvalidTagError";
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
98
105
|
export class InvalidAccessError extends TypeError {
|
|
99
106
|
public constructor(value: unknown) {
|
|
100
107
|
super(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import os from "node:os";
|
|
2
2
|
|
|
3
|
-
import type { PublishResult } from "./
|
|
3
|
+
import type { PublishResult } from "./compare-and-publish/index.js";
|
|
4
4
|
import type { PackageManifest } from "./read-manifest.js";
|
|
5
5
|
import type { NormalizedOptions } from "./normalize-options.js";
|
|
6
6
|
|
|
@@ -9,22 +9,22 @@ import type { NormalizedOptions } from "./normalize-options.js";
|
|
|
9
9
|
*
|
|
10
10
|
* @param manifest Package manifest
|
|
11
11
|
* @param options Configuration options.
|
|
12
|
-
* @param
|
|
12
|
+
* @param result Results from running npm publish.
|
|
13
13
|
* @returns Formatted string.
|
|
14
14
|
*/
|
|
15
15
|
export function formatPublishResult(
|
|
16
16
|
manifest: PackageManifest,
|
|
17
17
|
options: NormalizedOptions,
|
|
18
|
-
|
|
18
|
+
result: PublishResult
|
|
19
19
|
): string {
|
|
20
|
-
if (
|
|
20
|
+
if (result.id === undefined) {
|
|
21
21
|
return `🙅♀️ ${manifest.name}@${manifest.version} publish skipped.`;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
return [
|
|
25
|
-
`📦 ${
|
|
25
|
+
`📦 ${result.id}${options.dryRun.value ? " (DRY RUN)" : ""}`,
|
|
26
26
|
"=== Contents ===",
|
|
27
|
-
...
|
|
27
|
+
...result.files.map(({ path, size }) => `${formatSize(size)}\t${path}`),
|
|
28
28
|
].join(os.EOL);
|
|
29
29
|
}
|
|
30
30
|
|
package/src/normalize-options.ts
CHANGED
|
@@ -13,8 +13,8 @@ import {
|
|
|
13
13
|
type Logger,
|
|
14
14
|
} from "./options.js";
|
|
15
15
|
|
|
16
|
-
const
|
|
17
|
-
const
|
|
16
|
+
const REGISTRY_NPM = "https://registry.npmjs.org/";
|
|
17
|
+
export const TAG_LATEST = "latest";
|
|
18
18
|
|
|
19
19
|
/** Normalized and sanitized auth, publish, and runtime configurations. */
|
|
20
20
|
export interface NormalizedOptions {
|
|
@@ -22,6 +22,8 @@ export interface NormalizedOptions {
|
|
|
22
22
|
token: string;
|
|
23
23
|
tag: ConfigValue<string>;
|
|
24
24
|
access: ConfigValue<Access | undefined>;
|
|
25
|
+
provenance: ConfigValue<boolean>;
|
|
26
|
+
ignoreScripts: ConfigValue<boolean>;
|
|
25
27
|
dryRun: ConfigValue<boolean>;
|
|
26
28
|
strategy: ConfigValue<Strategy>;
|
|
27
29
|
logger: Logger | undefined;
|
|
@@ -37,28 +39,32 @@ export interface ConfigValue<TValue> {
|
|
|
37
39
|
/**
|
|
38
40
|
* Normalizes and sanitizes options, and fills-in any default values.
|
|
39
41
|
*
|
|
40
|
-
* @param options User-input options.
|
|
41
42
|
* @param manifest Package metadata from package.json.
|
|
43
|
+
* @param options User-input options.
|
|
42
44
|
* @returns Validated auth and publish configuration.
|
|
43
45
|
*/
|
|
44
46
|
export function normalizeOptions(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
manifest: PackageManifest,
|
|
48
|
+
options: Options
|
|
47
49
|
): NormalizedOptions {
|
|
48
|
-
const defaultTag = manifest.publishConfig?.tag ??
|
|
50
|
+
const defaultTag = manifest.publishConfig?.tag ?? TAG_LATEST;
|
|
49
51
|
|
|
50
|
-
const defaultRegistry = manifest.publishConfig?.registry ??
|
|
52
|
+
const defaultRegistry = manifest.publishConfig?.registry ?? REGISTRY_NPM;
|
|
51
53
|
|
|
52
54
|
const defaultAccess =
|
|
53
55
|
manifest.publishConfig?.access ??
|
|
54
56
|
(manifest.scope === undefined ? ACCESS_PUBLIC : undefined);
|
|
55
57
|
|
|
58
|
+
const defaultProvenance = manifest.publishConfig?.provenance ?? false;
|
|
59
|
+
|
|
56
60
|
return {
|
|
57
61
|
token: validateToken(options.token),
|
|
58
62
|
registry: validateRegistry(options.registry ?? defaultRegistry),
|
|
59
63
|
tag: setValue(options.tag, defaultTag, validateTag),
|
|
60
64
|
access: setValue(options.access, defaultAccess, validateAccess),
|
|
61
|
-
|
|
65
|
+
provenance: setValue(options.provenance, defaultProvenance, Boolean),
|
|
66
|
+
ignoreScripts: setValue(options.ignoreScripts, true, Boolean),
|
|
67
|
+
dryRun: setValue(options.dryRun, false, Boolean),
|
|
62
68
|
strategy: setValue(options.strategy, STRATEGY_ALL, validateStrategy),
|
|
63
69
|
logger: options.logger,
|
|
64
70
|
temporaryDirectory: options.temporaryDirectory ?? os.tmpdir(),
|
|
@@ -91,11 +97,11 @@ const validateRegistry = (value: unknown): URL => {
|
|
|
91
97
|
};
|
|
92
98
|
|
|
93
99
|
const validateTag = (value: unknown): string => {
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
if (typeof value === "string" && value.length > 0) {
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
96
103
|
|
|
97
|
-
|
|
98
|
-
return value as boolean;
|
|
104
|
+
throw new errors.InvalidTagError(value);
|
|
99
105
|
};
|
|
100
106
|
|
|
101
107
|
const validateAccess = (value: unknown): Access | undefined => {
|