Skip to content

Commit e6d0799

Browse files
Added a CLI and NPM module exports
1 parent 8aee3d5 commit e6d0799

9 files changed

+191
-57
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ pids
3838
# Dependencies
3939
/node_modules
4040

41+
# Build output
42+
/lib
43+
4144
# Test output
4245
/.nyc_output
4346
/coverage

bin/npm-publish.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env node
2+
"use strict";
3+
const { main } = require("../lib/cli");
4+
main(process.argv.slice(2));

package-lock.json

Lines changed: 9 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,25 @@
1919
"type": "git",
2020
"url": "https://github.com/JS-DevTools/npm-publish.git"
2121
},
22-
"main": "dist/index.js",
23-
"types": "dist/index.d.ts",
22+
"main": "lib/index.js",
23+
"types": "lib/index.d.ts",
2424
"bin": {
25-
"npm-publish": "dist/index.js"
25+
"npm-publish": "bin/npm-publish.js"
2626
},
2727
"files": [
28-
"dist"
28+
"bin",
29+
"lib"
2930
],
3031
"scripts": {
31-
"clean": "shx rm -rf .nyc_output coverage dist",
32+
"clean": "shx rm -rf .nyc_output coverage lib dist",
3233
"lint": "npm run lint:typescript && npm run lint:javascript",
3334
"lint:typescript": "tslint -p tsconfig.json",
3435
"lint:javascript": "eslint test",
35-
"build": "npm run build:ncc && npm run build:node_modules",
36-
"build:ncc": "ncc build src/index.ts --source-map --external semver",
36+
"build": "npm run build:typescript && npm run build:ncc && npm run build:node_modules",
37+
"build:typescript": "tsc --declaration",
38+
"build:ncc": "ncc build src/action/index.ts --source-map --external semver",
3739
"build:node_modules": "shx mkdir -p dist/node_modules && shx cp -r node_modules/semver dist/node_modules",
38-
"watch": "npm run build:ncc -- --watch",
40+
"watch": "tsc --watch",
3941
"test": "mocha && npm run lint",
4042
"coverage": "nyc -x dist/sourcemap-register.js node_modules/mocha/bin/mocha",
4143
"upgrade": "npm-check -u && npm audit fix",
@@ -48,6 +50,7 @@
4850
"devDependencies": {
4951
"@actions/core": "^1.2.1",
5052
"@types/chai": "^4.2.7",
53+
"@types/command-line-args": "^5.0.0",
5154
"@types/mocha": "^5.2.7",
5255
"@types/node": "^13.1.8",
5356
"@types/semver": "^6.2.0",
@@ -69,5 +72,8 @@
6972
"typescript": "^3.5.1",
7073
"typescript-tslint-plugin": "^0.5.0",
7174
"version-bump-prompt": "^5.0.3"
75+
},
76+
"dependencies": {
77+
"command-line-args": "^5.1.1"
7278
}
7379
}

src/cli/exit-code.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* CLI exit codes.
3+
*
4+
* @see https://nodejs.org/api/process.html#process_exit_codes
5+
* @internal
6+
*/
7+
export enum ExitCode {
8+
Success = 0,
9+
FatalError = 1,
10+
InvalidArgument = 9
11+
}

src/cli/help.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Text explaining how to use the CLI
3+
* @internal
4+
*/
5+
export const usageText = `
6+
Usage: npm-publish [options] [package_path]
7+
8+
options:
9+
--token <token> The NPM access token to use when publishing
10+
11+
--registry <url> The NPM registry URL to use
12+
13+
--debug, -d Enable debug mode, with increased logging
14+
15+
--quiet, -q Suppress unnecessary output
16+
17+
--version, -v Print the version number
18+
19+
--help, -h Show help
20+
21+
package_path The absolute or relative path of the NPM package to publish.
22+
Can be a directory path, or the path of a package.json file.
23+
Defaults to the current directory.
24+
`;

src/cli/index.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// tslint:disable: no-console
2+
import { join } from "path";
3+
import { npmPublish } from "../npm-publish";
4+
import { readManifest } from "../read-manifest";
5+
import { ExitCode } from "./exit-code";
6+
import { usageText } from "./help";
7+
import { parseArgs } from "./parse-args";
8+
9+
/**
10+
* The main entry point of the CLI
11+
*
12+
* @param args - The command-line arguments
13+
*/
14+
export async function main(args: string[]): Promise<void> {
15+
try {
16+
// Setup global error handlers
17+
process.on("uncaughtException", errorHandler);
18+
process.on("unhandledRejection", errorHandler);
19+
20+
// Parse the command-line arguments
21+
let { help, version, options } = parseArgs(args);
22+
23+
if (help) {
24+
// Show the help text and exit
25+
console.log(usageText);
26+
process.exit(ExitCode.Success);
27+
}
28+
else if (version) {
29+
// Show the version number and exit
30+
let manifest = await readManifest(join(__dirname, "../../package.json"));
31+
console.log(manifest.version);
32+
process.exit(ExitCode.Success);
33+
}
34+
else {
35+
await npmPublish(options);
36+
}
37+
}
38+
catch (error) {
39+
errorHandler(error as Error);
40+
}
41+
}
42+
43+
/**
44+
* Prints errors to the console
45+
*/
46+
function errorHandler(error: Error): void {
47+
let message = error.message || String(error);
48+
49+
if (process.env.DEBUG || process.env.NODE_ENV === "development") {
50+
message = error.stack || message;
51+
}
52+
53+
console.error(message);
54+
process.exit(ExitCode.FatalError);
55+
}

