auklet 0.1.4 → 0.1.5
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 +113 -429
- package/dist/cli/build.d.ts +3 -5
- package/dist/cli/build.js +84 -23
- package/dist/cli/buildCss.d.ts +10 -5
- package/dist/cli/buildCss.js +21 -17
- package/dist/cli/buildWorkspace.d.ts +23 -0
- package/dist/cli/buildWorkspace.js +43 -0
- package/dist/cli/dev.d.ts +2 -1
- package/dist/cli/dev.js +128 -23
- package/dist/cli/main.js +36 -12
- package/dist/cli/parse/build.d.ts +62 -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 +17 -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 +12 -0
- package/dist/cli/parse/workspace.js +45 -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 +26 -71
- 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
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,10 +18,11 @@ 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
27
|
if (options.packages.length)
|
|
27
28
|
return [...new Set(options.packages)];
|
|
@@ -63,27 +64,26 @@ const resolveMonorepoPublishPlan = async (options, runtime, logger) => {
|
|
|
63
64
|
const { env } = createPublishRootEnv({
|
|
64
65
|
token: options.token,
|
|
65
66
|
}, runtime);
|
|
66
|
-
const
|
|
67
|
+
const targets = await resolveWorkspaceTargets({
|
|
67
68
|
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({
|
|
69
|
+
cwd: root,
|
|
70
|
+
scope: 'publish',
|
|
71
|
+
readErrorMessage: publishWorkspaceReadErrorMessage,
|
|
72
|
+
readPackageJson,
|
|
73
|
+
filters: options.filters,
|
|
74
|
+
getDependencies: getWorkspaceDependencies,
|
|
75
|
+
emptyTargetMessage: '[publish] no publishable package found.',
|
|
76
|
+
createTarget: (item, packageJson) => createPublishTarget({
|
|
82
77
|
packageRoot: item.path,
|
|
83
78
|
packageJson,
|
|
84
79
|
publishVersion: '',
|
|
85
80
|
workspaceMode: 'monorepo',
|
|
86
|
-
})
|
|
81
|
+
}),
|
|
82
|
+
onPrivatePackage: (item, context) => {
|
|
83
|
+
if (context.exact) {
|
|
84
|
+
logger.warnOnce('package ', logger.package(item.name), ' is private, skipping.');
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
87
|
});
|
|
88
88
|
const versionBase = getMonorepoVersionBase(rootVersion, targets);
|
|
89
89
|
const publishVersion = await resolvePublishVersion(versionBase, options.version, root);
|
|
@@ -100,7 +100,7 @@ const resolveMonorepoPublishPlan = async (options, runtime, logger) => {
|
|
|
100
100
|
root,
|
|
101
101
|
version: publishVersion,
|
|
102
102
|
dryRun: options.dryRun,
|
|
103
|
-
targets:
|
|
103
|
+
targets: publishTargets,
|
|
104
104
|
config: getPublishConfig(rootPackageJson),
|
|
105
105
|
workspaceMode: 'monorepo',
|
|
106
106
|
};
|
|
@@ -122,23 +122,6 @@ const requireWorkspaceRoot = (cwd) => {
|
|
|
122
122
|
}
|
|
123
123
|
return root;
|
|
124
124
|
};
|
|
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
125
|
const createPublishTarget = (options) => {
|
|
143
126
|
const packageName = requirePackageName(options.packageRoot, options.packageJson);
|
|
144
127
|
const version = requirePackageVersion(options.packageRoot, options.packageJson);
|
|
@@ -159,39 +142,10 @@ const validatePublishTargets = (targets) => {
|
|
|
159
142
|
throw new Error('[publish] no publishable package found.');
|
|
160
143
|
}
|
|
161
144
|
};
|
|
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) => {
|
|
145
|
+
const getWorkspaceDependencies = (target) => {
|
|
192
146
|
return Object.entries({
|
|
193
|
-
...packageJson.dependencies,
|
|
194
|
-
...packageJson.optionalDependencies,
|
|
147
|
+
...target.packageJson.dependencies,
|
|
148
|
+
...target.packageJson.optionalDependencies,
|
|
195
149
|
})
|
|
196
150
|
.filter(([, version]) => version === 'workspace:*')
|
|
197
151
|
.map(([packageName]) => packageName);
|
|
@@ -215,3 +169,4 @@ const workspaceDependencyGroups = [
|
|
|
215
169
|
'optionalDependencies',
|
|
216
170
|
'peerDependencies',
|
|
217
171
|
];
|
|
172
|
+
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 {};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { isPlainObject } from 'aidly';
|
|
3
|
+
import { findWorkspaceRoot } from '#auklet/workspace/root';
|
|
4
|
+
import { readPnpmWorkspacePackageInfo } from '#auklet/workspace/packages';
|
|
5
|
+
export async function resolveWorkspacePackageInfos(cwd, filters, options) {
|
|
6
|
+
const root = requireWorkspaceRoot(cwd, options.scope);
|
|
7
|
+
const packages = await readWorkspacePackageInfo(root, options);
|
|
8
|
+
return filterWorkspacePackages(packages, filters, options.scope);
|
|
9
|
+
}
|
|
10
|
+
export async function resolveWorkspaceTargets(options) {
|
|
11
|
+
const root = requireWorkspaceRoot(options.cwd, options.scope);
|
|
12
|
+
const packages = filterWorkspaceRootPackage(await readWorkspacePackageInfo(root, options), root, options);
|
|
13
|
+
const matchedPackages = filterWorkspacePackages(packages, options.filters, options.scope);
|
|
14
|
+
const targetFactory = createWorkspaceTargetFactory(options);
|
|
15
|
+
const targets = options.includeDependencies
|
|
16
|
+
? includeWorkspaceDependencies(matchedPackages, packages, targetFactory, options)
|
|
17
|
+
: matchedPackages
|
|
18
|
+
.map((item) => targetFactory.create(item))
|
|
19
|
+
.filter(isWorkspaceTarget);
|
|
20
|
+
if (!targets.length) {
|
|
21
|
+
throw new Error(options.emptyTargetMessage);
|
|
22
|
+
}
|
|
23
|
+
return sortWorkspaceTargets(targets, {
|
|
24
|
+
getDependencies: options.getDependencies,
|
|
25
|
+
scope: options.scope,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export function getWorkspaceDependencyNames(value) {
|
|
29
|
+
return isPlainObject(value) ? Object.keys(value) : [];
|
|
30
|
+
}
|
|
31
|
+
const filterWorkspaceRootPackage = (packages, root, options) => {
|
|
32
|
+
if (!options.excludeRoot)
|
|
33
|
+
return packages;
|
|
34
|
+
const normalizedRoot = path.resolve(root);
|
|
35
|
+
return packages.filter((item) => path.resolve(item.path) !== normalizedRoot);
|
|
36
|
+
};
|
|
37
|
+
const isWorkspaceTarget = (target) => {
|
|
38
|
+
return target !== null;
|
|
39
|
+
};
|
|
40
|
+
const createWorkspaceTargetFactory = (options) => {
|
|
41
|
+
const cache = new Map();
|
|
42
|
+
const create = (item) => {
|
|
43
|
+
const cached = cache.get(item.name);
|
|
44
|
+
if (cached !== undefined)
|
|
45
|
+
return cached;
|
|
46
|
+
if (!options.includePrivate && item.private) {
|
|
47
|
+
options.onPrivatePackage?.(item, {
|
|
48
|
+
exact: options.filters.includes(item.name),
|
|
49
|
+
});
|
|
50
|
+
cache.set(item.name, null);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const packageJson = options.readPackageJson(item.path);
|
|
54
|
+
const target = options.createTarget(item, packageJson);
|
|
55
|
+
cache.set(item.name, target);
|
|
56
|
+
return target;
|
|
57
|
+
};
|
|
58
|
+
return { create };
|
|
59
|
+
};
|
|
60
|
+
const includeWorkspaceDependencies = (matchedPackages, packages, targetFactory, options) => {
|
|
61
|
+
const packageMap = new Map(packages.map((item) => [item.name, item]));
|
|
62
|
+
const included = new Map();
|
|
63
|
+
const include = (item) => {
|
|
64
|
+
const target = targetFactory.create(item);
|
|
65
|
+
if (!target || included.has(target.packageName))
|
|
66
|
+
return;
|
|
67
|
+
included.set(target.packageName, target);
|
|
68
|
+
for (const dependency of options.getDependencies(target)) {
|
|
69
|
+
const dependencyItem = packageMap.get(dependency);
|
|
70
|
+
if (dependencyItem)
|
|
71
|
+
include(dependencyItem);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
for (const item of matchedPackages) {
|
|
75
|
+
include(item);
|
|
76
|
+
}
|
|
77
|
+
return [...included.values()];
|
|
78
|
+
};
|
|
79
|
+
const requireWorkspaceRoot = (cwd, scope) => {
|
|
80
|
+
const root = findWorkspaceRoot(cwd);
|
|
81
|
+
if (!root) {
|
|
82
|
+
throw new Error(`[${scope}] --filter requires a pnpm workspace root.`);
|
|
83
|
+
}
|
|
84
|
+
return root;
|
|
85
|
+
};
|
|
86
|
+
const readWorkspacePackageInfo = async (root, options) => {
|
|
87
|
+
try {
|
|
88
|
+
return await readPnpmWorkspacePackageInfo(root, {
|
|
89
|
+
env: options.env,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
if (!options.readErrorMessage)
|
|
94
|
+
throw error;
|
|
95
|
+
throw new Error(options.readErrorMessage, {
|
|
96
|
+
cause: error,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const filterWorkspacePackages = (packages, filters, scope) => {
|
|
101
|
+
const matched = packages.filter((item) => filters.some((filter) => matchesWorkspacePackageFilter(item.name, filter)));
|
|
102
|
+
if (!matched.length) {
|
|
103
|
+
throw new Error(`[${scope}] no workspace package matched filter: ${filters.join(', ')}`);
|
|
104
|
+
}
|
|
105
|
+
return matched;
|
|
106
|
+
};
|
|
107
|
+
const matchesWorkspacePackageFilter = (packageName, filter) => {
|
|
108
|
+
if (filter === '*')
|
|
109
|
+
return true;
|
|
110
|
+
if (filter.endsWith('/*')) {
|
|
111
|
+
const scope = filter.slice(0, -2);
|
|
112
|
+
return packageName.startsWith(`${scope}/`);
|
|
113
|
+
}
|
|
114
|
+
return packageName === filter;
|
|
115
|
+
};
|
|
116
|
+
const sortWorkspaceTargets = (targets, options) => {
|
|
117
|
+
const targetNames = new Set(targets.map((target) => target.packageName));
|
|
118
|
+
const targetMap = new Map(targets.map((target) => [target.packageName, target]));
|
|
119
|
+
const sorted = [];
|
|
120
|
+
const visited = new Set();
|
|
121
|
+
const visiting = new Set();
|
|
122
|
+
const visit = (target) => {
|
|
123
|
+
if (visited.has(target.packageName))
|
|
124
|
+
return;
|
|
125
|
+
if (visiting.has(target.packageName)) {
|
|
126
|
+
throw new Error(`[${options.scope}] circular workspace dependency detected at ${target.packageName}.`);
|
|
127
|
+
}
|
|
128
|
+
visiting.add(target.packageName);
|
|
129
|
+
for (const dependency of options.getDependencies(target)) {
|
|
130
|
+
if (!targetNames.has(dependency))
|
|
131
|
+
continue;
|
|
132
|
+
const dependencyTarget = targetMap.get(dependency);
|
|
133
|
+
if (dependencyTarget)
|
|
134
|
+
visit(dependencyTarget);
|
|
135
|
+
}
|
|
136
|
+
visiting.delete(target.packageName);
|
|
137
|
+
visited.add(target.packageName);
|
|
138
|
+
sorted.push(target);
|
|
139
|
+
};
|
|
140
|
+
for (const target of targets) {
|
|
141
|
+
visit(target);
|
|
142
|
+
}
|
|
143
|
+
return sorted;
|
|
144
|
+
};
|
package/package.json
CHANGED
package/dist/cli/buildArgs.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { AukletEnvContext } from '#auklet/env';
|
|
2
|
-
import type { AukletConfig } from '#auklet/types';
|
|
3
|
-
export declare function resolveBuildCliArgs(args: Array<string>, envContext?: AukletEnvContext): {
|
|
4
|
-
args: string[];
|
|
5
|
-
config: AukletConfig;
|
|
6
|
-
};
|
|
7
|
-
export declare function createBuildEnv(config: AukletConfig): {
|
|
8
|
-
AUKLET_CONFIG_OVERRIDES: string;
|
|
9
|
-
} | undefined;
|
package/dist/cli/publish.d.ts
DELETED
package/dist/cli/publish.js
DELETED
|
File without changes
|
|
File without changes
|