@doki-land/nifty 0.1.1 → 0.1.3
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/cli/nifty.mjs +2 -2
- package/package.json +8 -7
- package/src/cli/authArgs.ts +29 -29
- package/src/cli/bump-cmd.ts +15 -15
- package/src/cli/bump.ts +183 -94
- package/src/cli/change-logs-cmd.ts +26 -26
- package/src/cli/cli.ts +3 -3
- package/src/cli/commit-cmd.ts +77 -77
- package/src/cli/commit-lint-report.ts +44 -44
- package/src/cli/context.ts +9 -9
- package/src/cli/format-cmd.ts +6 -6
- package/src/cli/format.ts +15 -15
- package/src/cli/install-native-cmd.ts +4 -4
- package/src/cli/install-native.ts +24 -24
- package/src/cli/lint-cmd.ts +11 -11
- package/src/cli/lint.ts +49 -49
- package/src/cli/options.ts +16 -16
- package/src/cli/publish-cmd.ts +16 -16
- package/src/cli/publish.ts +38 -38
- package/src/cli/resolveNpm.ts +3 -3
- package/src/cli/retime-cmd.ts +18 -18
- package/src/cli/trust-cmd.ts +11 -11
- package/src/cli/trust.ts +26 -26
- package/src/cli/update-cmd.ts +5 -5
- package/src/cli/update.ts +12 -12
- package/src/cli/upload-cmd.ts +17 -17
- package/src/cli/upload.ts +132 -132
- package/src/cli/workspace.ts +49 -49
- package/src/config/authorMap.ts +4 -4
- package/src/config/defineConfig.ts +10 -8
- package/src/config/detectProject.ts +46 -46
- package/src/config/formatPresets.ts +26 -26
- package/src/config/loadConfig.ts +35 -35
- package/src/config/trustPayload.ts +7 -7
- package/src/config/types.ts +38 -38
- package/src/git.ts +14 -14
- package/src/github.ts +54 -54
- package/src/gitmoji.ts +18 -18
- package/src/native.ts +600 -600
- package/src/nifty.ts +30 -30
- package/src/types.ts +17 -17
package/src/cli/format.ts
CHANGED
|
@@ -2,38 +2,38 @@ import { loadConfig, resolveFormatConfig } from "../config/index.js";
|
|
|
2
2
|
import { loadNiftyNative } from "../native.js";
|
|
3
3
|
|
|
4
4
|
export type FormatOptions = {
|
|
5
|
-
check
|
|
6
|
-
cwd
|
|
5
|
+
check?: boolean;
|
|
6
|
+
cwd?: string;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
export async function formatWorkspace(options
|
|
9
|
+
export async function formatWorkspace(options: FormatOptions): Promise<number> {
|
|
10
10
|
const cwd = options.cwd ?? process.cwd();
|
|
11
|
-
const { config } = await loadConfig({ cwd, createIfMissing
|
|
11
|
+
const { config } = await loadConfig({ cwd, createIfMissing: false, env: { command: "format" } });
|
|
12
12
|
const resolved = resolveFormatConfig(config.format);
|
|
13
13
|
const native = loadNiftyNative();
|
|
14
14
|
const report = native.formatter.run({
|
|
15
15
|
cwd,
|
|
16
|
-
check
|
|
17
|
-
includes
|
|
18
|
-
excludes
|
|
19
|
-
rust
|
|
20
|
-
javascript
|
|
21
|
-
style
|
|
16
|
+
check: options.check,
|
|
17
|
+
includes: resolved.includes,
|
|
18
|
+
excludes: resolved.excludes,
|
|
19
|
+
rust: resolved.rust,
|
|
20
|
+
javascript: resolved.javascript,
|
|
21
|
+
style: resolved.style,
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
if(report.errors.length>0){
|
|
25
|
-
for(const message of report.errors){
|
|
24
|
+
if (report.errors.length > 0) {
|
|
25
|
+
for (const message of report.errors) {
|
|
26
26
|
console.error(`error: ${message}`);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
if(report.formatted === 0 && report.unchanged>0 && report.errors.length === 0){
|
|
30
|
+
if (report.formatted === 0 && report.unchanged > 0 && report.errors.length === 0) {
|
|
31
31
|
console.log(`format: no changes needed (preset ${resolved.preset})`);
|
|
32
|
-
} else if(report.errors.length === 0){
|
|
32
|
+
} else if (report.errors.length === 0) {
|
|
33
33
|
console.log(
|
|
34
34
|
`format: ${report.formatted} file(s) updated, ${report.unchanged} unchanged (preset ${resolved.preset})`,
|
|
35
35
|
);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
return report.errors.length>0 ? 1 : 0;
|
|
38
|
+
return report.errors.length > 0 ? 1 : 0;
|
|
39
39
|
}
|
|
@@ -3,20 +3,20 @@ import type { Cli, ParsedOptions } from "@vmz/commander";
|
|
|
3
3
|
import { installNativeFromOptions } from "./install-native.js";
|
|
4
4
|
import { cwdFrom, str } from "./options.js";
|
|
5
5
|
|
|
6
|
-
export function registerInstallNativeCommand(cli
|
|
6
|
+
export function registerInstallNativeCommand(cli: Cli): void {
|
|
7
7
|
cli.command("install-native", "cli.cmd.install-native")
|
|
8
8
|
.option("--from <dir>", "cli.opt.from-artifacts")
|
|
9
|
-
.action(async(options) =>cmdInstallNative(options));
|
|
9
|
+
.action(async (options) => cmdInstallNative(options));
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export async function cmdInstallNative(options
|
|
12
|
+
export async function cmdInstallNative(options: ParsedOptions): Promise<number> {
|
|
13
13
|
const from =
|
|
14
14
|
str(options, "from") ??
|
|
15
15
|
process.env.NATIVE_ARTIFACT_ROOT ??
|
|
16
16
|
"native-artifacts";
|
|
17
17
|
installNativeFromOptions({
|
|
18
18
|
from,
|
|
19
|
-
cwd
|
|
19
|
+
cwd: cwdFrom(options),
|
|
20
20
|
});
|
|
21
21
|
return 0;
|
|
22
22
|
}
|
|
@@ -4,12 +4,12 @@ import { basename, dirname, join, relative, resolve } from "node:path";
|
|
|
4
4
|
import { detectProjectLayout } from "../config/detectProject.js";
|
|
5
5
|
|
|
6
6
|
/** Basename of a built .node file → platform package directory under projects/packages/. */
|
|
7
|
-
const PACKAGE_BY_ASSET
|
|
8
|
-
"nifty-win32-x64-msvc.node"
|
|
9
|
-
"nifty-linux-x64-gnu.node"
|
|
10
|
-
"nifty-linux-arm64-gnu.node"
|
|
11
|
-
"nifty-darwin-x64.node"
|
|
12
|
-
"nifty-darwin-arm64.node"
|
|
7
|
+
const PACKAGE_BY_ASSET: Record<string, string> = {
|
|
8
|
+
"nifty-win32-x64-msvc.node": "nifty-win32-x64",
|
|
9
|
+
"nifty-linux-x64-gnu.node": "nifty-linux-x64",
|
|
10
|
+
"nifty-linux-arm64-gnu.node": "nifty-linux-arm64",
|
|
11
|
+
"nifty-darwin-x64.node": "nifty-darwin-x64",
|
|
12
|
+
"nifty-darwin-arm64.node": "nifty-darwin-arm64",
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
/** Matrix platforms that must be present after install (matches publish-npm.yml). */
|
|
@@ -17,61 +17,61 @@ const REQUIRED_PACKAGES = ["nifty-win32-x64", "nifty-linux-x64", "nifty-darwin-a
|
|
|
17
17
|
|
|
18
18
|
export type InstallNativeOptions = {
|
|
19
19
|
/** Downloaded CI artifact tree (walked recursively for .node files). */
|
|
20
|
-
from
|
|
21
|
-
cwd
|
|
20
|
+
from: string;
|
|
21
|
+
cwd?: string;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
function walkNodes(dir
|
|
25
|
-
const out
|
|
26
|
-
if(!existsSync(dir)){
|
|
24
|
+
function walkNodes(dir: string): string[] {
|
|
25
|
+
const out: string[] = [];
|
|
26
|
+
if (!existsSync(dir)) {
|
|
27
27
|
return out;
|
|
28
28
|
}
|
|
29
|
-
for(const entry of readdirSync(dir, { withFileTypes
|
|
29
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
30
30
|
const full = join(dir, entry.name);
|
|
31
|
-
if(entry.isDirectory()){
|
|
31
|
+
if (entry.isDirectory()) {
|
|
32
32
|
out.push(...walkNodes(full));
|
|
33
|
-
} else if(entry.isFile() && entry.name.endsWith(".node")){
|
|
33
|
+
} else if (entry.isFile() && entry.name.endsWith(".node")) {
|
|
34
34
|
out.push(full);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
return out;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
function libHasNode(libDir
|
|
41
|
-
return existsSync(libDir) && readdirSync(libDir).some((name) =>name.endsWith(".node"));
|
|
40
|
+
function libHasNode(libDir: string): boolean {
|
|
41
|
+
return existsSync(libDir) && readdirSync(libDir).some((name) => name.endsWith(".node"));
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/** Copy matrix .node artifacts into platform package lib dirs for npm publish. */
|
|
45
|
-
export function installNativeFromOptions(options
|
|
45
|
+
export function installNativeFromOptions(options: InstallNativeOptions): void {
|
|
46
46
|
const layout = detectProjectLayout(options.cwd ?? process.cwd());
|
|
47
47
|
const artifactRoot = resolve(layout.root, options.from);
|
|
48
48
|
const nodes = walkNodes(artifactRoot);
|
|
49
|
-
if(nodes.length === 0){
|
|
49
|
+
if (nodes.length === 0) {
|
|
50
50
|
throw new Error(`install-native: no .node files under ${artifactRoot}`);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
let installed = 0;
|
|
54
|
-
for(const file of nodes){
|
|
54
|
+
for (const file of nodes) {
|
|
55
55
|
const base = basename(file);
|
|
56
56
|
const packageDir = PACKAGE_BY_ASSET[base];
|
|
57
|
-
if(!packageDir){
|
|
57
|
+
if (!packageDir) {
|
|
58
58
|
console.log(`skip unmapped artifact ${relative(artifactRoot, file)}`);
|
|
59
59
|
continue;
|
|
60
60
|
}
|
|
61
61
|
const dest = join(layout.root, "projects/packages", packageDir, "lib", base);
|
|
62
|
-
mkdirSync(dirname(dest), { recursive
|
|
62
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
63
63
|
copyFileSync(file, dest);
|
|
64
64
|
console.log(`installed ${relative(layout.root, dest)}`);
|
|
65
65
|
installed += 1;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
if(installed === 0){
|
|
68
|
+
if (installed === 0) {
|
|
69
69
|
throw new Error("install-native: no mapped platform .node files installed");
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
for(const packageDir of REQUIRED_PACKAGES){
|
|
72
|
+
for (const packageDir of REQUIRED_PACKAGES) {
|
|
73
73
|
const libDir = join(layout.root, "projects/packages", packageDir, "lib");
|
|
74
|
-
if(!libHasNode(libDir)){
|
|
74
|
+
if (!libHasNode(libDir)) {
|
|
75
75
|
throw new Error(`install-native: missing .node under ${packageDir}/lib`);
|
|
76
76
|
}
|
|
77
77
|
}
|
package/src/cli/lint-cmd.ts
CHANGED
|
@@ -4,31 +4,31 @@ import { bootstrapFromOptions } from "./context.js";
|
|
|
4
4
|
import { lintCommits, type LintOptions } from "./lint.js";
|
|
5
5
|
import { cwdFrom, flag, str, strList } from "./options.js";
|
|
6
6
|
|
|
7
|
-
export function registerLintCommands(cli
|
|
7
|
+
export function registerLintCommands(cli: Cli): void {
|
|
8
8
|
registerLintLike(cli, "lint", "cli.cmd.lint", false);
|
|
9
9
|
registerLintLike(cli, "check", "cli.cmd.check", true);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
function registerLintLike(cli
|
|
12
|
+
function registerLintLike(cli: Cli, name: string, helpId: string, check: boolean): void {
|
|
13
13
|
cli.command(name, helpId)
|
|
14
14
|
.option("--from <ref>", "cli.opt.from")
|
|
15
15
|
.option("--to <ref>", "cli.opt.to")
|
|
16
16
|
.option("-s, --subject <text>...", "cli.opt.subject")
|
|
17
17
|
.option("--no-cargo", "cli.opt.no-cargo")
|
|
18
|
-
.action(async(options) =>cmdLint(options, check));
|
|
18
|
+
.action(async (options) => cmdLint(options, check));
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export async function cmdLint(options
|
|
21
|
+
export async function cmdLint(options: ParsedOptions, check: boolean): Promise<number> {
|
|
22
22
|
await bootstrapFromOptions(options);
|
|
23
|
-
const lintOptions
|
|
24
|
-
subjects
|
|
25
|
-
from
|
|
26
|
-
to
|
|
27
|
-
cwd
|
|
28
|
-
scanCargo
|
|
23
|
+
const lintOptions: LintOptions = {
|
|
24
|
+
subjects: strList(options, "subject"),
|
|
25
|
+
from: str(options, "from"),
|
|
26
|
+
to: str(options, "to"),
|
|
27
|
+
cwd: cwdFrom(options),
|
|
28
|
+
scanCargo: flag(options, "no-cargo") ? false : undefined,
|
|
29
29
|
};
|
|
30
30
|
const errorCount = await lintCommits(lintOptions, check);
|
|
31
|
-
if(check && errorCount>0){
|
|
31
|
+
if (check && errorCount > 0) {
|
|
32
32
|
throw new Error(`found ${errorCount} lint error(s)`);
|
|
33
33
|
}
|
|
34
34
|
return 0;
|
package/src/cli/lint.ts
CHANGED
|
@@ -3,70 +3,70 @@ import { loadNiftyNative } from "../native.js";
|
|
|
3
3
|
import { printCommitLintReport, type CommitLintDiagnostic } from "./commit-lint-report.js";
|
|
4
4
|
|
|
5
5
|
export type LintOptions = {
|
|
6
|
-
subjects
|
|
7
|
-
from
|
|
8
|
-
to
|
|
9
|
-
cwd
|
|
10
|
-
scanCargo
|
|
11
|
-
commitOnly
|
|
12
|
-
json
|
|
13
|
-
errorsOnly
|
|
14
|
-
reportTitle
|
|
6
|
+
subjects: string[];
|
|
7
|
+
from?: string;
|
|
8
|
+
to?: string;
|
|
9
|
+
cwd?: string;
|
|
10
|
+
scanCargo?: boolean;
|
|
11
|
+
commitOnly?: boolean;
|
|
12
|
+
json?: boolean;
|
|
13
|
+
errorsOnly?: boolean;
|
|
14
|
+
reportTitle?: string;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
type LintDiagnostic = CommitLintDiagnostic;
|
|
18
18
|
|
|
19
19
|
type LintRuleConfig = {
|
|
20
|
-
id
|
|
21
|
-
enabled
|
|
22
|
-
severity
|
|
20
|
+
id: string;
|
|
21
|
+
enabled?: boolean;
|
|
22
|
+
severity?: "error" | "warning" | "info";
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
export async function runLint(argv
|
|
25
|
+
export async function runLint(argv: string[], check: boolean): Promise<void> {
|
|
26
26
|
const options = parseLintArgs(argv);
|
|
27
27
|
const errorCount = await lintCommits(options, check);
|
|
28
|
-
if(check && errorCount>0){
|
|
28
|
+
if (check && errorCount > 0) {
|
|
29
29
|
throw new Error(`found ${errorCount} lint error(s)`);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export async function lintCommits(
|
|
34
|
-
options
|
|
35
|
-
check
|
|
34
|
+
options: LintOptions,
|
|
35
|
+
check: boolean,
|
|
36
36
|
commitOnly = options.commitOnly ?? false,
|
|
37
|
-
)
|
|
37
|
+
): Promise<number> {
|
|
38
38
|
const native = loadNiftyNative();
|
|
39
39
|
const cwd = options.cwd ?? process.cwd();
|
|
40
|
-
const { config } = await loadConfig({ cwd, createIfMissing
|
|
41
|
-
const rules
|
|
42
|
-
id
|
|
43
|
-
enabled
|
|
44
|
-
severity
|
|
40
|
+
const { config } = await loadConfig({ cwd, createIfMissing: false });
|
|
41
|
+
const rules: LintRuleConfig[] | undefined = config.lint?.rules?.map((rule) => ({
|
|
42
|
+
id: rule.id,
|
|
43
|
+
enabled: rule.enabled,
|
|
44
|
+
severity: rule.severity,
|
|
45
45
|
}));
|
|
46
46
|
|
|
47
47
|
const runner = check ? native.lint.check : native.lint.run;
|
|
48
48
|
const report = runner({
|
|
49
49
|
cwd,
|
|
50
|
-
fromRef
|
|
51
|
-
toRef
|
|
52
|
-
subjects
|
|
50
|
+
fromRef: options.from,
|
|
51
|
+
toRef: options.to,
|
|
52
|
+
subjects: options.subjects.length > 0 ? options.subjects : undefined,
|
|
53
53
|
rules,
|
|
54
|
-
scanCargo
|
|
55
|
-
commitOnly
|
|
54
|
+
scanCargo: options.scanCargo,
|
|
55
|
+
commitOnly: commitOnly || options.commitOnly,
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
-
if(commitOnly || options.commitOnly){
|
|
58
|
+
if (commitOnly || options.commitOnly) {
|
|
59
59
|
printCommitLintReport(report.diagnostics, report.errorCount, report.warningCount, {
|
|
60
|
-
json
|
|
61
|
-
errorsOnly
|
|
62
|
-
title
|
|
60
|
+
json: options.json,
|
|
61
|
+
errorsOnly: options.errorsOnly,
|
|
62
|
+
title: options.reportTitle ?? "commit lint",
|
|
63
63
|
});
|
|
64
64
|
} else {
|
|
65
|
-
for(const item of report.diagnostics){
|
|
65
|
+
for (const item of report.diagnostics) {
|
|
66
66
|
printWorkspaceDiagnostic(item);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
if(report.diagnostics.length>0){
|
|
69
|
+
if (report.diagnostics.length > 0) {
|
|
70
70
|
console.log(`lint: ${report.errorCount} error(s), ${report.warningCount} warning(s)`);
|
|
71
71
|
} else {
|
|
72
72
|
console.log("lint: no issues found");
|
|
@@ -76,16 +76,16 @@ export async function lintCommits(
|
|
|
76
76
|
return report.errorCount;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
function printWorkspaceDiagnostic(item
|
|
79
|
+
function printWorkspaceDiagnostic(item: LintDiagnostic): void {
|
|
80
80
|
const prefix = item.severity === "error" ? "error" : item.severity === "warning" ? "warning" : "info";
|
|
81
|
-
if(item.subject){
|
|
81
|
+
if (item.subject) {
|
|
82
82
|
const hash = item.hash ? `${item.hash.slice(0, 8)} ` : "";
|
|
83
83
|
console.log(`${prefix} [${item.rule}] ${hash}${item.message} (${item.subject})`);
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
86
|
const location =
|
|
87
|
-
item.path!== undefined
|
|
88
|
-
? item.line!== undefined
|
|
87
|
+
item.path !== undefined
|
|
88
|
+
? item.line !== undefined
|
|
89
89
|
? `${item.path}:${item.line}`
|
|
90
90
|
: item.path
|
|
91
91
|
: undefined;
|
|
@@ -93,19 +93,19 @@ function printWorkspaceDiagnostic(item : LintDiagnostic) : void {
|
|
|
93
93
|
console.log(`${prefix} [${item.rule}] ${item.message}${suffix}`);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
function parseLintArgs(argv
|
|
97
|
-
const options
|
|
98
|
-
for(let i = 0; i<argv.length; i += 1){
|
|
96
|
+
function parseLintArgs(argv: string[]): LintOptions {
|
|
97
|
+
const options: LintOptions = { subjects: [] };
|
|
98
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
99
99
|
const arg = argv[i];
|
|
100
|
-
if(arg === "--from"){
|
|
101
|
-
options.from = argv[
|
|
102
|
-
} else if(arg === "--to"){
|
|
103
|
-
options.to = argv[
|
|
104
|
-
} else if(arg === "-C" || arg === "--cwd"){
|
|
105
|
-
options.cwd = argv[
|
|
106
|
-
} else if(arg === "-s" || arg === "--subject"){
|
|
107
|
-
options.subjects.push(argv[
|
|
108
|
-
} else if(arg === "--no-cargo"){
|
|
100
|
+
if (arg === "--from") {
|
|
101
|
+
options.from = argv[++i];
|
|
102
|
+
} else if (arg === "--to") {
|
|
103
|
+
options.to = argv[++i];
|
|
104
|
+
} else if (arg === "-C" || arg === "--cwd") {
|
|
105
|
+
options.cwd = argv[++i];
|
|
106
|
+
} else if (arg === "-s" || arg === "--subject") {
|
|
107
|
+
options.subjects.push(argv[++i]);
|
|
108
|
+
} else if (arg === "--no-cargo") {
|
|
109
109
|
options.scanCargo = false;
|
|
110
110
|
}
|
|
111
111
|
}
|
package/src/cli/options.ts
CHANGED
|
@@ -5,36 +5,36 @@ import type { ParsedOptions } from "@vmz/commander";
|
|
|
5
5
|
import { resolveNpmExecutable } from "./resolveNpm.js";
|
|
6
6
|
import type { AuthCliOptions } from "./authArgs.js";
|
|
7
7
|
|
|
8
|
-
export function cwdFrom(options
|
|
8
|
+
export function cwdFrom(options: ParsedOptions): string | undefined {
|
|
9
9
|
const value = options.cwd;
|
|
10
|
-
return typeof value === "string" && value.length>0 ? resolve(value) : undefined;
|
|
10
|
+
return typeof value === "string" && value.length > 0 ? resolve(value) : undefined;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function flag(options
|
|
13
|
+
export function flag(options: ParsedOptions, key: string): boolean {
|
|
14
14
|
return options[key] === true;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export function str(options
|
|
17
|
+
export function str(options: ParsedOptions, key: string): string | undefined {
|
|
18
18
|
const value = options[key];
|
|
19
|
-
return typeof value === "string" && value.length>0 ? value : undefined;
|
|
19
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export function strList(options
|
|
22
|
+
export function strList(options: ParsedOptions, key: string): string[] {
|
|
23
23
|
const value = options[key];
|
|
24
|
-
if(Array.isArray(value)){
|
|
25
|
-
return value.filter((entry)
|
|
24
|
+
if (Array.isArray(value)) {
|
|
25
|
+
return value.filter((entry): entry is string => typeof entry === "string" && entry.length > 0);
|
|
26
26
|
}
|
|
27
|
-
if(typeof value === "string" && value.length>0){
|
|
28
|
-
return[value];
|
|
27
|
+
if (typeof value === "string" && value.length > 0) {
|
|
28
|
+
return [value];
|
|
29
29
|
}
|
|
30
|
-
return[];
|
|
30
|
+
return [];
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export function authFromOptions(options
|
|
33
|
+
export function authFromOptions(options: ParsedOptions): AuthCliOptions {
|
|
34
34
|
return {
|
|
35
|
-
otp
|
|
36
|
-
totpSecret
|
|
37
|
-
token
|
|
38
|
-
npm
|
|
35
|
+
otp: str(options, "otp"),
|
|
36
|
+
totpSecret: str(options, "totp-secret"),
|
|
37
|
+
token: str(options, "npm-token") ?? str(options, "token"),
|
|
38
|
+
npm: resolveNpmExecutable(),
|
|
39
39
|
};
|
|
40
40
|
}
|
package/src/cli/publish-cmd.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { bootstrapFromOptions } from "./context.js";
|
|
|
8
8
|
import { printPublishReport } from "./publish.js";
|
|
9
9
|
import { authFromOptions, cwdFrom, flag, str, strList } from "./options.js";
|
|
10
10
|
|
|
11
|
-
export function registerPublishCommand(cli
|
|
11
|
+
export function registerPublishCommand(cli: Cli): void {
|
|
12
12
|
cli.command("publish", "cli.cmd.publish")
|
|
13
13
|
.option("--dry-run", "cli.opt.dry-run")
|
|
14
14
|
.option("--refresh", "cli.opt.refresh")
|
|
@@ -19,29 +19,29 @@ export function registerPublishCommand(cli : Cli) : void {
|
|
|
19
19
|
.option("--otp <code>", "cli.opt.otp")
|
|
20
20
|
.option("--totp-secret <secret>", "cli.opt.totp-secret")
|
|
21
21
|
.option("--npm-token <token>", "cli.opt.npm-token")
|
|
22
|
-
.action(async(options) =>cmdPublish(options));
|
|
22
|
+
.action(async (options) => cmdPublish(options));
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export async function cmdPublish(options
|
|
25
|
+
export async function cmdPublish(options: ParsedOptions): Promise<number> {
|
|
26
26
|
await bootstrapFromOptions(options);
|
|
27
|
-
const { config } = await loadConfig({ cwd
|
|
27
|
+
const { config } = await loadConfig({ cwd: cwdFrom(options), createIfMissing: false });
|
|
28
28
|
const packages = strList(options, "package");
|
|
29
|
-
const fromConfig = config.publish
|
|
29
|
+
const fromConfig = config.publish?.packages ?? [];
|
|
30
30
|
const native = loadNiftyNative();
|
|
31
31
|
const report = native.publisher["publish-workspace"]({
|
|
32
|
-
cwd
|
|
33
|
-
dryRun
|
|
34
|
-
refresh
|
|
35
|
-
placeholder
|
|
36
|
-
tag
|
|
37
|
-
access
|
|
32
|
+
cwd: cwdFrom(options),
|
|
33
|
+
dryRun: flag(options, "dry-run"),
|
|
34
|
+
refresh: flag(options, "refresh"),
|
|
35
|
+
placeholder: flag(options, "placeholder"),
|
|
36
|
+
tag: str(options, "tag"),
|
|
37
|
+
access: str(options, "access") ?? "public",
|
|
38
38
|
...(packages.length === 1
|
|
39
|
-
? { only
|
|
40
|
-
: packages.length>1
|
|
39
|
+
? { only: packages[0] }
|
|
40
|
+
: packages.length > 1
|
|
41
41
|
? { packages }
|
|
42
|
-
: fromConfig.length>0
|
|
43
|
-
? { packages
|
|
44
|
-
: {
|
|
42
|
+
: fromConfig.length > 0
|
|
43
|
+
? { packages: fromConfig }
|
|
44
|
+
: {}),
|
|
45
45
|
...trustPayloadFromConfig(config),
|
|
46
46
|
...authPayload(authFromOptions(options)),
|
|
47
47
|
});
|
package/src/cli/publish.ts
CHANGED
|
@@ -2,64 +2,64 @@ import { loadNiftyNative } from "../native.js";
|
|
|
2
2
|
import { authPayload, parseAuthArgs } from "./authArgs.js";
|
|
3
3
|
|
|
4
4
|
export type PublishOptions = {
|
|
5
|
-
cwd
|
|
6
|
-
dryRun
|
|
7
|
-
refresh
|
|
8
|
-
placeholder
|
|
9
|
-
tag
|
|
10
|
-
access
|
|
5
|
+
cwd?: string;
|
|
6
|
+
dryRun?: boolean;
|
|
7
|
+
refresh?: boolean;
|
|
8
|
+
placeholder?: boolean;
|
|
9
|
+
tag?: string;
|
|
10
|
+
access?: string;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
export type PublishReport = {
|
|
14
|
-
root
|
|
15
|
-
order
|
|
16
|
-
published
|
|
17
|
-
skipped
|
|
18
|
-
skippedVersions
|
|
14
|
+
root: string;
|
|
15
|
+
order: string[];
|
|
16
|
+
published: string[];
|
|
17
|
+
skipped: string[];
|
|
18
|
+
skippedVersions: string[];
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
export async function runPublish(argv
|
|
21
|
+
export async function runPublish(argv: string[]): Promise<void> {
|
|
22
22
|
const options = parsePublishArgs(argv);
|
|
23
23
|
const native = loadNiftyNative();
|
|
24
24
|
const report = native.publisher["publish-workspace"]({
|
|
25
|
-
cwd
|
|
26
|
-
dryRun
|
|
27
|
-
refresh
|
|
28
|
-
placeholder
|
|
29
|
-
tag
|
|
30
|
-
access
|
|
25
|
+
cwd: options.cwd,
|
|
26
|
+
dryRun: options.dryRun,
|
|
27
|
+
refresh: options.refresh,
|
|
28
|
+
placeholder: options.placeholder,
|
|
29
|
+
tag: options.tag,
|
|
30
|
+
access: options.access,
|
|
31
31
|
...authPayload(options.auth),
|
|
32
32
|
});
|
|
33
33
|
printPublishReport(report, options.dryRun);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
function parsePublishArgs(argv
|
|
37
|
-
let cwd
|
|
36
|
+
function parsePublishArgs(argv: string[]) {
|
|
37
|
+
let cwd: string | undefined;
|
|
38
38
|
let dryRun = false;
|
|
39
39
|
let refresh = false;
|
|
40
40
|
let placeholder = false;
|
|
41
|
-
let tag
|
|
41
|
+
let tag: string | undefined;
|
|
42
42
|
let access = "public";
|
|
43
43
|
const auth = parseAuthArgs(argv);
|
|
44
44
|
|
|
45
|
-
for(let i = 0; i<argv.length; i += 1){
|
|
45
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
46
46
|
const arg = argv[i];
|
|
47
|
-
if(arg === "--dry-run"){
|
|
47
|
+
if (arg === "--dry-run") {
|
|
48
48
|
dryRun = true;
|
|
49
|
-
} else if(arg === "--refresh"){
|
|
49
|
+
} else if (arg === "--refresh") {
|
|
50
50
|
refresh = true;
|
|
51
|
-
} else if(arg === "--placeholder"){
|
|
51
|
+
} else if (arg === "--placeholder") {
|
|
52
52
|
placeholder = true;
|
|
53
|
-
} else if(arg === "-C" || arg === "--cwd"){
|
|
54
|
-
cwd = argv[
|
|
55
|
-
} else if(arg === "--tag"){
|
|
56
|
-
tag = argv[
|
|
57
|
-
} else if(arg === "--access"){
|
|
58
|
-
access = argv[
|
|
59
|
-
} else if(arg === "-h" || arg === "--help"){
|
|
53
|
+
} else if (arg === "-C" || arg === "--cwd") {
|
|
54
|
+
cwd = argv[++i];
|
|
55
|
+
} else if (arg === "--tag") {
|
|
56
|
+
tag = argv[++i];
|
|
57
|
+
} else if (arg === "--access") {
|
|
58
|
+
access = argv[++i];
|
|
59
|
+
} else if (arg === "-h" || arg === "--help") {
|
|
60
60
|
printPublishHelp();
|
|
61
61
|
process.exit(0);
|
|
62
|
-
} else if(arg.startsWith("-")){
|
|
62
|
+
} else if (arg.startsWith("-")) {
|
|
63
63
|
continue;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -67,23 +67,23 @@ function parsePublishArgs(argv : string[]){
|
|
|
67
67
|
return { cwd, dryRun, refresh, placeholder, tag, access, auth };
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
export function printPublishReport(report
|
|
70
|
+
export function printPublishReport(report: PublishReport, dryRun?: boolean): void {
|
|
71
71
|
const prefix = dryRun ? "would publish" : "published";
|
|
72
72
|
console.log(`${prefix} workspace ${report.root}`);
|
|
73
|
-
if(report.skipped.length>0){
|
|
73
|
+
if (report.skipped.length > 0) {
|
|
74
74
|
console.log(`skipped private packages: ${report.skipped.join(", ")}`);
|
|
75
75
|
}
|
|
76
|
-
if(report.skippedVersions.length>0){
|
|
76
|
+
if (report.skippedVersions.length > 0) {
|
|
77
77
|
console.log(`skipped already published: ${report.skippedVersions.join(", ")}`);
|
|
78
78
|
}
|
|
79
79
|
console.log("publish order:");
|
|
80
|
-
for(const name of report.order){
|
|
80
|
+
for (const name of report.order) {
|
|
81
81
|
const marker = report.published.includes(name) ? prefix : "pending";
|
|
82
82
|
console.log(` ${marker}: ${name}`);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
function printPublishHelp()
|
|
86
|
+
function printPublishHelp(): void {
|
|
87
87
|
console.log(`nifty publish — publish workspace npm packages in dependency order
|
|
88
88
|
|
|
89
89
|
OTP/TOTP is generated in nifty-publisher (set NPM_TOTP_SECRET in .env.placeholder.local).
|
package/src/cli/resolveNpm.ts
CHANGED
|
@@ -2,13 +2,13 @@ import { existsSync } from "node:fs";
|
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
|
|
4
4
|
/** Resolve npm next to the active Node binary (Windows needs `npm.cmd`). */
|
|
5
|
-
export function resolveNpmExecutable()
|
|
6
|
-
if(process.env.NIFTY_NPM){
|
|
5
|
+
export function resolveNpmExecutable(): string {
|
|
6
|
+
if (process.env.NIFTY_NPM) {
|
|
7
7
|
return process.env.NIFTY_NPM;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
const sibling = join(dirname(process.execPath), process.platform === "win32" ? "npm.cmd" : "npm");
|
|
11
|
-
if(existsSync(sibling)){
|
|
11
|
+
if (existsSync(sibling)) {
|
|
12
12
|
return sibling;
|
|
13
13
|
}
|
|
14
14
|
|