src/cli/parse-args.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// tslint:disable: no-console
2+
import * as commandLineArgs from "command-line-args";
3+
import { Options } from "../options";
4+
import { ExitCode } from "./exit-code";
5+
import { usageText } from "./help";
6+
7+
/**
8+
* The parsed command-line arguments
9+
* @internal
10+
*/
11+
export interface ParsedArgs {
12+
help?: boolean;
13+
version?: boolean;
14+
options: Options;
15+
}
16+
17+
/**
18+
* Parses the command-line arguments
19+
* @internal
20+
*/
21+
export function parseArgs(argv: string[]): ParsedArgs {
22+
try {
23+
let args = commandLineArgs(
24+
[
25+
{ name: "token", type: String },
26+
{ name: "registry", type: String },
27+
{ name: "package", type: String, defaultOption: true },
28+
{ name: "debug", alias: "d", type: Boolean },
29+
{ name: "quiet", alias: "q", type: Boolean },
30+
{ name: "version", alias: "v", type: Boolean },
31+
{ name: "help", alias: "h", type: Boolean },
32+
],
33+
{ argv }
34+
);
35+
36+
let parsedArgs: ParsedArgs = {
37+
help: args.help as boolean,
38+
version: args.version as boolean,
39+
options: {
40+
token: args.token as string,
41+
registry: args.registry as string,
42+
package: args.package as string,
43+
debug: args.debug ? console.debug : undefined,
44+
quiet: args.quiet as boolean,
45+
}
46+
};
47+
48+
return parsedArgs;
49+
}
50+
catch (error) {
51+
// There was an error parsing the command-line args
52+
return errorHandler(error as Error);
53+
}
54+
}
55+
56+
function errorHandler(error: Error): never {
57+
console.error(error.message);
58+
console.error(usageText);
59+
return process.exit(ExitCode.InvalidArgument);
60+
}

src/index.ts

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,15 @@
1-
import { getInput, setFailed, setOutput } from "@actions/core";
2-
import { Options } from "./options";
3-
import { publishToNPM } from "./publish-to-npm";
1+
// tslint:disable: no-default-export
2+
import { npmPublish } from "./npm-publish";
43

5-
/**
6-
* The main entry point of the GitHub Action
7-
*/
8-
async function main(): Promise<void> {
9-
try {
10-
// Setup global error handlers
11-
process.on("uncaughtException", errorHandler);
12-
process.on("unhandledRejection", errorHandler);
4+
// Exprot the external type definitions as named exports
5+
export * from "./options";
6+
export * from "./results";
137

14-
// Get the GitHub Actions input options
15-
const options: Options = {
16-
token: getInput("token", { required: true }),
17-
registry: getInput("registry", { required: true }),
18-
package: getInput("package", { required: true }),
19-
checkVersion: getInput("check-version", { required: true }).toLowerCase() === "true",
20-
};
8+
// Export `npmPublish` as a named export and the default export
9+
export { npmPublish };
10+
export default npmPublish;
2111

22-
// Puglish to NPM
23-
let results = await publishToNPM(options);
24-
25-
// Set the GitHub Actions output variables
26-
setOutput("type", results.type);
27-
setOutput("version", results.version);
28-
setOutput("old-version", results.oldVersion);
29-
}
30-
catch (error) {
31-
errorHandler(error as Error);
32-
}
33-
}
34-
35-
/**
36-
* Prints errors to the console
37-
*/
38-
function errorHandler(error: Error): void {
39-
let message = error.stack || error.message || String(error);
40-
setFailed(message);
41-
process.exit();
12+
// CommonJS default export hack
13+
if (typeof module === "object" && typeof module.exports === "object") {
14+
module.exports = Object.assign(module.exports.default, module.exports); // tslint:disable-line: no-unsafe-any
4215
}
43-
44-
// tslint:disable-next-line: no-floating-promises
45-
main();

0 commit comments

Comments
 (0)