auklet 0.1.4 → 0.1.6
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 +116 -429
- package/dist/cli/build.d.ts +3 -5
- package/dist/cli/build.js +86 -23
- package/dist/cli/buildCss.d.ts +10 -5
- package/dist/cli/buildCss.js +21 -17
- package/dist/cli/buildWorkspace.d.ts +24 -0
- package/dist/cli/buildWorkspace.js +43 -0
- package/dist/cli/dev.d.ts +2 -1
- package/dist/cli/dev.js +130 -23
- package/dist/cli/main.js +167 -26
- package/dist/cli/parse/build.d.ts +63 -0
- package/dist/cli/{buildArgs.js → parse/build.js} +47 -22
- package/dist/cli/parse/core.d.ts +14 -0
- package/dist/cli/parse/core.js +68 -0
- package/dist/cli/parse/dev.d.ts +18 -0
- package/dist/cli/parse/dev.js +4 -0
- package/dist/cli/parse/owner.d.ts +11 -0
- package/dist/cli/parse/owner.js +25 -0
- package/dist/cli/parse/publish.d.ts +19 -0
- package/dist/cli/parse/publish.js +60 -0
- package/dist/cli/parse/workspace.d.ts +14 -0
- package/dist/cli/parse/workspace.js +60 -0
- package/dist/css/inspect.js +4 -3
- package/dist/publish/api/pnpmApi.d.ts +0 -4
- package/dist/publish/api/pnpmApi.js +0 -34
- package/dist/publish/cli.d.ts +0 -16
- package/dist/publish/cli.js +5 -122
- package/dist/publish/inspect.js +2 -2
- package/dist/publish/targetResolver.js +28 -72
- package/dist/publish/types.d.ts +1 -7
- package/dist/workspace/targets.d.ts +31 -0
- package/dist/workspace/targets.js +144 -0
- package/package.json +1 -1
- package/dist/cli/buildArgs.d.ts +0 -9
- package/dist/cli/publish.d.ts +0 -2
- package/dist/cli/publish.js +0 -9
- /package/dist/cli/{values.d.ts → parse/values.d.ts} +0 -0
- /package/dist/cli/{values.js → parse/values.js} +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { resolveCliBoolean, resolveCliValue } from '#auklet/cli/parse/values';
|
|
2
|
+
import { dedupe, readFlagValue, readOptionalFlagValue, } from '#auklet/cli/parse/core';
|
|
3
|
+
export function parseWorkspaceSelectionArgs(args, envContext) {
|
|
4
|
+
const filters = [];
|
|
5
|
+
const remainingArgs = [];
|
|
6
|
+
let includePrivate = false;
|
|
7
|
+
let includeDependencies = false;
|
|
8
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
9
|
+
const arg = args[index];
|
|
10
|
+
const [name, inlineValue] = arg.split('=', 2);
|
|
11
|
+
if (name === '--workspace') {
|
|
12
|
+
if (inlineValue !== undefined) {
|
|
13
|
+
throw new Error('--workspace does not accept a value.');
|
|
14
|
+
}
|
|
15
|
+
filters.push('*');
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (name === '--filter') {
|
|
19
|
+
filters.push(resolveCliValue(readFlagValue(args, index, inlineValue, name), {
|
|
20
|
+
label: name,
|
|
21
|
+
context: envContext,
|
|
22
|
+
}));
|
|
23
|
+
if (inlineValue === undefined)
|
|
24
|
+
index += 1;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (name === '--deps') {
|
|
28
|
+
const result = readWorkspaceBooleanFlag(args, index, inlineValue, name, envContext);
|
|
29
|
+
includeDependencies = result.value;
|
|
30
|
+
if (result.consumedNext)
|
|
31
|
+
index += 1;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (name === '--private') {
|
|
35
|
+
const result = readWorkspaceBooleanFlag(args, index, inlineValue, name, envContext);
|
|
36
|
+
includePrivate = result.value;
|
|
37
|
+
if (result.consumedNext)
|
|
38
|
+
index += 1;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
remainingArgs.push(arg);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
remainingArgs,
|
|
45
|
+
workspace: {
|
|
46
|
+
filters: dedupe(filters),
|
|
47
|
+
includeDependencies,
|
|
48
|
+
includePrivate,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const readWorkspaceBooleanFlag = (args, index, inlineValue, name, envContext) => {
|
|
53
|
+
const value = readOptionalFlagValue(args, index, inlineValue);
|
|
54
|
+
return {
|
|
55
|
+
consumedNext: inlineValue === undefined && value !== undefined,
|
|
56
|
+
value: value === undefined
|
|
57
|
+
? true
|
|
58
|
+
: resolveCliBoolean(value, { label: name, context: envContext }),
|
|
59
|
+
};
|
|
60
|
+
};
|
package/dist/css/inspect.js
CHANGED
|
@@ -3,7 +3,8 @@ import { readFileSync } from 'node:fs';
|
|
|
3
3
|
import { isPlainObject, isString } from 'aidly';
|
|
4
4
|
import { normalizeAukletConfig } from '#auklet/config';
|
|
5
5
|
import { loadAukletConfig } from '#auklet/configLoader';
|
|
6
|
-
import {
|
|
6
|
+
import { parseBuildOverrideArgs } from '#auklet/cli/parse/build';
|
|
7
|
+
import { AukletEnvContext } from '#auklet/env';
|
|
7
8
|
import { moduleStyleBuildConfig } from '#auklet/css/config';
|
|
8
9
|
import { mergeAukletConfigOverrides } from '#auklet/build/cliOverrides';
|
|
9
10
|
import { createExternalEntryParts, createModuleStyleEntryPlans, createStyleEntryParts, createThemeEntryParts, } from '#auklet/css/core/style/entries';
|
|
@@ -20,11 +21,11 @@ export async function runInspectCssCli(args) {
|
|
|
20
21
|
return 0;
|
|
21
22
|
}
|
|
22
23
|
export async function resolveInspectCssOptions(args) {
|
|
23
|
-
const
|
|
24
|
+
const cwd = process.cwd();
|
|
25
|
+
const buildArgs = parseBuildOverrideArgs(args.filter((arg) => arg !== '--'), new AukletEnvContext(cwd));
|
|
24
26
|
if (buildArgs.args.length) {
|
|
25
27
|
throw new Error(`[inspect] unknown inspect css argument: ${buildArgs.args[0]}`);
|
|
26
28
|
}
|
|
27
|
-
const cwd = process.cwd();
|
|
28
29
|
const workspaceRoot = findWorkspaceRoot(cwd);
|
|
29
30
|
const packageRoots = workspaceRoot === cwd
|
|
30
31
|
? (await readPnpmWorkspacePackageInfo(cwd))
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { execa, type Options } from 'execa';
|
|
2
|
-
import type { WorkspacePackage } from '#auklet/publish/types';
|
|
3
2
|
export declare class NpmPublishAuthenticationError extends Error {
|
|
4
3
|
readonly packageRoot: string;
|
|
5
4
|
constructor(packageRoot: string);
|
|
@@ -11,9 +10,6 @@ export declare function withPnpmTimeout(subprocess: ReturnType<typeof execa>, ti
|
|
|
11
10
|
export declare function ensurePnpm(options?: {
|
|
12
11
|
env?: Record<string, string | undefined>;
|
|
13
12
|
}): Promise<string>;
|
|
14
|
-
export declare function readPnpmWorkspacePackages(root: string, options?: {
|
|
15
|
-
env?: Record<string, string | undefined>;
|
|
16
|
-
}): Promise<WorkspacePackage[]>;
|
|
17
13
|
export declare function runPnpmBuild(packageRoot: string, options?: {
|
|
18
14
|
env?: Record<string, string | undefined>;
|
|
19
15
|
}): Promise<void>;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { isPlainObject, isString } from 'aidly';
|
|
2
1
|
import { execa } from 'execa';
|
|
3
2
|
import semver from 'semver';
|
|
4
|
-
import { readPnpmWorkspacePackageInfo } from '#auklet/workspace/packages';
|
|
5
3
|
const supportedPnpmRange = '>=10.0.0';
|
|
6
4
|
export class NpmPublishAuthenticationError extends Error {
|
|
7
5
|
packageRoot;
|
|
@@ -68,22 +66,6 @@ export async function ensurePnpm(options = {}) {
|
|
|
68
66
|
}
|
|
69
67
|
return version;
|
|
70
68
|
}
|
|
71
|
-
export async function readPnpmWorkspacePackages(root, options = {}) {
|
|
72
|
-
try {
|
|
73
|
-
return (await readPnpmWorkspacePackageInfo(root, {
|
|
74
|
-
env: options.env,
|
|
75
|
-
})).map((item) => {
|
|
76
|
-
if (!isWorkspacePackage(item))
|
|
77
|
-
throwInvalidWorkspacePackages();
|
|
78
|
-
return item;
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
throw new Error('[publish] failed to read pnpm workspace packages.', {
|
|
83
|
-
cause: error,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
69
|
export async function runPnpmBuild(packageRoot, options = {}) {
|
|
88
70
|
const result = await runPnpm(['run', 'build'], {
|
|
89
71
|
cwd: packageRoot,
|
|
@@ -159,18 +141,6 @@ export async function runPnpmOwnerAdd(packageName, user, options) {
|
|
|
159
141
|
throw new Error(`[publish] pnpm owner add failed for ${user} -> ${packageName}.`);
|
|
160
142
|
}
|
|
161
143
|
}
|
|
162
|
-
const isWorkspacePackage = (value) => {
|
|
163
|
-
if (!isPlainObject(value)) {
|
|
164
|
-
return false;
|
|
165
|
-
}
|
|
166
|
-
return (isString(value.name) &&
|
|
167
|
-
value.name.length > 0 &&
|
|
168
|
-
isString(value.path) &&
|
|
169
|
-
value.path.length > 0 &&
|
|
170
|
-
isString(value.version) &&
|
|
171
|
-
value.version.length > 0 &&
|
|
172
|
-
(value.private === undefined || typeof value.private === 'boolean'));
|
|
173
|
-
};
|
|
174
144
|
const hasFailedPnpmResult = (result) => {
|
|
175
145
|
return result.failed === true || result.exitCode !== 0;
|
|
176
146
|
};
|
|
@@ -181,10 +151,6 @@ const getPnpmFailureReason = (result) => {
|
|
|
181
151
|
const stdout = String(result.stdout ?? '').trim();
|
|
182
152
|
return stdout || null;
|
|
183
153
|
};
|
|
184
|
-
function throwInvalidWorkspacePackages() {
|
|
185
|
-
throw new Error('[publish] failed to read pnpm workspace packages.\n' +
|
|
186
|
-
'[publish] Expected `pnpm list -r --depth -1 --json` to return package objects with name/path/version.');
|
|
187
|
-
}
|
|
188
154
|
export function hasNpmAuthChallenge(result) {
|
|
189
155
|
const output = [result.stdout, result.stderr]
|
|
190
156
|
.map((value) => String(value ?? ''))
|
package/dist/publish/cli.d.ts
CHANGED
|
@@ -1,18 +1,2 @@
|
|
|
1
|
-
import { AukletEnvContext } from '#auklet/env';
|
|
2
1
|
export declare function runPublishCli(args: Array<string>): Promise<void>;
|
|
3
|
-
export declare function resolvePublishCliOptions(args: Array<string>, cwd?: string, envContext?: AukletEnvContext): {
|
|
4
|
-
cwd: string;
|
|
5
|
-
otp: string | undefined;
|
|
6
|
-
filters: string[];
|
|
7
|
-
version: string | undefined;
|
|
8
|
-
git: boolean;
|
|
9
|
-
format: boolean;
|
|
10
|
-
dryRun: boolean;
|
|
11
|
-
allowDirty: boolean;
|
|
12
|
-
ignoreScripts: boolean;
|
|
13
|
-
token: {
|
|
14
|
-
raw: string;
|
|
15
|
-
resolve(context: AukletEnvContext): string | undefined;
|
|
16
|
-
} | undefined;
|
|
17
|
-
};
|
|
18
2
|
export declare function runOwnerCli(args: Array<string>): Promise<void>;
|
package/dist/publish/cli.js
CHANGED
|
@@ -1,154 +1,37 @@
|
|
|
1
|
-
import minimist from 'minimist';
|
|
2
|
-
import { isArray } from 'aidly';
|
|
3
1
|
import { AukletEnvContext } from '#auklet/env';
|
|
4
2
|
import { ensurePnpm } from '#auklet/publish/api/pnpmApi';
|
|
5
3
|
import { OwnerRunner } from '#auklet/publish/ownerRunner';
|
|
6
4
|
import { PublishRunner } from '#auklet/publish/publishRunner';
|
|
7
5
|
import { validateNpmrcAuthEnv } from '#auklet/publish/api/npmrc';
|
|
8
|
-
import { resolveCliBoolean, resolveCliValue, createDeferredCliValue, } from '#auklet/cli/values';
|
|
9
6
|
import { createPublishRootEnv } from '#auklet/publish/publishEnv';
|
|
10
7
|
import { findWorkspaceRoot } from '#auklet/workspace/root';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
'filter',
|
|
14
|
-
'version',
|
|
15
|
-
'dry-run',
|
|
16
|
-
'format',
|
|
17
|
-
'git',
|
|
18
|
-
'otp',
|
|
19
|
-
'token',
|
|
20
|
-
'ignore-scripts',
|
|
21
|
-
'allow-dirty',
|
|
22
|
-
]);
|
|
23
|
-
const ownerFlags = new Set(['_', 'filter', 'package', 'otp']);
|
|
8
|
+
import { parseOwnerCommand } from '#auklet/cli/parse/owner';
|
|
9
|
+
import { parsePublishCommand } from '#auklet/cli/parse/publish';
|
|
24
10
|
export async function runPublishCli(args) {
|
|
25
11
|
const cwd = process.cwd();
|
|
26
12
|
const root = findWorkspaceRoot(cwd) ?? cwd;
|
|
27
13
|
const envContext = new AukletEnvContext(cwd, root);
|
|
28
14
|
await envContext.run(async () => {
|
|
29
15
|
const runtime = { envContext };
|
|
30
|
-
const options =
|
|
16
|
+
const options = parsePublishCommand(args, { cwd, envContext });
|
|
31
17
|
const { env } = createPublishRootEnv(options, runtime);
|
|
32
18
|
validatePublishCliNpmrcAuthEnv(options.cwd, env);
|
|
33
19
|
await ensurePnpm({ env });
|
|
34
20
|
await new PublishRunner(options, runtime).run();
|
|
35
21
|
});
|
|
36
22
|
}
|
|
37
|
-
export function resolvePublishCliOptions(args, cwd = process.cwd(), envContext = new AukletEnvContext(cwd)) {
|
|
38
|
-
const argv = parsePublishArgs(args);
|
|
39
|
-
if (argv._.length) {
|
|
40
|
-
throw new Error(`[publish] unknown publish argument: ${argv._.join(' ')}`);
|
|
41
|
-
}
|
|
42
|
-
return {
|
|
43
|
-
cwd,
|
|
44
|
-
otp: stringOption(argv.otp, '--otp', envContext),
|
|
45
|
-
filters: toArray(argv.filter, '--filter', envContext),
|
|
46
|
-
version: stringOption(argv.version, '--version', envContext),
|
|
47
|
-
git: booleanOption(argv.git, '--git', envContext, true),
|
|
48
|
-
format: booleanOption(argv.format, '--format', envContext, true),
|
|
49
|
-
dryRun: booleanOption(argv['dry-run'], '--dry-run', envContext),
|
|
50
|
-
allowDirty: booleanOption(argv['allow-dirty'], '--allow-dirty', envContext),
|
|
51
|
-
ignoreScripts: booleanOption(argv['ignore-scripts'], '--ignore-scripts', envContext),
|
|
52
|
-
token: deferredStringOption(argv.token, '--token'),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
const parsePublishArgs = (args) => {
|
|
56
|
-
const cliArgs = stripLeadingArgsSeparator(args);
|
|
57
|
-
validateNoPrefixedFlags(cliArgs, new Set(['--no-format', '--no-git']));
|
|
58
|
-
const argv = minimist(cliArgs, {
|
|
59
|
-
string: [
|
|
60
|
-
'filter',
|
|
61
|
-
'version',
|
|
62
|
-
'otp',
|
|
63
|
-
'token',
|
|
64
|
-
'dry-run',
|
|
65
|
-
'format',
|
|
66
|
-
'git',
|
|
67
|
-
'ignore-scripts',
|
|
68
|
-
'allow-dirty',
|
|
69
|
-
],
|
|
70
|
-
});
|
|
71
|
-
validateFlags(argv, publishFlags);
|
|
72
|
-
return argv;
|
|
73
|
-
};
|
|
74
23
|
export async function runOwnerCli(args) {
|
|
75
24
|
const cwd = process.cwd();
|
|
76
25
|
const root = findWorkspaceRoot(cwd) ?? cwd;
|
|
77
26
|
const envContext = new AukletEnvContext(cwd, root);
|
|
78
27
|
await envContext.run(async () => {
|
|
79
|
-
const
|
|
80
|
-
validateNoPrefixedFlags(cliArgs, new Set());
|
|
81
|
-
const argv = minimist(cliArgs, {
|
|
82
|
-
string: ['filter', 'package', 'otp'],
|
|
83
|
-
});
|
|
84
|
-
validateFlags(argv, ownerFlags);
|
|
85
|
-
const [subcommand, ...users] = argv._;
|
|
86
|
-
if (subcommand !== 'add') {
|
|
87
|
-
throw new Error('[publish] expected owner command: auk owner add <user...>');
|
|
88
|
-
}
|
|
89
|
-
if (!users.length) {
|
|
90
|
-
throw new Error('[publish] owner add requires at least one user.');
|
|
91
|
-
}
|
|
28
|
+
const options = parseOwnerCommand(args, { cwd, envContext });
|
|
92
29
|
const env = envContext.values;
|
|
93
30
|
validatePublishCliNpmrcAuthEnv(cwd, env);
|
|
94
31
|
await ensurePnpm({ env: envContext.normalizedValues });
|
|
95
|
-
await new OwnerRunner(
|
|
96
|
-
cwd,
|
|
97
|
-
users,
|
|
98
|
-
filters: toArray(argv.filter, '--filter', envContext),
|
|
99
|
-
packages: toArray(argv.package, '--package', envContext),
|
|
100
|
-
otp: stringOption(argv.otp, '--otp', envContext),
|
|
101
|
-
}).run();
|
|
32
|
+
await new OwnerRunner(options).run();
|
|
102
33
|
});
|
|
103
34
|
}
|
|
104
|
-
const validateFlags = (argv, allowedFlags) => {
|
|
105
|
-
for (const flag of Object.keys(argv)) {
|
|
106
|
-
if (!allowedFlags.has(flag)) {
|
|
107
|
-
throw new Error(`[publish] unknown option: --${flag}`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
const validateNoPrefixedFlags = (args, allowedFlags) => {
|
|
112
|
-
const flag = args.find((arg) => arg.startsWith('--no-') && !allowedFlags.has(arg));
|
|
113
|
-
if (flag) {
|
|
114
|
-
throw new Error(`[publish] unknown option: ${flag}`);
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
const stripLeadingArgsSeparator = (args) => {
|
|
118
|
-
return args.filter((arg) => arg !== '--');
|
|
119
|
-
};
|
|
120
|
-
const toArray = (value, label, envContext) => {
|
|
121
|
-
if (value === undefined)
|
|
122
|
-
return [];
|
|
123
|
-
const values = isArray(value)
|
|
124
|
-
? value.map((item) => stringOption(item, label, envContext)).filter(Boolean)
|
|
125
|
-
: [stringOption(value, label, envContext)].filter(Boolean);
|
|
126
|
-
return values.filter((item) => Boolean(item));
|
|
127
|
-
};
|
|
128
|
-
const stringOption = (value, label, envContext) => {
|
|
129
|
-
if (value === undefined)
|
|
130
|
-
return undefined;
|
|
131
|
-
if (isArray(value))
|
|
132
|
-
return stringOption(value.at(-1), label, envContext);
|
|
133
|
-
return resolveCliValue(String(value), { label, context: envContext });
|
|
134
|
-
};
|
|
135
|
-
const deferredStringOption = (value, label) => {
|
|
136
|
-
if (value === undefined)
|
|
137
|
-
return undefined;
|
|
138
|
-
if (isArray(value))
|
|
139
|
-
return deferredStringOption(value.at(-1), label);
|
|
140
|
-
return createDeferredCliValue(String(value), { label });
|
|
141
|
-
};
|
|
142
|
-
const booleanOption = (value, label, envContext, defaultValue = false) => {
|
|
143
|
-
if (value === undefined)
|
|
144
|
-
return defaultValue;
|
|
145
|
-
if (isArray(value)) {
|
|
146
|
-
return booleanOption(value.at(-1), label, envContext, defaultValue);
|
|
147
|
-
}
|
|
148
|
-
if (typeof value === 'boolean')
|
|
149
|
-
return value;
|
|
150
|
-
return resolveCliBoolean(String(value), { label, context: envContext });
|
|
151
|
-
};
|
|
152
35
|
const validatePublishCliNpmrcAuthEnv = (cwd, env) => {
|
|
153
36
|
validateNpmrcAuthEnv(cwd, findWorkspaceRoot(cwd) ?? cwd, { env });
|
|
154
37
|
};
|
package/dist/publish/inspect.js
CHANGED
|
@@ -6,7 +6,7 @@ import { findWorkspaceRoot } from '#auklet/workspace/root';
|
|
|
6
6
|
import { ensurePnpm } from '#auklet/publish/api/pnpmApi';
|
|
7
7
|
import { getPublishRegistry } from '#auklet/publish/api/registry';
|
|
8
8
|
import { resolvePublishTag } from '#auklet/publish/api/publishArgs';
|
|
9
|
-
import {
|
|
9
|
+
import { parsePublishCommand } from '#auklet/cli/parse/publish';
|
|
10
10
|
import { validateNpmrcAuthEnv } from '#auklet/publish/api/npmrc';
|
|
11
11
|
import { createPublishRootEnv } from '#auklet/publish/publishEnv';
|
|
12
12
|
import { inspectPublishRegistry, } from '#auklet/publish/inspectRegistry';
|
|
@@ -17,7 +17,7 @@ export async function runInspectPublishCli(args) {
|
|
|
17
17
|
const root = findWorkspaceRoot(cwd) ?? cwd;
|
|
18
18
|
const envContext = new AukletEnvContext(cwd, root);
|
|
19
19
|
return envContext.run(async () => {
|
|
20
|
-
const options =
|
|
20
|
+
const options = parsePublishCommand(args, { cwd, envContext });
|
|
21
21
|
return runInspectPublish(options, root, { envContext });
|
|
22
22
|
});
|
|
23
23
|
}
|
|
@@ -3,8 +3,8 @@ import semver from 'semver';
|
|
|
3
3
|
import { findWorkspaceRoot } from '#auklet/workspace/root';
|
|
4
4
|
import { createPublishRootEnv } from '#auklet/publish/publishEnv';
|
|
5
5
|
import { createAukletLogger } from '#auklet/logger';
|
|
6
|
+
import { resolveWorkspacePackageInfos, resolveWorkspaceTargets, } from '#auklet/workspace/targets';
|
|
6
7
|
import { getPublishConfig, readPackageJson, requirePackageName, requirePackageVersion, } from '#auklet/publish/api/packageJsonApi';
|
|
7
|
-
import { readPnpmWorkspacePackages } from '#auklet/publish/api/pnpmApi';
|
|
8
8
|
import { resolvePublishVersion, validateVersionConsistency, } from '#auklet/publish/version';
|
|
9
9
|
export async function resolvePublishPlan(options, runtime, logger = createAukletLogger({ scope: 'publish' })) {
|
|
10
10
|
if (options.filters.length) {
|
|
@@ -18,13 +18,15 @@ export async function resolveOwnerPackageNames(options) {
|
|
|
18
18
|
}
|
|
19
19
|
if (options.filters.length) {
|
|
20
20
|
const root = requireWorkspaceRoot(options.cwd);
|
|
21
|
-
const packages = await
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const packages = await resolveWorkspacePackageInfos(root, options.filters, {
|
|
22
|
+
scope: 'publish',
|
|
23
|
+
readErrorMessage: publishWorkspaceReadErrorMessage,
|
|
24
|
+
});
|
|
25
|
+
return packages.filter((item) => !item.private).map((item) => item.name);
|
|
25
26
|
}
|
|
26
|
-
if (options.packages.length)
|
|
27
|
+
if (options.packages.length) {
|
|
27
28
|
return [...new Set(options.packages)];
|
|
29
|
+
}
|
|
28
30
|
const packageJson = readPackageJson(options.cwd);
|
|
29
31
|
if (packageJson.private) {
|
|
30
32
|
throw new Error('[publish] current package is private.');
|
|
@@ -63,27 +65,26 @@ const resolveMonorepoPublishPlan = async (options, runtime, logger) => {
|
|
|
63
65
|
const { env } = createPublishRootEnv({
|
|
64
66
|
token: options.token,
|
|
65
67
|
}, runtime);
|
|
66
|
-
const
|
|
68
|
+
const targets = await resolveWorkspaceTargets({
|
|
67
69
|
env,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
return false;
|
|
78
|
-
})
|
|
79
|
-
.map((item) => {
|
|
80
|
-
const packageJson = readPackageJson(item.path);
|
|
81
|
-
return createPublishTarget({
|
|
70
|
+
cwd: root,
|
|
71
|
+
scope: 'publish',
|
|
72
|
+
readErrorMessage: publishWorkspaceReadErrorMessage,
|
|
73
|
+
readPackageJson,
|
|
74
|
+
filters: options.filters,
|
|
75
|
+
getDependencies: getWorkspaceDependencies,
|
|
76
|
+
emptyTargetMessage: '[publish] no publishable package found.',
|
|
77
|
+
createTarget: (item, packageJson) => createPublishTarget({
|
|
82
78
|
packageRoot: item.path,
|
|
83
79
|
packageJson,
|
|
84
80
|
publishVersion: '',
|
|
85
81
|
workspaceMode: 'monorepo',
|
|
86
|
-
})
|
|
82
|
+
}),
|
|
83
|
+
onPrivatePackage: (item, context) => {
|
|
84
|
+
if (context.exact) {
|
|
85
|
+
logger.warnOnce('package ', logger.package(item.name), ' is private, skipping.');
|
|
86
|
+
}
|
|
87
|
+
},
|
|
87
88
|
});
|
|
88
89
|
const versionBase = getMonorepoVersionBase(rootVersion, targets);
|
|
89
90
|
const publishVersion = await resolvePublishVersion(versionBase, options.version, root);
|
|
@@ -100,7 +101,7 @@ const resolveMonorepoPublishPlan = async (options, runtime, logger) => {
|
|
|
100
101
|
root,
|
|
101
102
|
version: publishVersion,
|
|
102
103
|
dryRun: options.dryRun,
|
|
103
|
-
targets:
|
|
104
|
+
targets: publishTargets,
|
|
104
105
|
config: getPublishConfig(rootPackageJson),
|
|
105
106
|
workspaceMode: 'monorepo',
|
|
106
107
|
};
|
|
@@ -122,23 +123,6 @@ const requireWorkspaceRoot = (cwd) => {
|
|
|
122
123
|
}
|
|
123
124
|
return root;
|
|
124
125
|
};
|
|
125
|
-
const filterWorkspacePackages = (packages, filters) => {
|
|
126
|
-
const matched = packages.filter((item) => filters.some((filter) => matchesFilter(item.name, filter)));
|
|
127
|
-
if (!matched.length) {
|
|
128
|
-
throw new Error(`[publish] no workspace package matched filter: ${filters.join(', ')}`);
|
|
129
|
-
}
|
|
130
|
-
return matched;
|
|
131
|
-
};
|
|
132
|
-
const matchesFilter = (packageName, filter) => {
|
|
133
|
-
if (filter.endsWith('/*')) {
|
|
134
|
-
const scope = filter.slice(0, -2);
|
|
135
|
-
return packageName.startsWith(`${scope}/`);
|
|
136
|
-
}
|
|
137
|
-
return packageName === filter;
|
|
138
|
-
};
|
|
139
|
-
const isExactlyMatchedByFilter = (packageName, filters) => {
|
|
140
|
-
return filters.some((filter) => filter === packageName);
|
|
141
|
-
};
|
|
142
126
|
const createPublishTarget = (options) => {
|
|
143
127
|
const packageName = requirePackageName(options.packageRoot, options.packageJson);
|
|
144
128
|
const version = requirePackageVersion(options.packageRoot, options.packageJson);
|
|
@@ -159,39 +143,10 @@ const validatePublishTargets = (targets) => {
|
|
|
159
143
|
throw new Error('[publish] no publishable package found.');
|
|
160
144
|
}
|
|
161
145
|
};
|
|
162
|
-
const
|
|
163
|
-
const targetNames = new Set(targets.map((target) => target.packageName));
|
|
164
|
-
const visited = new Set();
|
|
165
|
-
const visiting = new Set();
|
|
166
|
-
const sorted = [];
|
|
167
|
-
const targetMap = new Map(targets.map((target) => [target.packageName, target]));
|
|
168
|
-
const visit = (target) => {
|
|
169
|
-
if (visited.has(target.packageName))
|
|
170
|
-
return;
|
|
171
|
-
if (visiting.has(target.packageName)) {
|
|
172
|
-
throw new Error(`[publish] circular workspace dependency detected at ${target.packageName}.`);
|
|
173
|
-
}
|
|
174
|
-
visiting.add(target.packageName);
|
|
175
|
-
for (const dependency of getWorkspaceDependencies(target.packageJson)) {
|
|
176
|
-
if (!targetNames.has(dependency))
|
|
177
|
-
continue;
|
|
178
|
-
const dependencyTarget = targetMap.get(dependency);
|
|
179
|
-
if (dependencyTarget)
|
|
180
|
-
visit(dependencyTarget);
|
|
181
|
-
}
|
|
182
|
-
visiting.delete(target.packageName);
|
|
183
|
-
visited.add(target.packageName);
|
|
184
|
-
sorted.push(target);
|
|
185
|
-
};
|
|
186
|
-
for (const target of targets) {
|
|
187
|
-
visit(target);
|
|
188
|
-
}
|
|
189
|
-
return sorted;
|
|
190
|
-
};
|
|
191
|
-
const getWorkspaceDependencies = (packageJson) => {
|
|
146
|
+
const getWorkspaceDependencies = (target) => {
|
|
192
147
|
return Object.entries({
|
|
193
|
-
...packageJson.dependencies,
|
|
194
|
-
...packageJson.optionalDependencies,
|
|
148
|
+
...target.packageJson.dependencies,
|
|
149
|
+
...target.packageJson.optionalDependencies,
|
|
195
150
|
})
|
|
196
151
|
.filter(([, version]) => version === 'workspace:*')
|
|
197
152
|
.map(([packageName]) => packageName);
|
|
@@ -215,3 +170,4 @@ const workspaceDependencyGroups = [
|
|
|
215
170
|
'optionalDependencies',
|
|
216
171
|
'peerDependencies',
|
|
217
172
|
];
|
|
173
|
+
const publishWorkspaceReadErrorMessage = '[publish] failed to read pnpm workspace packages.';
|
package/dist/publish/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AukletEnvContext } from '#auklet/env';
|
|
2
|
-
import type { DeferredCliValue } from '#auklet/cli/values';
|
|
2
|
+
import type { DeferredCliValue } from '#auklet/cli/parse/values';
|
|
3
3
|
export type PackageJson = {
|
|
4
4
|
name?: string;
|
|
5
5
|
version?: string;
|
|
@@ -37,12 +37,6 @@ export type PublishTarget = {
|
|
|
37
37
|
workspaceMode: 'single' | 'monorepo';
|
|
38
38
|
packageJson: PackageJson;
|
|
39
39
|
};
|
|
40
|
-
export type WorkspacePackage = {
|
|
41
|
-
name: string;
|
|
42
|
-
path: string;
|
|
43
|
-
version: string;
|
|
44
|
-
private?: boolean;
|
|
45
|
-
};
|
|
46
40
|
export type PublishOptions = {
|
|
47
41
|
cwd: string;
|
|
48
42
|
dryRun: boolean;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { WorkspacePackageInfo } from '#auklet/workspace/packages';
|
|
2
|
+
type WorkspaceTargetBase<T> = {
|
|
3
|
+
private?: boolean;
|
|
4
|
+
packageJson: T;
|
|
5
|
+
packageName: string;
|
|
6
|
+
};
|
|
7
|
+
type ResolveWorkspaceTargetsOptions<T, TTarget> = {
|
|
8
|
+
cwd: string;
|
|
9
|
+
scope: string;
|
|
10
|
+
filters: Array<string>;
|
|
11
|
+
emptyTargetMessage: string;
|
|
12
|
+
excludeRoot?: boolean;
|
|
13
|
+
includePrivate?: boolean;
|
|
14
|
+
readErrorMessage?: string;
|
|
15
|
+
includeDependencies?: boolean;
|
|
16
|
+
env?: Record<string, string | undefined>;
|
|
17
|
+
readPackageJson: (packageRoot: string) => T;
|
|
18
|
+
getDependencies: (target: TTarget) => Array<string>;
|
|
19
|
+
createTarget: (item: WorkspacePackageInfo, packageJson: T) => TTarget;
|
|
20
|
+
onPrivatePackage?: (item: WorkspacePackageInfo, context: {
|
|
21
|
+
exact: boolean;
|
|
22
|
+
}) => void;
|
|
23
|
+
};
|
|
24
|
+
export declare function resolveWorkspacePackageInfos(cwd: string, filters: Array<string>, options: {
|
|
25
|
+
env?: Record<string, string | undefined>;
|
|
26
|
+
scope: string;
|
|
27
|
+
readErrorMessage?: string;
|
|
28
|
+
}): Promise<WorkspacePackageInfo[]>;
|
|
29
|
+
export declare function resolveWorkspaceTargets<T, K extends WorkspaceTargetBase<T>>(options: ResolveWorkspaceTargetsOptions<T, K>): Promise<K[]>;
|
|
30
|
+
export declare function getWorkspaceDependencyNames(value: unknown): string[];
|
|
31
|
+
export {};
|