auklet 0.0.29 → 0.1.1
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 +25 -1
- package/dist/cli/inspect.d.ts +1 -0
- package/dist/cli/inspect.js +20 -0
- package/dist/cli/main.js +5 -0
- package/dist/css/inspect.d.ts +87 -0
- package/dist/css/inspect.js +303 -0
- package/dist/css/vite/hmr.js +0 -7
- package/dist/css/watch/watcher.d.ts +9 -2
- package/dist/css/watch/watcher.js +64 -15
- package/dist/publish/api/pnpmApi.d.ts +4 -0
- package/dist/publish/api/pnpmApi.js +54 -9
- package/dist/publish/api/publishArgs.d.ts +1 -0
- package/dist/publish/api/publishArgs.js +3 -3
- package/dist/publish/api/registry.d.ts +1 -0
- package/dist/publish/api/registry.js +7 -0
- package/dist/publish/cli.d.ts +11 -0
- package/dist/publish/cli.js +26 -16
- package/dist/publish/inspect.d.ts +29 -0
- package/dist/publish/inspect.js +220 -0
- package/dist/publish/inspectPack.d.ts +28 -0
- package/dist/publish/inspectPack.js +206 -0
- package/dist/publish/inspectRegistry.d.ts +23 -0
- package/dist/publish/inspectRegistry.js +107 -0
- package/dist/publish/runner/publishPreflight.js +1 -7
- package/dist/publish/runner/releaseGitController.js +4 -0
- package/dist/publish/types.d.ts +5 -4
- package/package.json +3 -3
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { execa, type Options } from 'execa';
|
|
1
2
|
import type { WorkspacePackage } from '#auklet/publish/types';
|
|
2
3
|
export declare class NpmPublishAuthenticationError extends Error {
|
|
3
4
|
readonly packageRoot: string;
|
|
@@ -6,6 +7,7 @@ export declare class NpmPublishAuthenticationError extends Error {
|
|
|
6
7
|
export declare class NpmPackageVersionExistsError extends Error {
|
|
7
8
|
constructor(packageName: string, version: string, registry?: string);
|
|
8
9
|
}
|
|
10
|
+
export declare function withPnpmTimeout(subprocess: ReturnType<typeof execa>, timeout: number): Promise<import("node_modules/execa/types/return/result").CommonResult<false, Options> & import("node_modules/execa/types/return/result").OmitErrorIfReject<boolean | undefined>>;
|
|
9
11
|
export declare function ensurePnpm(): Promise<string>;
|
|
10
12
|
export declare function readPnpmWorkspacePackages(root: string): Promise<WorkspacePackage[]>;
|
|
11
13
|
export declare function runPnpmBuild(packageRoot: string): Promise<void>;
|
|
@@ -13,9 +15,11 @@ export declare function runPnpmPublish(packageRoot: string, args: Array<string>)
|
|
|
13
15
|
export declare function runPnpmWhoami(packageRoot: string, options?: {
|
|
14
16
|
packageName?: string;
|
|
15
17
|
registry?: string;
|
|
18
|
+
timeout?: number;
|
|
16
19
|
}): Promise<string>;
|
|
17
20
|
export declare function hasPublishedPackageVersion(packageRoot: string, packageName: string, version: string, options?: {
|
|
18
21
|
registry?: string;
|
|
22
|
+
timeout?: number;
|
|
19
23
|
}): Promise<boolean>;
|
|
20
24
|
export declare function runPnpmOwnerAdd(packageName: string, user: string, options: {
|
|
21
25
|
cwd: string;
|
|
@@ -17,15 +17,43 @@ export class NpmPackageVersionExistsError extends Error {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
const runPnpm = async (args, options = {}) => {
|
|
20
|
-
|
|
20
|
+
const timeout = options.timeout;
|
|
21
|
+
const subprocess = execa('pnpm', args, {
|
|
21
22
|
reject: false,
|
|
22
23
|
...options,
|
|
24
|
+
timeout: undefined,
|
|
23
25
|
});
|
|
26
|
+
if (!timeout)
|
|
27
|
+
return subprocess;
|
|
28
|
+
return withPnpmTimeout(subprocess, timeout);
|
|
24
29
|
};
|
|
30
|
+
export async function withPnpmTimeout(subprocess, timeout) {
|
|
31
|
+
let timeoutId = null;
|
|
32
|
+
const result = await Promise.race([
|
|
33
|
+
subprocess,
|
|
34
|
+
new Promise((resolve) => {
|
|
35
|
+
timeoutId = setTimeout(() => {
|
|
36
|
+
const error = new Error(`pnpm command timed out after ${timeout}ms.`);
|
|
37
|
+
subprocess.kill('SIGKILL', error);
|
|
38
|
+
resolve({
|
|
39
|
+
failed: true,
|
|
40
|
+
timedOut: true,
|
|
41
|
+
exitCode: undefined,
|
|
42
|
+
stdout: '',
|
|
43
|
+
stderr: error.message,
|
|
44
|
+
});
|
|
45
|
+
}, timeout);
|
|
46
|
+
}),
|
|
47
|
+
]);
|
|
48
|
+
if (timeoutId)
|
|
49
|
+
clearTimeout(timeoutId);
|
|
50
|
+
subprocess.catch(() => { });
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
25
53
|
export async function ensurePnpm() {
|
|
26
54
|
const result = await runPnpm(['--version']);
|
|
27
55
|
const stdout = String(result.stdout ?? '');
|
|
28
|
-
if (result
|
|
56
|
+
if (hasFailedPnpmResult(result) || !stdout) {
|
|
29
57
|
throw new Error('[publish] pnpm is required for publishing.\n' +
|
|
30
58
|
'[publish] Install pnpm first:\n' +
|
|
31
59
|
' corepack enable\n' +
|
|
@@ -57,7 +85,7 @@ export async function runPnpmBuild(packageRoot) {
|
|
|
57
85
|
cwd: packageRoot,
|
|
58
86
|
stdio: 'inherit',
|
|
59
87
|
});
|
|
60
|
-
if (result
|
|
88
|
+
if (hasFailedPnpmResult(result)) {
|
|
61
89
|
throw new Error(`[publish] build failed at ${packageRoot}.`);
|
|
62
90
|
}
|
|
63
91
|
}
|
|
@@ -69,7 +97,7 @@ export async function runPnpmPublish(packageRoot, args) {
|
|
|
69
97
|
});
|
|
70
98
|
if (isDryRun)
|
|
71
99
|
writeProcessOutput(result);
|
|
72
|
-
if (result
|
|
100
|
+
if (hasFailedPnpmResult(result)) {
|
|
73
101
|
if (hasNpmAuthChallenge(result)) {
|
|
74
102
|
throw new NpmPublishAuthenticationError(packageRoot);
|
|
75
103
|
}
|
|
@@ -82,12 +110,15 @@ export async function runPnpmWhoami(packageRoot, options = {}) {
|
|
|
82
110
|
args.push('--registry', options.registry);
|
|
83
111
|
const result = await runPnpm(args, {
|
|
84
112
|
cwd: packageRoot,
|
|
113
|
+
timeout: options.timeout,
|
|
85
114
|
});
|
|
86
|
-
if (result
|
|
115
|
+
if (hasFailedPnpmResult(result)) {
|
|
87
116
|
const target = options.packageName ? ` for ${options.packageName}` : '';
|
|
88
117
|
const registry = options.registry ? ` at ${options.registry}` : '';
|
|
118
|
+
const reason = getPnpmFailureReason(result);
|
|
89
119
|
throw new Error(`[publish] npm authentication is required${target}${registry} before publishing.\n` +
|
|
90
|
-
'[publish] Run `pnpm login` or configure an npm token before retrying.'
|
|
120
|
+
'[publish] Run `pnpm login` or configure an npm token before retrying.' +
|
|
121
|
+
(reason ? `\n[publish] Reason: ${reason}` : ''));
|
|
91
122
|
}
|
|
92
123
|
return String(result.stdout ?? '').trim();
|
|
93
124
|
}
|
|
@@ -97,12 +128,16 @@ export async function hasPublishedPackageVersion(packageRoot, packageName, versi
|
|
|
97
128
|
args.push('--registry', options.registry);
|
|
98
129
|
const result = await runPnpm(args, {
|
|
99
130
|
cwd: packageRoot,
|
|
131
|
+
timeout: options.timeout,
|
|
100
132
|
});
|
|
101
|
-
if (!result
|
|
133
|
+
if (!hasFailedPnpmResult(result)) {
|
|
102
134
|
return String(result.stdout ?? '').trim() === version;
|
|
135
|
+
}
|
|
103
136
|
if (isPackageNotFound(result))
|
|
104
137
|
return false;
|
|
105
|
-
|
|
138
|
+
const reason = getPnpmFailureReason(result);
|
|
139
|
+
throw new Error(`[publish] failed to check published version for ${packageName}@${version}.` +
|
|
140
|
+
(reason ? `\n[publish] Reason: ${reason}` : ''));
|
|
106
141
|
}
|
|
107
142
|
export async function runPnpmOwnerAdd(packageName, user, options) {
|
|
108
143
|
const args = ['owner', 'add', user, packageName];
|
|
@@ -112,7 +147,7 @@ export async function runPnpmOwnerAdd(packageName, user, options) {
|
|
|
112
147
|
cwd: options.cwd,
|
|
113
148
|
stdio: 'inherit',
|
|
114
149
|
});
|
|
115
|
-
if (result
|
|
150
|
+
if (hasFailedPnpmResult(result)) {
|
|
116
151
|
throw new Error(`[publish] pnpm owner add failed for ${user} -> ${packageName}.`);
|
|
117
152
|
}
|
|
118
153
|
}
|
|
@@ -128,6 +163,16 @@ const isWorkspacePackage = (value) => {
|
|
|
128
163
|
value.version.length > 0 &&
|
|
129
164
|
(value.private === undefined || typeof value.private === 'boolean'));
|
|
130
165
|
};
|
|
166
|
+
const hasFailedPnpmResult = (result) => {
|
|
167
|
+
return result.failed === true || result.exitCode !== 0;
|
|
168
|
+
};
|
|
169
|
+
const getPnpmFailureReason = (result) => {
|
|
170
|
+
const stderr = String(result.stderr ?? '').trim();
|
|
171
|
+
if (stderr)
|
|
172
|
+
return stderr;
|
|
173
|
+
const stdout = String(result.stdout ?? '').trim();
|
|
174
|
+
return stdout || null;
|
|
175
|
+
};
|
|
131
176
|
function throwInvalidWorkspacePackages() {
|
|
132
177
|
throw new Error('[publish] failed to read pnpm workspace packages.\n' +
|
|
133
178
|
'[publish] Expected `pnpm list -r --depth -1 --json` to return package objects with name/path/version.');
|
|
@@ -8,7 +8,7 @@ export function createPublishArgs(target, options) {
|
|
|
8
8
|
args.push('--ignore-scripts');
|
|
9
9
|
if (shouldAddPublicAccess(target))
|
|
10
10
|
args.push('--access', 'public');
|
|
11
|
-
const tag =
|
|
11
|
+
const tag = resolvePublishTag(options.version);
|
|
12
12
|
if (tag)
|
|
13
13
|
args.push('--tag', tag);
|
|
14
14
|
return args;
|
|
@@ -18,8 +18,8 @@ const shouldAddPublicAccess = (target) => {
|
|
|
18
18
|
!target.private &&
|
|
19
19
|
!target.packageJson.publishConfig?.access);
|
|
20
20
|
};
|
|
21
|
-
|
|
21
|
+
export function resolvePublishTag(versionSpec) {
|
|
22
22
|
if (versionSpec === 'alpha' || versionSpec === 'beta')
|
|
23
23
|
return versionSpec;
|
|
24
24
|
return null;
|
|
25
|
-
}
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getPublishRegistry(publishConfig: unknown): string | undefined;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { isPlainObject, isString } from 'aidly';
|
|
2
|
+
export function getPublishRegistry(publishConfig) {
|
|
3
|
+
if (!isPlainObject(publishConfig))
|
|
4
|
+
return undefined;
|
|
5
|
+
const registry = Reflect.get(publishConfig, 'registry');
|
|
6
|
+
return isString(registry) && registry.length > 0 ? registry : undefined;
|
|
7
|
+
}
|
package/dist/publish/cli.d.ts
CHANGED
|
@@ -1,2 +1,13 @@
|
|
|
1
1
|
export declare function runPublishCli(args: Array<string>): Promise<void>;
|
|
2
|
+
export declare function resolvePublishCliOptions(args: Array<string>, cwd?: string): {
|
|
3
|
+
cwd: string;
|
|
4
|
+
otp: string | undefined;
|
|
5
|
+
filters: string[];
|
|
6
|
+
version: string | undefined;
|
|
7
|
+
git: boolean;
|
|
8
|
+
format: boolean;
|
|
9
|
+
dryRun: boolean;
|
|
10
|
+
allowDirty: boolean;
|
|
11
|
+
ignoreScripts: boolean;
|
|
12
|
+
};
|
|
2
13
|
export declare function runOwnerCli(args: Array<string>): Promise<void>;
|
package/dist/publish/cli.js
CHANGED
|
@@ -9,37 +9,47 @@ const publishFlags = new Set([
|
|
|
9
9
|
'version',
|
|
10
10
|
'dry-run',
|
|
11
11
|
'format',
|
|
12
|
+
'git',
|
|
12
13
|
'otp',
|
|
13
14
|
'ignore-scripts',
|
|
14
15
|
'allow-dirty',
|
|
15
16
|
]);
|
|
16
17
|
const ownerFlags = new Set(['_', 'filter', 'package', 'otp']);
|
|
17
18
|
export async function runPublishCli(args) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
default: {
|
|
24
|
-
format: true,
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
validateFlags(argv, publishFlags);
|
|
19
|
+
await ensurePnpm();
|
|
20
|
+
await new PublishRunner(resolvePublishCliOptions(args)).run();
|
|
21
|
+
}
|
|
22
|
+
export function resolvePublishCliOptions(args, cwd = process.cwd()) {
|
|
23
|
+
const argv = parsePublishArgs(args);
|
|
28
24
|
if (argv._.length) {
|
|
29
25
|
throw new Error(`[publish] unknown publish argument: ${argv._.join(' ')}`);
|
|
30
26
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
return {
|
|
28
|
+
cwd,
|
|
29
|
+
otp: stringOption(argv.otp),
|
|
34
30
|
filters: toArray(argv.filter),
|
|
35
31
|
version: stringOption(argv.version),
|
|
36
|
-
|
|
32
|
+
git: argv.git !== false,
|
|
37
33
|
format: argv.format !== false,
|
|
38
|
-
|
|
34
|
+
dryRun: argv['dry-run'] === true,
|
|
39
35
|
allowDirty: argv['allow-dirty'] === true,
|
|
40
36
|
ignoreScripts: argv['ignore-scripts'] === true,
|
|
41
|
-
}
|
|
37
|
+
};
|
|
42
38
|
}
|
|
39
|
+
const parsePublishArgs = (args) => {
|
|
40
|
+
const cliArgs = stripLeadingArgsSeparator(args);
|
|
41
|
+
validateNoPrefixedFlags(cliArgs, new Set(['--no-format', '--no-git']));
|
|
42
|
+
const argv = minimist(cliArgs, {
|
|
43
|
+
string: ['filter', 'version', 'otp'],
|
|
44
|
+
boolean: ['dry-run', 'format', 'git', 'ignore-scripts', 'allow-dirty'],
|
|
45
|
+
default: {
|
|
46
|
+
git: true,
|
|
47
|
+
format: true,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
validateFlags(argv, publishFlags);
|
|
51
|
+
return argv;
|
|
52
|
+
};
|
|
43
53
|
export async function runOwnerCli(args) {
|
|
44
54
|
const cliArgs = stripLeadingArgsSeparator(args);
|
|
45
55
|
validateNoPrefixedFlags(cliArgs, new Set());
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type PublishRegistryCheck } from '#auklet/publish/inspectRegistry';
|
|
2
|
+
import { type PackFileCheck } from '#auklet/publish/inspectPack';
|
|
3
|
+
import type { PublishOptions, PublishPlan } from '#auklet/publish/types';
|
|
4
|
+
export declare function runInspectPublishCli(args: Array<string>): Promise<0 | 1>;
|
|
5
|
+
export declare function createPublishInspectModel(options: PublishOptions, plan: PublishPlan, packageFileChecks?: Array<PackFileCheck>, registryChecks?: Array<PublishRegistryCheck>): {
|
|
6
|
+
details: {
|
|
7
|
+
mode: "monorepo" | "single";
|
|
8
|
+
publish: string;
|
|
9
|
+
packages: number;
|
|
10
|
+
version: string;
|
|
11
|
+
tag: string;
|
|
12
|
+
git: string;
|
|
13
|
+
format: string;
|
|
14
|
+
root: string;
|
|
15
|
+
};
|
|
16
|
+
packageFileChecks: PackFileCheck[];
|
|
17
|
+
targets: {
|
|
18
|
+
packageName: string;
|
|
19
|
+
version: string;
|
|
20
|
+
publishVersion: string;
|
|
21
|
+
registry: string;
|
|
22
|
+
access: string;
|
|
23
|
+
}[];
|
|
24
|
+
registryChecks: PublishRegistryCheck[];
|
|
25
|
+
hooks: {
|
|
26
|
+
name: string;
|
|
27
|
+
configured: boolean;
|
|
28
|
+
}[];
|
|
29
|
+
};
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { isString } from 'aidly';
|
|
3
|
+
import { createAukletLogger } from '#auklet/logger';
|
|
4
|
+
import { resolvePublishTag } from '#auklet/publish/api/publishArgs';
|
|
5
|
+
import { getPublishRegistry } from '#auklet/publish/api/registry';
|
|
6
|
+
import { ensurePnpm } from '#auklet/publish/api/pnpmApi';
|
|
7
|
+
import { resolvePublishCliOptions } from '#auklet/publish/cli';
|
|
8
|
+
import { inspectPublishRegistry, } from '#auklet/publish/inspectRegistry';
|
|
9
|
+
import { inspectPackageFiles, PackInspectReporter, } from '#auklet/publish/inspectPack';
|
|
10
|
+
import { resolvePublishPlan } from '#auklet/publish/targetResolver';
|
|
11
|
+
export async function runInspectPublishCli(args) {
|
|
12
|
+
await ensurePnpm();
|
|
13
|
+
const options = resolvePublishCliOptions(args);
|
|
14
|
+
const logger = createAukletLogger({ scope: 'inspect' });
|
|
15
|
+
const plan = await resolvePublishPlan(options, logger);
|
|
16
|
+
const packageFileChecks = inspectPackageFiles(plan.targets);
|
|
17
|
+
const packageFileCheckFailed = packageFileChecks.some((check) => check.status === 'missing');
|
|
18
|
+
if (packageFileCheckFailed) {
|
|
19
|
+
new PublishInspectReporter(options, plan, packageFileChecks, []).report();
|
|
20
|
+
return 1;
|
|
21
|
+
}
|
|
22
|
+
const spinner = logger.spinner('Checking publish registry');
|
|
23
|
+
spinner.start();
|
|
24
|
+
const registryChecks = await inspectPublishRegistry(plan, {
|
|
25
|
+
onCheck: (info) => {
|
|
26
|
+
spinner.text([
|
|
27
|
+
'Checking registry ',
|
|
28
|
+
info.check,
|
|
29
|
+
' for ',
|
|
30
|
+
logger.package(info.packageName),
|
|
31
|
+
]);
|
|
32
|
+
},
|
|
33
|
+
onRetry: (info) => {
|
|
34
|
+
spinner.text([
|
|
35
|
+
'Checking registry ',
|
|
36
|
+
info.check,
|
|
37
|
+
' for ',
|
|
38
|
+
logger.package(info.packageName),
|
|
39
|
+
', retrying ',
|
|
40
|
+
logger.value(`${info.attempt}/${info.maxAttempts}`),
|
|
41
|
+
]);
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
if (registryChecks.some((check) => check.reason)) {
|
|
45
|
+
spinner.fail('Publish registry checks failed');
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
spinner.succeed('Publish registry checks passed');
|
|
49
|
+
}
|
|
50
|
+
new PublishInspectReporter(options, plan, packageFileChecks, registryChecks).report();
|
|
51
|
+
if (registryChecks.some((check) => check.reason)) {
|
|
52
|
+
return 1;
|
|
53
|
+
}
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
class PublishInspectReporter {
|
|
57
|
+
options;
|
|
58
|
+
plan;
|
|
59
|
+
packageFileChecks;
|
|
60
|
+
registryChecks;
|
|
61
|
+
logger = createAukletLogger();
|
|
62
|
+
constructor(options, plan, packageFileChecks, registryChecks) {
|
|
63
|
+
this.options = options;
|
|
64
|
+
this.plan = plan;
|
|
65
|
+
this.packageFileChecks = packageFileChecks;
|
|
66
|
+
this.registryChecks = registryChecks;
|
|
67
|
+
}
|
|
68
|
+
report() {
|
|
69
|
+
const model = createPublishInspectModel(this.options, this.plan, this.packageFileChecks, this.registryChecks);
|
|
70
|
+
new PackInspectReporter(this.options.cwd, this.plan.targets, model.packageFileChecks, 'Package file checks').report();
|
|
71
|
+
this.logger.newline();
|
|
72
|
+
this.logger.result({
|
|
73
|
+
title: this.formatResultTitle('Publish inspect', model.registryChecks.some((check) => check.reason)),
|
|
74
|
+
status: 'info',
|
|
75
|
+
body: [
|
|
76
|
+
'Read-only publish plan. No files, git refs, or packages changed.',
|
|
77
|
+
],
|
|
78
|
+
details: this.formatDetails(model),
|
|
79
|
+
});
|
|
80
|
+
this.logger.newline();
|
|
81
|
+
this.writeSectionTitle('Targets');
|
|
82
|
+
this.logger.rows({
|
|
83
|
+
columns: ['package', 'version', 'registry', 'access'],
|
|
84
|
+
rows: model.targets.map((target) => [
|
|
85
|
+
this.logger.package(target.packageName),
|
|
86
|
+
this.formatVersionChange(target.version, target.publishVersion),
|
|
87
|
+
this.logger.colors.gray(target.registry),
|
|
88
|
+
this.logger.colors.gray(target.access),
|
|
89
|
+
]),
|
|
90
|
+
});
|
|
91
|
+
this.logger.newline();
|
|
92
|
+
this.writeSectionTitle('Registry checks');
|
|
93
|
+
this.logger.rows({
|
|
94
|
+
columns: ['package', 'registry', 'auth', 'version'],
|
|
95
|
+
rows: model.registryChecks.map((check) => [
|
|
96
|
+
this.logger.package(check.packageName),
|
|
97
|
+
this.logger.colors.gray(check.registry),
|
|
98
|
+
this.formatCheckStatus(check.auth),
|
|
99
|
+
this.formatCheckStatus(check.version),
|
|
100
|
+
]),
|
|
101
|
+
});
|
|
102
|
+
const failedChecks = model.registryChecks.filter((check) => check.reason);
|
|
103
|
+
if (failedChecks.length) {
|
|
104
|
+
this.logger.newline();
|
|
105
|
+
this.writeSectionTitle('Registry issues', 'error');
|
|
106
|
+
this.writeRegistryIssues(failedChecks);
|
|
107
|
+
}
|
|
108
|
+
this.logger.newline();
|
|
109
|
+
this.writeSectionTitle('Hooks');
|
|
110
|
+
this.logger.rows({
|
|
111
|
+
columns: ['hook', 'configured'],
|
|
112
|
+
rows: model.hooks.map((hook) => [
|
|
113
|
+
this.logger.colors.gray(hook.name),
|
|
114
|
+
this.formatValue(hook.configured ? 'yes' : 'no'),
|
|
115
|
+
]),
|
|
116
|
+
});
|
|
117
|
+
this.logger.newline();
|
|
118
|
+
}
|
|
119
|
+
formatDetails(model) {
|
|
120
|
+
return {
|
|
121
|
+
mode: this.formatValue(model.details.mode),
|
|
122
|
+
publish: this.formatValue(model.details.publish),
|
|
123
|
+
packages: this.formatValue(model.details.packages),
|
|
124
|
+
version: this.logger.version(model.details.version),
|
|
125
|
+
tag: this.formatValue(model.details.tag),
|
|
126
|
+
git: this.formatValue(model.details.git),
|
|
127
|
+
format: this.formatValue(model.details.format),
|
|
128
|
+
root: this.logger.path(model.details.root),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
formatVersionChange(from, to) {
|
|
132
|
+
return [
|
|
133
|
+
this.logger.version(from),
|
|
134
|
+
this.logger.colors.gray(' -> '),
|
|
135
|
+
this.logger.version(to),
|
|
136
|
+
];
|
|
137
|
+
}
|
|
138
|
+
formatValue(value) {
|
|
139
|
+
return this.logger.colors.bold(this.logger.colors.cyan(String(value)));
|
|
140
|
+
}
|
|
141
|
+
formatResultTitle(title, failed) {
|
|
142
|
+
return this.logger.colors.bold(failed ? this.logger.colors.red(title) : this.logger.colors.green(title));
|
|
143
|
+
}
|
|
144
|
+
formatCheckStatus(status) {
|
|
145
|
+
if (status === 'success')
|
|
146
|
+
return this.logger.colors.green('ok');
|
|
147
|
+
return this.logger.colors.red('failed');
|
|
148
|
+
}
|
|
149
|
+
writeSectionTitle(title, status = 'normal') {
|
|
150
|
+
const content = status === 'error' ? this.logger.colors.red(title) : title;
|
|
151
|
+
this.logger.raw(content);
|
|
152
|
+
}
|
|
153
|
+
writeRegistryIssues(checks) {
|
|
154
|
+
for (const [index, check] of checks.entries()) {
|
|
155
|
+
if (index > 0)
|
|
156
|
+
this.logger.newline();
|
|
157
|
+
const [firstLine, ...restLines] = String(check.reason ?? '').split('\n');
|
|
158
|
+
this.logger.item(this.logger.package(check.packageName), ': ', this.logger.colors.red(firstLine));
|
|
159
|
+
for (const line of restLines) {
|
|
160
|
+
this.logger.raw(` ${this.logger.colors.red(line)}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
export function createPublishInspectModel(options, plan, packageFileChecks = [], registryChecks = []) {
|
|
166
|
+
return {
|
|
167
|
+
details: {
|
|
168
|
+
mode: plan.workspaceMode,
|
|
169
|
+
publish: plan.dryRun ? 'dry-run' : 'real',
|
|
170
|
+
packages: plan.targets.length,
|
|
171
|
+
version: plan.version,
|
|
172
|
+
tag: resolvePublishTag(options.version) ?? 'latest',
|
|
173
|
+
git: getGitMode(options),
|
|
174
|
+
format: options.format ? 'enabled' : 'disabled',
|
|
175
|
+
root: path.relative(options.cwd, plan.root) || '.',
|
|
176
|
+
},
|
|
177
|
+
packageFileChecks,
|
|
178
|
+
targets: plan.targets.map((target) => ({
|
|
179
|
+
packageName: target.packageName,
|
|
180
|
+
version: target.version,
|
|
181
|
+
publishVersion: target.publishVersion,
|
|
182
|
+
registry: getRegistry(target.packageJson),
|
|
183
|
+
access: getAccess(target),
|
|
184
|
+
})),
|
|
185
|
+
registryChecks,
|
|
186
|
+
hooks: getHookRows(plan.config),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
const getGitMode = (options) => {
|
|
190
|
+
if (options.dryRun)
|
|
191
|
+
return 'skipped (dry-run)';
|
|
192
|
+
if (options.allowDirty)
|
|
193
|
+
return 'skipped (--allow-dirty)';
|
|
194
|
+
if (options.git === false)
|
|
195
|
+
return 'skipped (--no-git)';
|
|
196
|
+
return 'commit + tag';
|
|
197
|
+
};
|
|
198
|
+
const getHookRows = (config) => {
|
|
199
|
+
const hooks = [
|
|
200
|
+
['beforeBuild', config.beforeBuild],
|
|
201
|
+
['afterBuild', config.afterBuild],
|
|
202
|
+
['beforePublish', config.beforePublish],
|
|
203
|
+
['afterPublish', config.afterPublish],
|
|
204
|
+
];
|
|
205
|
+
return hooks.map(([name, value]) => ({
|
|
206
|
+
name,
|
|
207
|
+
configured: Boolean(value),
|
|
208
|
+
}));
|
|
209
|
+
};
|
|
210
|
+
const getRegistry = (packageJson) => {
|
|
211
|
+
return getPublishRegistry(packageJson.publishConfig) ?? 'default';
|
|
212
|
+
};
|
|
213
|
+
const getAccess = (target) => {
|
|
214
|
+
const access = target.packageJson.publishConfig?.access;
|
|
215
|
+
if (isString(access) && access)
|
|
216
|
+
return access;
|
|
217
|
+
if (target.packageName.startsWith('@') && !target.private)
|
|
218
|
+
return 'public';
|
|
219
|
+
return 'default';
|
|
220
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { PublishTarget } from '#auklet/publish/types';
|
|
2
|
+
export type PackFileCheckStatus = 'exists' | 'missing' | 'pattern' | 'skipped';
|
|
3
|
+
export type PackFileCheck = {
|
|
4
|
+
target: PublishTarget;
|
|
5
|
+
field: string;
|
|
6
|
+
file: string;
|
|
7
|
+
status: PackFileCheckStatus;
|
|
8
|
+
};
|
|
9
|
+
export declare function runInspectPackCli(args: Array<string>): Promise<0 | 1>;
|
|
10
|
+
export declare function inspectPackageFiles(targets: Array<PublishTarget>): {
|
|
11
|
+
target: PublishTarget;
|
|
12
|
+
field: string;
|
|
13
|
+
file: string;
|
|
14
|
+
status: PackFileCheckStatus;
|
|
15
|
+
}[];
|
|
16
|
+
export declare class PackInspectReporter {
|
|
17
|
+
private readonly cwd;
|
|
18
|
+
private readonly targets;
|
|
19
|
+
private readonly checks;
|
|
20
|
+
private readonly title;
|
|
21
|
+
private readonly logger;
|
|
22
|
+
constructor(cwd: string, targets: Array<PublishTarget>, checks: Array<PackFileCheck>, title?: string);
|
|
23
|
+
report(): void;
|
|
24
|
+
private writeSectionTitle;
|
|
25
|
+
private formatStatus;
|
|
26
|
+
private formatValue;
|
|
27
|
+
private formatResultTitle;
|
|
28
|
+
}
|