Skip to content

Commit

Permalink
fix(windows): allow spawning npm cli on windows
Browse files Browse the repository at this point in the history
Fixes #198
  • Loading branch information
mcous committed Jun 1, 2024
1 parent c292f92 commit cdd51f2
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 24 deletions.
116 changes: 106 additions & 10 deletions dist/main.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions dist/main.js.map

Large diffs are not rendered by default.

29 changes: 28 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"@types/command-line-args": "^5.2.1",
"@types/node": "^20.10.3",
"@types/tar": "^6.1.6",
"@types/validate-npm-package-name": "^4.0.2",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@vitest/coverage-istanbul": "^1.0.1",
Expand All @@ -81,6 +82,7 @@
"@types/semver": "^7.5.2",
"command-line-args": "5.2.1",
"semver": "7.6.0",
"tar": "6.2.1"
"tar": "6.2.1",
"validate-npm-package-name": "^5.0.1"
}
}
12 changes: 11 additions & 1 deletion src/__tests__/normalize-options.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ describe("normalizeOptions", () => {
});
});

it("should validate tag value", () => {
it("should validate tag type", () => {
expect(() => {
subject.normalizeOptions(manifest, {
token: "abc123",
Expand All @@ -144,6 +144,16 @@ describe("normalizeOptions", () => {
}).toThrow(errors.InvalidTagError);
});

it("should validate tag value", () => {
expect(() => {
subject.normalizeOptions(manifest, {
token: "abc123",
// tag must not require contain characters encoded by encodeUriComponent
tag: "fresh&clean",
});
}).toThrow(errors.InvalidTagError);
});

it("should validate access value", () => {
expect(() => {
subject.normalizeOptions(manifest, {
Expand Down
2 changes: 1 addition & 1 deletion src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class PackageJsonParseError extends SyntaxError {

export class InvalidPackageNameError extends TypeError {
public constructor(value: unknown) {
super(`Package name must be a string, got "${String(value)}"`);
super(`Package name is not valid, got "${String(value)}"`);
this.name = "InvalidPackageNameError";
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/normalize-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,13 @@ const validateRegistry = (value: unknown): URL => {
};

const validateTag = (value: unknown): string => {
if (typeof value === "string" && value.length > 0) {
return value;
if (typeof value === "string") {
const trimmedValue = value.trim();
const encodedValue = encodeURIComponent(trimmedValue);

if (trimmedValue.length > 0 && trimmedValue === encodedValue) {
return value;
}
}

throw new errors.InvalidTagError(value);
Expand Down
4 changes: 3 additions & 1 deletion src/npm/call-npm-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ export const PUBLISH = "publish";
export const E404 = "E404";
export const EPUBLISHCONFLICT = "EPUBLISHCONFLICT";

const NPM = os.platform() === "win32" ? "npm.cmd" : "npm";
const IS_WINDOWS = os.platform() === "win32";
const NPM = IS_WINDOWS ? "npm.cmd" : "npm";
const JSON_MATCH_RE = /(\{[\s\S]*\})/mu;

const baseArguments = (options: NpmCliOptions) =>
Expand Down Expand Up @@ -106,6 +107,7 @@ async function execNpm(

const npm = childProcess.spawn(NPM, commandArguments, {
env: { ...process.env, ...environment },
shell: IS_WINDOWS,
});

npm.stdout.on("data", (data: string) => (stdout += data));
Expand Down
11 changes: 8 additions & 3 deletions src/read-manifest.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import fs from "node:fs/promises";
import path from "node:path";
import validatePackageName from "validate-npm-package-name";
import semverValid from "semver/functions/valid.js";
import tarList from "tar/lib/list.js";
import type { ReadEntry } from "tar";
Expand Down Expand Up @@ -39,10 +40,14 @@ const isTarball = (file: unknown): file is string => {
return typeof file === "string" && path.extname(file) === TARBALL_EXTNAME;
};

const validateVersion = (version: unknown): string | undefined => {
const normalizeVersion = (version: unknown): string | undefined => {
return semverValid(version as string) ?? undefined;
};

const validateName = (name: unknown): name is string => {
return validatePackageName(name as string).validForNewPackages;
};

const readPackageJson = async (...pathSegments: string[]): Promise<string> => {
const file = path.resolve(...pathSegments);

Expand Down Expand Up @@ -110,13 +115,13 @@ export async function readManifest(
try {
manifestJson = JSON.parse(manifestContents) as Record<string, unknown>;
name = manifestJson["name"];
version = validateVersion(manifestJson["version"]);
version = normalizeVersion(manifestJson["version"]);
publishConfig = manifestJson["publishConfig"] ?? {};
} catch (error) {
throw new errors.PackageJsonParseError(packageSpec, error);
}

if (typeof name !== "string" || name.length === 0) {
if (!validateName(name)) {
throw new errors.InvalidPackageNameError(name);
}

Expand Down

0 comments on commit cdd51f2

Please sign in to comment.