auklet 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/README.md +14 -3
- package/dist/config.d.ts +1 -2
- package/dist/config.js +0 -8
- package/dist/publish/api/npmrc.d.ts +8 -0
- package/dist/publish/api/npmrc.js +89 -0
- package/dist/publish/api/pnpmApi.d.ts +18 -4
- package/dist/publish/api/pnpmApi.js +22 -6
- package/dist/publish/api/pnpmPublishApi.js +6 -1
- package/dist/publish/cli.d.ts +1 -0
- package/dist/publish/cli.js +15 -4
- package/dist/publish/inspect.js +7 -1
- package/dist/publish/inspectRegistry.d.ts +2 -1
- package/dist/publish/inspectRegistry.js +2 -0
- package/dist/publish/publishRunner.js +1 -1
- package/dist/publish/runner/packageBuilder.d.ts +2 -1
- package/dist/publish/runner/packageBuilder.js +5 -1
- package/dist/publish/runner/publishPreflight.d.ts +2 -0
- package/dist/publish/runner/publishPreflight.js +40 -1
- package/dist/publish/targetResolver.d.ts +1 -1
- package/dist/publish/targetResolver.js +3 -1
- package/dist/publish/types.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -131,6 +131,7 @@ auk publish --version patch --dry-run
|
|
|
131
131
|
auk publish --no-format
|
|
132
132
|
auk publish --no-git
|
|
133
133
|
auk publish --otp 123456
|
|
134
|
+
auk publish --token npm_xxx
|
|
134
135
|
auk inspect publish --version patch
|
|
135
136
|
auk inspect pack --filter @scope/ui
|
|
136
137
|
auk inspect css --modules
|
|
@@ -161,8 +162,16 @@ Before writing versions, auklet checks npm authentication from each target
|
|
|
161
162
|
package directory. Package-local `.npmrc` files and
|
|
162
163
|
`package.json#publishConfig.registry` are respected.
|
|
163
164
|
`--otp` is forwarded to `pnpm publish` for npm accounts or organizations that
|
|
164
|
-
require publish 2FA, and to `pnpm owner add` for owner management 2FA.
|
|
165
|
-
|
|
165
|
+
require publish 2FA, and to `pnpm owner add` for owner management 2FA.
|
|
166
|
+
`--token` sets `NODE_AUTH_TOKEN` and `NPM_TOKEN` for publish subprocesses. The
|
|
167
|
+
token still needs npmrc auth config, for example:
|
|
168
|
+
|
|
169
|
+
```ini
|
|
170
|
+
//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
When a package uses `package.json#publishConfig.registry`, the npmrc token entry
|
|
174
|
+
must target that registry. In CI, prefer an npm automation token over `--otp`.
|
|
166
175
|
|
|
167
176
|
`auk inspect publish` accepts the same publish selection and version flags as
|
|
168
177
|
`auk publish`. It resolves the publish plan, checks package entry/export files,
|
|
@@ -177,7 +186,9 @@ and declared `files` paths point to existing package files.
|
|
|
177
186
|
`auk inspect css` accepts the same build override flags as `auk build`. It
|
|
178
187
|
prints the normalized CSS plan, including output entries, theme files, and
|
|
179
188
|
module entries. When run from a pnpm workspace root, it inspects workspace child
|
|
180
|
-
packages instead of the root package. It does not write CSS output
|
|
189
|
+
packages instead of the root package. It does not write CSS output, but
|
|
190
|
+
dependency CSS files must already exist when the plan relies on external package
|
|
191
|
+
style entries or component auto imports.
|
|
181
192
|
|
|
182
193
|
## Configuration
|
|
183
194
|
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AukletConfig
|
|
1
|
+
import type { AukletConfig } from '#auklet/types';
|
|
2
2
|
export declare const aukletConfigFiles: string[];
|
|
3
3
|
export declare function isAukletConfigFile(file: string): boolean;
|
|
4
4
|
export declare const aukletDefaultOptions: {
|
|
@@ -15,7 +15,6 @@ export declare const aukletDefaultOptions: {
|
|
|
15
15
|
dependencies: {};
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
|
-
export declare const aukletDefaultStyleDependencyConfig: StyleDependencyGroup;
|
|
19
18
|
export declare function normalizeAukletConfig(config?: AukletConfig): {
|
|
20
19
|
source: string;
|
|
21
20
|
output: string;
|
package/dist/config.js
CHANGED
|
@@ -16,14 +16,6 @@ export const aukletDefaultOptions = {
|
|
|
16
16
|
dependencies: {},
|
|
17
17
|
},
|
|
18
18
|
};
|
|
19
|
-
export const aukletDefaultStyleDependencyConfig = {
|
|
20
|
-
entry: '/style.css',
|
|
21
|
-
components: ['/pages/**.css', '/components/**.css'],
|
|
22
|
-
themes: {
|
|
23
|
-
dark: '/themes/dark.css',
|
|
24
|
-
light: '/themes/light.css',
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
19
|
const normalizeStyleDependency = (dependency) => ({
|
|
28
20
|
entry: dependency.entry,
|
|
29
21
|
themes: dependency.themes,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type NpmrcAuthEnvOptions = {
|
|
2
|
+
token?: string;
|
|
3
|
+
};
|
|
4
|
+
export declare function findNpmrcWithAuthToken(packageRoot: string, root: string, registry?: string): string | undefined;
|
|
5
|
+
export declare function findNpmrcFiles(packageRoot: string, root: string): string[];
|
|
6
|
+
export declare function validateNpmrcAuthEnv(packageRoot: string, root: string, options?: NpmrcAuthEnvOptions): void;
|
|
7
|
+
export declare function hasAuthToken(content: string, registry?: string): boolean;
|
|
8
|
+
export declare function toNpmrcRegistryKey(registry: string): string;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export function findNpmrcWithAuthToken(packageRoot, root, registry) {
|
|
4
|
+
const npmrcFiles = findNpmrcFiles(packageRoot, root);
|
|
5
|
+
return npmrcFiles.find((file) => {
|
|
6
|
+
return hasAuthToken(fs.readFileSync(file, 'utf8'), registry);
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
export function findNpmrcFiles(packageRoot, root) {
|
|
10
|
+
const files = [];
|
|
11
|
+
let current = path.resolve(packageRoot);
|
|
12
|
+
const boundary = path.resolve(root);
|
|
13
|
+
while (true) {
|
|
14
|
+
const file = path.join(current, '.npmrc');
|
|
15
|
+
if (fs.existsSync(file))
|
|
16
|
+
files.push(file);
|
|
17
|
+
if (current === boundary)
|
|
18
|
+
break;
|
|
19
|
+
const parent = path.dirname(current);
|
|
20
|
+
if (parent === current)
|
|
21
|
+
break;
|
|
22
|
+
current = parent;
|
|
23
|
+
}
|
|
24
|
+
return files;
|
|
25
|
+
}
|
|
26
|
+
export function validateNpmrcAuthEnv(packageRoot, root, options = {}) {
|
|
27
|
+
const env = createAvailableAuthEnv(options);
|
|
28
|
+
for (const file of findNpmrcFiles(packageRoot, root)) {
|
|
29
|
+
const missing = findMissingNpmrcEnvVars(fs.readFileSync(file, 'utf8'), env);
|
|
30
|
+
if (!missing.length)
|
|
31
|
+
continue;
|
|
32
|
+
const variable = missing[0];
|
|
33
|
+
throw new Error(`[publish] npmrc auth environment is missing: ${variable}\n` +
|
|
34
|
+
`[publish] file: ${file}\n` +
|
|
35
|
+
`[publish] Set ${variable} before retrying, or use --token with an npmrc entry such as:\n` +
|
|
36
|
+
' //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function hasAuthToken(content, registry) {
|
|
40
|
+
const lines = content
|
|
41
|
+
.split(/\r?\n/)
|
|
42
|
+
.map((line) => line.trim())
|
|
43
|
+
.filter((line) => line && !line.startsWith('#') && !line.startsWith(';'));
|
|
44
|
+
if (!registry)
|
|
45
|
+
return lines.some((line) => line.includes('_authToken'));
|
|
46
|
+
const authKey = `${toNpmrcRegistryKey(registry)}:_authToken`;
|
|
47
|
+
return lines.some((line) => line.startsWith(authKey));
|
|
48
|
+
}
|
|
49
|
+
export function toNpmrcRegistryKey(registry) {
|
|
50
|
+
const url = parseRegistryUrl(registry);
|
|
51
|
+
const pathname = url.pathname.endsWith('/')
|
|
52
|
+
? url.pathname
|
|
53
|
+
: `${url.pathname}/`;
|
|
54
|
+
return `//${url.host}${pathname}`;
|
|
55
|
+
}
|
|
56
|
+
const parseRegistryUrl = (registry) => {
|
|
57
|
+
try {
|
|
58
|
+
return new URL(registry);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw new Error(`[publish] invalid publishConfig.registry: ${registry}`, {
|
|
62
|
+
cause: error,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const findMissingNpmrcEnvVars = (content, env) => {
|
|
67
|
+
return getNpmrcAuthLines(content)
|
|
68
|
+
.flatMap((line) => [...line.matchAll(/\$\{([^}]+)\}/g)])
|
|
69
|
+
.map((match) => match[1])
|
|
70
|
+
.filter((name) => name && !env[name]);
|
|
71
|
+
};
|
|
72
|
+
const getNpmrcAuthLines = (content) => {
|
|
73
|
+
return content
|
|
74
|
+
.split(/\r?\n/)
|
|
75
|
+
.map((line) => line.trim())
|
|
76
|
+
.filter((line) => line &&
|
|
77
|
+
!line.startsWith('#') &&
|
|
78
|
+
!line.startsWith(';') &&
|
|
79
|
+
line.includes('_authToken'));
|
|
80
|
+
};
|
|
81
|
+
const createAvailableAuthEnv = (options) => {
|
|
82
|
+
if (!options.token)
|
|
83
|
+
return process.env;
|
|
84
|
+
return {
|
|
85
|
+
...process.env,
|
|
86
|
+
NODE_AUTH_TOKEN: options.token,
|
|
87
|
+
NPM_TOKEN: options.token,
|
|
88
|
+
};
|
|
89
|
+
};
|
|
@@ -8,23 +8,37 @@ export declare class NpmPackageVersionExistsError extends Error {
|
|
|
8
8
|
constructor(packageName: string, version: string, registry?: string);
|
|
9
9
|
}
|
|
10
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>>;
|
|
11
|
-
export declare function ensurePnpm(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export declare function
|
|
11
|
+
export declare function ensurePnpm(options?: {
|
|
12
|
+
token?: string;
|
|
13
|
+
}): Promise<string>;
|
|
14
|
+
export declare function readPnpmWorkspacePackages(root: string, options?: {
|
|
15
|
+
token?: string;
|
|
16
|
+
}): Promise<WorkspacePackage[]>;
|
|
17
|
+
export declare function runPnpmBuild(packageRoot: string, options?: {
|
|
18
|
+
token?: string;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
export declare function runPnpmPublish(packageRoot: string, args: Array<string>, options?: {
|
|
21
|
+
token?: string;
|
|
22
|
+
}): Promise<void>;
|
|
15
23
|
export declare function runPnpmWhoami(packageRoot: string, options?: {
|
|
16
24
|
packageName?: string;
|
|
17
25
|
registry?: string;
|
|
18
26
|
timeout?: number;
|
|
27
|
+
token?: string;
|
|
19
28
|
}): Promise<string>;
|
|
20
29
|
export declare function hasPublishedPackageVersion(packageRoot: string, packageName: string, version: string, options?: {
|
|
21
30
|
registry?: string;
|
|
22
31
|
timeout?: number;
|
|
32
|
+
token?: string;
|
|
23
33
|
}): Promise<boolean>;
|
|
24
34
|
export declare function runPnpmOwnerAdd(packageName: string, user: string, options: {
|
|
25
35
|
cwd: string;
|
|
26
36
|
otp?: string;
|
|
27
37
|
}): Promise<void>;
|
|
38
|
+
export declare function createPnpmAuthEnv(token?: string): {
|
|
39
|
+
NODE_AUTH_TOKEN: string;
|
|
40
|
+
NPM_TOKEN: string;
|
|
41
|
+
} | undefined;
|
|
28
42
|
export declare function hasNpmAuthChallenge(result: {
|
|
29
43
|
stdout?: unknown;
|
|
30
44
|
stderr?: unknown;
|
|
@@ -50,8 +50,10 @@ export async function withPnpmTimeout(subprocess, timeout) {
|
|
|
50
50
|
subprocess.catch(() => { });
|
|
51
51
|
return result;
|
|
52
52
|
}
|
|
53
|
-
export async function ensurePnpm() {
|
|
54
|
-
const result = await runPnpm(['--version']
|
|
53
|
+
export async function ensurePnpm(options = {}) {
|
|
54
|
+
const result = await runPnpm(['--version'], {
|
|
55
|
+
env: createPnpmAuthEnv(options.token),
|
|
56
|
+
});
|
|
55
57
|
const stdout = String(result.stdout ?? '');
|
|
56
58
|
if (hasFailedPnpmResult(result) || !stdout) {
|
|
57
59
|
throw new Error('[publish] pnpm is required for publishing.\n' +
|
|
@@ -66,9 +68,11 @@ export async function ensurePnpm() {
|
|
|
66
68
|
}
|
|
67
69
|
return version;
|
|
68
70
|
}
|
|
69
|
-
export async function readPnpmWorkspacePackages(root) {
|
|
71
|
+
export async function readPnpmWorkspacePackages(root, options = {}) {
|
|
70
72
|
try {
|
|
71
|
-
return (await readPnpmWorkspacePackageInfo(root
|
|
73
|
+
return (await readPnpmWorkspacePackageInfo(root, {
|
|
74
|
+
env: createPnpmAuthEnv(options.token),
|
|
75
|
+
})).map((item) => {
|
|
72
76
|
if (!isWorkspacePackage(item))
|
|
73
77
|
throwInvalidWorkspacePackages();
|
|
74
78
|
return item;
|
|
@@ -80,19 +84,21 @@ export async function readPnpmWorkspacePackages(root) {
|
|
|
80
84
|
});
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
|
-
export async function runPnpmBuild(packageRoot) {
|
|
87
|
+
export async function runPnpmBuild(packageRoot, options = {}) {
|
|
84
88
|
const result = await runPnpm(['run', 'build'], {
|
|
85
89
|
cwd: packageRoot,
|
|
90
|
+
env: createPnpmAuthEnv(options.token),
|
|
86
91
|
stdio: 'inherit',
|
|
87
92
|
});
|
|
88
93
|
if (hasFailedPnpmResult(result)) {
|
|
89
94
|
throw new Error(`[publish] build failed at ${packageRoot}.`);
|
|
90
95
|
}
|
|
91
96
|
}
|
|
92
|
-
export async function runPnpmPublish(packageRoot, args) {
|
|
97
|
+
export async function runPnpmPublish(packageRoot, args, options = {}) {
|
|
93
98
|
const isDryRun = args.includes('--dry-run');
|
|
94
99
|
const result = await runPnpm(['publish', ...args], {
|
|
95
100
|
cwd: packageRoot,
|
|
101
|
+
env: createPnpmAuthEnv(options.token),
|
|
96
102
|
stdio: isDryRun ? 'pipe' : 'inherit',
|
|
97
103
|
});
|
|
98
104
|
if (isDryRun)
|
|
@@ -110,6 +116,7 @@ export async function runPnpmWhoami(packageRoot, options = {}) {
|
|
|
110
116
|
args.push('--registry', options.registry);
|
|
111
117
|
const result = await runPnpm(args, {
|
|
112
118
|
cwd: packageRoot,
|
|
119
|
+
env: createPnpmAuthEnv(options.token),
|
|
113
120
|
timeout: options.timeout,
|
|
114
121
|
});
|
|
115
122
|
if (hasFailedPnpmResult(result)) {
|
|
@@ -128,6 +135,7 @@ export async function hasPublishedPackageVersion(packageRoot, packageName, versi
|
|
|
128
135
|
args.push('--registry', options.registry);
|
|
129
136
|
const result = await runPnpm(args, {
|
|
130
137
|
cwd: packageRoot,
|
|
138
|
+
env: createPnpmAuthEnv(options.token),
|
|
131
139
|
timeout: options.timeout,
|
|
132
140
|
});
|
|
133
141
|
if (!hasFailedPnpmResult(result)) {
|
|
@@ -151,6 +159,14 @@ export async function runPnpmOwnerAdd(packageName, user, options) {
|
|
|
151
159
|
throw new Error(`[publish] pnpm owner add failed for ${user} -> ${packageName}.`);
|
|
152
160
|
}
|
|
153
161
|
}
|
|
162
|
+
export function createPnpmAuthEnv(token) {
|
|
163
|
+
if (!token)
|
|
164
|
+
return undefined;
|
|
165
|
+
return {
|
|
166
|
+
NODE_AUTH_TOKEN: token,
|
|
167
|
+
NPM_TOKEN: token,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
154
170
|
const isWorkspacePackage = (value) => {
|
|
155
171
|
if (!isPlainObject(value)) {
|
|
156
172
|
return false;
|
|
@@ -2,6 +2,11 @@ import { runPnpmPublish } from '#auklet/publish/api/pnpmApi';
|
|
|
2
2
|
import { createPublishArgs } from '#auklet/publish/api/publishArgs';
|
|
3
3
|
export class PnpmPublishApi {
|
|
4
4
|
async publish(target, options) {
|
|
5
|
-
|
|
5
|
+
const args = createPublishArgs(target, options);
|
|
6
|
+
if (options.token) {
|
|
7
|
+
await runPnpmPublish(target.packageRoot, args, { token: options.token });
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
await runPnpmPublish(target.packageRoot, args);
|
|
6
11
|
}
|
|
7
12
|
}
|
package/dist/publish/cli.d.ts
CHANGED
package/dist/publish/cli.js
CHANGED
|
@@ -2,7 +2,9 @@ import minimist from 'minimist';
|
|
|
2
2
|
import { isArray } from 'aidly';
|
|
3
3
|
import { OwnerRunner } from '#auklet/publish/ownerRunner';
|
|
4
4
|
import { PublishRunner } from '#auklet/publish/publishRunner';
|
|
5
|
+
import { validateNpmrcAuthEnv } from '#auklet/publish/api/npmrc';
|
|
5
6
|
import { ensurePnpm } from '#auklet/publish/api/pnpmApi';
|
|
7
|
+
import { findWorkspaceRoot } from '#auklet/workspace/root';
|
|
6
8
|
const publishFlags = new Set([
|
|
7
9
|
'_',
|
|
8
10
|
'filter',
|
|
@@ -11,13 +13,16 @@ const publishFlags = new Set([
|
|
|
11
13
|
'format',
|
|
12
14
|
'git',
|
|
13
15
|
'otp',
|
|
16
|
+
'token',
|
|
14
17
|
'ignore-scripts',
|
|
15
18
|
'allow-dirty',
|
|
16
19
|
]);
|
|
17
20
|
const ownerFlags = new Set(['_', 'filter', 'package', 'otp']);
|
|
18
21
|
export async function runPublishCli(args) {
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
const options = resolvePublishCliOptions(args);
|
|
23
|
+
validatePublishCliNpmrcAuthEnv(options.cwd, options.token);
|
|
24
|
+
await ensurePnpm({ token: options.token });
|
|
25
|
+
await new PublishRunner(options).run();
|
|
21
26
|
}
|
|
22
27
|
export function resolvePublishCliOptions(args, cwd = process.cwd()) {
|
|
23
28
|
const argv = parsePublishArgs(args);
|
|
@@ -34,13 +39,14 @@ export function resolvePublishCliOptions(args, cwd = process.cwd()) {
|
|
|
34
39
|
dryRun: argv['dry-run'] === true,
|
|
35
40
|
allowDirty: argv['allow-dirty'] === true,
|
|
36
41
|
ignoreScripts: argv['ignore-scripts'] === true,
|
|
42
|
+
token: stringOption(argv.token),
|
|
37
43
|
};
|
|
38
44
|
}
|
|
39
45
|
const parsePublishArgs = (args) => {
|
|
40
46
|
const cliArgs = stripLeadingArgsSeparator(args);
|
|
41
47
|
validateNoPrefixedFlags(cliArgs, new Set(['--no-format', '--no-git']));
|
|
42
48
|
const argv = minimist(cliArgs, {
|
|
43
|
-
string: ['filter', 'version', 'otp'],
|
|
49
|
+
string: ['filter', 'version', 'otp', 'token'],
|
|
44
50
|
boolean: ['dry-run', 'format', 'git', 'ignore-scripts', 'allow-dirty'],
|
|
45
51
|
default: {
|
|
46
52
|
git: true,
|
|
@@ -64,9 +70,11 @@ export async function runOwnerCli(args) {
|
|
|
64
70
|
if (!users.length) {
|
|
65
71
|
throw new Error('[publish] owner add requires at least one user.');
|
|
66
72
|
}
|
|
73
|
+
const cwd = process.cwd();
|
|
74
|
+
validatePublishCliNpmrcAuthEnv(cwd);
|
|
67
75
|
await ensurePnpm();
|
|
68
76
|
await new OwnerRunner({
|
|
69
|
-
cwd
|
|
77
|
+
cwd,
|
|
70
78
|
users,
|
|
71
79
|
filters: toArray(argv.filter),
|
|
72
80
|
packages: toArray(argv.package),
|
|
@@ -103,3 +111,6 @@ const stringOption = (value) => {
|
|
|
103
111
|
return String(value.at(-1));
|
|
104
112
|
return String(value);
|
|
105
113
|
};
|
|
114
|
+
const validatePublishCliNpmrcAuthEnv = (cwd, token) => {
|
|
115
|
+
validateNpmrcAuthEnv(cwd, findWorkspaceRoot(cwd) ?? cwd, { token });
|
|
116
|
+
};
|
package/dist/publish/inspect.js
CHANGED
|
@@ -4,13 +4,18 @@ import { createAukletLogger } from '#auklet/logger';
|
|
|
4
4
|
import { resolvePublishTag } from '#auklet/publish/api/publishArgs';
|
|
5
5
|
import { getPublishRegistry } from '#auklet/publish/api/registry';
|
|
6
6
|
import { ensurePnpm } from '#auklet/publish/api/pnpmApi';
|
|
7
|
+
import { validateNpmrcAuthEnv } from '#auklet/publish/api/npmrc';
|
|
7
8
|
import { resolvePublishCliOptions } from '#auklet/publish/cli';
|
|
9
|
+
import { findWorkspaceRoot } from '#auklet/workspace/root';
|
|
8
10
|
import { inspectPublishRegistry, } from '#auklet/publish/inspectRegistry';
|
|
9
11
|
import { inspectPackageFiles, PackInspectReporter, } from '#auklet/publish/inspectPack';
|
|
10
12
|
import { resolvePublishPlan } from '#auklet/publish/targetResolver';
|
|
11
13
|
export async function runInspectPublishCli(args) {
|
|
12
|
-
await ensurePnpm();
|
|
13
14
|
const options = resolvePublishCliOptions(args);
|
|
15
|
+
validateNpmrcAuthEnv(options.cwd, findWorkspaceRoot(options.cwd) ?? options.cwd, {
|
|
16
|
+
token: options.token,
|
|
17
|
+
});
|
|
18
|
+
await ensurePnpm({ token: options.token });
|
|
14
19
|
const logger = createAukletLogger({ scope: 'inspect' });
|
|
15
20
|
const plan = await resolvePublishPlan(options, logger);
|
|
16
21
|
const packageFileChecks = inspectPackageFiles(plan.targets);
|
|
@@ -22,6 +27,7 @@ export async function runInspectPublishCli(args) {
|
|
|
22
27
|
const spinner = logger.spinner('Checking publish registry');
|
|
23
28
|
spinner.start();
|
|
24
29
|
const registryChecks = await inspectPublishRegistry(plan, {
|
|
30
|
+
token: options.token,
|
|
25
31
|
onCheck: (info) => {
|
|
26
32
|
spinner.text([
|
|
27
33
|
'Checking registry ',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PublishPlan } from '#auklet/publish/types';
|
|
1
|
+
import type { PublishOptions, PublishPlan } from '#auklet/publish/types';
|
|
2
2
|
export type PublishRegistryCheckStatus = 'success' | 'error';
|
|
3
3
|
export type PublishRegistryCheck = {
|
|
4
4
|
packageName: string;
|
|
@@ -17,6 +17,7 @@ export type PublishRegistryRetryInfo = {
|
|
|
17
17
|
};
|
|
18
18
|
export type PublishRegistryCheckInfo = Pick<PublishRegistryRetryInfo, 'packageName' | 'registry' | 'check'>;
|
|
19
19
|
export type InspectPublishRegistryOptions = {
|
|
20
|
+
token?: PublishOptions['token'];
|
|
20
21
|
onCheck?: (info: PublishRegistryCheckInfo) => void;
|
|
21
22
|
onRetry?: (info: PublishRegistryRetryInfo) => void;
|
|
22
23
|
};
|
|
@@ -35,6 +35,7 @@ const checkAuth = async (authResults, authKey, packageRoot, packageName, registr
|
|
|
35
35
|
await retryWithLog(() => runPnpmWhoami(packageRoot, {
|
|
36
36
|
packageName,
|
|
37
37
|
registry,
|
|
38
|
+
token: options.token,
|
|
38
39
|
timeout: registryCheckTimeout,
|
|
39
40
|
}), {
|
|
40
41
|
check: 'auth',
|
|
@@ -60,6 +61,7 @@ const checkVersion = async (packageRoot, packageName, version, registry, options
|
|
|
60
61
|
});
|
|
61
62
|
const exists = await retryWithLog(() => hasPublishedPackageVersion(packageRoot, packageName, version, {
|
|
62
63
|
registry,
|
|
64
|
+
token: options.token,
|
|
63
65
|
timeout: registryCheckTimeout,
|
|
64
66
|
}), {
|
|
65
67
|
check: 'version',
|
|
@@ -36,7 +36,7 @@ export class PublishRunner {
|
|
|
36
36
|
await runPublishHook({ status: 'beforeBuild', plan });
|
|
37
37
|
failureHookEnabled = true;
|
|
38
38
|
this.versions.writeBeforeBuild(plan);
|
|
39
|
-
await runPackageBuilds(plan.targets, this.logger);
|
|
39
|
+
await runPackageBuilds(plan.targets, this.logger, this.options);
|
|
40
40
|
await runPublishHook({ status: 'afterBuild', plan });
|
|
41
41
|
await formatPublishOutputs(plan.targets, this.options.format);
|
|
42
42
|
await runPublishHook({ status: 'beforePublish', plan });
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PublishTarget } from '#auklet/publish/types';
|
|
2
2
|
import type { AukletLogger } from '#auklet/logger';
|
|
3
|
+
import type { PublishOptions } from '#auklet/publish/types';
|
|
3
4
|
export declare function validateBuildScript(targets: Array<PublishTarget>): void;
|
|
4
|
-
export declare function runPackageBuilds(targets: Array<PublishTarget>, logger: AukletLogger): Promise<void>;
|
|
5
|
+
export declare function runPackageBuilds(targets: Array<PublishTarget>, logger: AukletLogger, options?: Pick<PublishOptions, 'token'>): Promise<void>;
|
|
@@ -8,9 +8,13 @@ export function validateBuildScript(targets) {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
-
export async function runPackageBuilds(targets, logger) {
|
|
11
|
+
export async function runPackageBuilds(targets, logger, options = {}) {
|
|
12
12
|
for (const target of targets) {
|
|
13
13
|
logger.step('build ', logger.package(target.packageName));
|
|
14
|
+
if (options.token) {
|
|
15
|
+
await runPnpmBuild(target.packageRoot, { token: options.token });
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
14
18
|
await runPnpmBuild(target.packageRoot);
|
|
15
19
|
}
|
|
16
20
|
}
|
|
@@ -7,6 +7,8 @@ export declare class PublishPreflight {
|
|
|
7
7
|
constructor(options: PublishOptions, logger: AukletLogger);
|
|
8
8
|
run(plan: PublishPlan): Promise<void>;
|
|
9
9
|
verifyBeforeBuild(plan: PublishPlan): Promise<void>;
|
|
10
|
+
private verifyNpmrcAuthEnv;
|
|
11
|
+
private verifyTokenConfig;
|
|
10
12
|
private verifyAuthentication;
|
|
11
13
|
private verifyPnpmPublishDryRun;
|
|
12
14
|
private verifyPackageVersions;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PnpmPublishApi } from '#auklet/publish/api/pnpmPublishApi';
|
|
2
2
|
import { hasPublishedPackageVersion, NpmPackageVersionExistsError, runPnpmWhoami, } from '#auklet/publish/api/pnpmApi';
|
|
3
|
+
import { findNpmrcFiles, findNpmrcWithAuthToken, toNpmrcRegistryKey, validateNpmrcAuthEnv, } from '#auklet/publish/api/npmrc';
|
|
3
4
|
import { getPublishRegistry } from '#auklet/publish/api/registry';
|
|
4
5
|
import { logAuthenticationError } from '#auklet/publish/runner/packagePublisher';
|
|
5
6
|
import { PublishTargetError } from '#auklet/publish/runner/publishTargetError';
|
|
@@ -15,11 +16,31 @@ export class PublishPreflight {
|
|
|
15
16
|
await this.verifyPnpmPublishDryRun(plan);
|
|
16
17
|
}
|
|
17
18
|
async verifyBeforeBuild(plan) {
|
|
19
|
+
this.verifyNpmrcAuthEnv(plan);
|
|
20
|
+
this.verifyTokenConfig(plan);
|
|
18
21
|
if (plan.dryRun)
|
|
19
22
|
return;
|
|
20
23
|
await this.verifyAuthentication(plan);
|
|
21
24
|
await this.verifyPackageVersions(plan);
|
|
22
25
|
}
|
|
26
|
+
verifyNpmrcAuthEnv(plan) {
|
|
27
|
+
for (const target of plan.targets) {
|
|
28
|
+
validateNpmrcAuthEnv(target.packageRoot, plan.root, {
|
|
29
|
+
token: this.options.token,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
verifyTokenConfig(plan) {
|
|
34
|
+
if (!this.options.token)
|
|
35
|
+
return;
|
|
36
|
+
for (const target of plan.targets) {
|
|
37
|
+
const registry = getPublishRegistry(target.packageJson.publishConfig);
|
|
38
|
+
const npmrc = findNpmrcWithAuthToken(target.packageRoot, plan.root, registry);
|
|
39
|
+
if (npmrc)
|
|
40
|
+
continue;
|
|
41
|
+
throw new PublishTargetError(target, 'preflight', new Error(createMissingNpmrcAuthMessage(target, plan.root, registry)), []);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
23
44
|
async verifyAuthentication(plan) {
|
|
24
45
|
const checked = new Set();
|
|
25
46
|
for (const target of plan.targets) {
|
|
@@ -30,6 +51,7 @@ export class PublishPreflight {
|
|
|
30
51
|
await runPnpmWhoami(target.packageRoot, {
|
|
31
52
|
packageName: target.packageName,
|
|
32
53
|
registry,
|
|
54
|
+
token: this.options.token,
|
|
33
55
|
});
|
|
34
56
|
checked.add(key);
|
|
35
57
|
}
|
|
@@ -52,7 +74,7 @@ export class PublishPreflight {
|
|
|
52
74
|
async verifyPackageVersions(plan) {
|
|
53
75
|
for (const target of plan.targets) {
|
|
54
76
|
const registry = getPublishRegistry(target.packageJson.publishConfig);
|
|
55
|
-
const exists = await hasPublishedPackageVersion(target.packageRoot, target.packageName, target.publishVersion, { registry });
|
|
77
|
+
const exists = await hasPublishedPackageVersion(target.packageRoot, target.packageName, target.publishVersion, { registry, token: this.options.token });
|
|
56
78
|
if (!exists)
|
|
57
79
|
continue;
|
|
58
80
|
this.logExistingVersion(target, registry);
|
|
@@ -66,3 +88,20 @@ export class PublishPreflight {
|
|
|
66
88
|
}
|
|
67
89
|
}
|
|
68
90
|
}
|
|
91
|
+
function createMissingNpmrcAuthMessage(target, root, registry) {
|
|
92
|
+
const npmrcFiles = findNpmrcFiles(target.packageRoot, root);
|
|
93
|
+
const authTarget = registry
|
|
94
|
+
? `${toNpmrcRegistryKey(registry)}:_authToken`
|
|
95
|
+
: '_authToken';
|
|
96
|
+
const registryHint = registry
|
|
97
|
+
? `[publish] ${target.packageName} uses publishConfig.registry: ${registry}.\n`
|
|
98
|
+
: '';
|
|
99
|
+
const location = npmrcFiles.length
|
|
100
|
+
? 'found npmrc files, but none declares'
|
|
101
|
+
: 'could not find an npmrc file declaring';
|
|
102
|
+
return (`[publish] --token requires npmrc auth config for ${target.packageName}.\n` +
|
|
103
|
+
registryHint +
|
|
104
|
+
`[publish] ${location} ${authTarget}.\n` +
|
|
105
|
+
'[publish] Add an npmrc entry such as:\n' +
|
|
106
|
+
` ${authTarget}=\${NODE_AUTH_TOKEN}`);
|
|
107
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type AukletLogger } from '#auklet/logger';
|
|
2
2
|
import type { OwnerOptions, PublishOptions, PublishPlan } from '#auklet/publish/types';
|
|
3
|
-
type ResolvePublishTargetsOptions = Pick<PublishOptions, 'cwd' | 'filters' | 'version' | 'dryRun'>;
|
|
3
|
+
type ResolvePublishTargetsOptions = Pick<PublishOptions, 'cwd' | 'filters' | 'version' | 'dryRun' | 'token'>;
|
|
4
4
|
type ResolveOwnerTargetsOptions = Pick<OwnerOptions, 'cwd' | 'filters' | 'packages'>;
|
|
5
5
|
export declare function resolvePublishPlan(options: ResolvePublishTargetsOptions, logger?: AukletLogger): Promise<PublishPlan>;
|
|
6
6
|
export declare function resolveOwnerPackageNames(options: ResolveOwnerTargetsOptions): Promise<string[]>;
|
|
@@ -59,7 +59,9 @@ const resolveMonorepoPublishPlan = async (options, logger) => {
|
|
|
59
59
|
const root = requireWorkspaceRoot(options.cwd);
|
|
60
60
|
const rootPackageJson = readPackageJson(root);
|
|
61
61
|
const rootVersion = requirePackageVersion(root, rootPackageJson);
|
|
62
|
-
const workspacePackages = await readPnpmWorkspacePackages(root
|
|
62
|
+
const workspacePackages = await readPnpmWorkspacePackages(root, {
|
|
63
|
+
token: options.token,
|
|
64
|
+
});
|
|
63
65
|
const selectedPackages = filterWorkspacePackages(workspacePackages, options.filters);
|
|
64
66
|
const targets = selectedPackages
|
|
65
67
|
.filter((item) => {
|
package/dist/publish/types.d.ts
CHANGED