@smoothbricks/cli 0.1.1 → 0.3.0
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 +161 -32
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +110 -10
- package/dist/devenv/index.d.ts +10 -0
- package/dist/devenv/index.d.ts.map +1 -0
- package/dist/devenv/index.js +27 -0
- package/dist/generate/index.d.ts +20 -0
- package/dist/generate/index.d.ts.map +1 -0
- package/dist/generate/index.js +47 -0
- package/dist/lib/cli-package.d.ts +4 -0
- package/dist/lib/cli-package.d.ts.map +1 -0
- package/dist/lib/cli-package.js +15 -0
- package/dist/lib/run.d.ts +6 -0
- package/dist/lib/run.d.ts.map +1 -1
- package/dist/lib/run.js +32 -0
- package/dist/lib/workspace.d.ts +25 -1
- package/dist/lib/workspace.d.ts.map +1 -1
- package/dist/lib/workspace.js +79 -17
- package/dist/monorepo/commit-msg.d.ts +8 -1
- package/dist/monorepo/commit-msg.d.ts.map +1 -1
- package/dist/monorepo/commit-msg.js +85 -7
- package/dist/monorepo/index.d.ts +19 -2
- package/dist/monorepo/index.d.ts.map +1 -1
- package/dist/monorepo/index.js +104 -16
- package/dist/monorepo/lockfile.d.ts.map +1 -1
- package/dist/monorepo/lockfile.js +9 -0
- package/dist/monorepo/managed-files.js +1 -1
- package/dist/monorepo/nx-sync.d.ts +2 -1
- package/dist/monorepo/nx-sync.d.ts.map +1 -1
- package/dist/monorepo/nx-sync.js +8 -2
- package/dist/monorepo/package-hygiene.d.ts +6 -2
- package/dist/monorepo/package-hygiene.d.ts.map +1 -1
- package/dist/monorepo/package-hygiene.js +12 -4
- package/dist/monorepo/package-policy.d.ts +13 -4
- package/dist/monorepo/package-policy.d.ts.map +1 -1
- package/dist/monorepo/package-policy.js +208 -113
- package/dist/monorepo/packed-package.d.ts +3 -0
- package/dist/monorepo/packed-package.d.ts.map +1 -1
- package/dist/monorepo/packed-package.js +68 -36
- package/dist/monorepo/packs/index.d.ts +20 -1
- package/dist/monorepo/packs/index.d.ts.map +1 -1
- package/dist/monorepo/packs/index.js +238 -19
- package/dist/monorepo/publish-workflow.d.ts +0 -4
- package/dist/monorepo/publish-workflow.d.ts.map +1 -1
- package/dist/monorepo/publish-workflow.js +7 -15
- package/dist/monorepo/tool-validation.d.ts +22 -0
- package/dist/monorepo/tool-validation.d.ts.map +1 -0
- package/dist/monorepo/tool-validation.js +399 -0
- package/dist/nx/index.d.ts +25 -0
- package/dist/nx/index.d.ts.map +1 -0
- package/dist/nx/index.js +112 -0
- package/dist/release/bootstrap-npm-packages.d.ts +19 -0
- package/dist/release/bootstrap-npm-packages.d.ts.map +1 -0
- package/dist/release/bootstrap-npm-packages.js +58 -0
- package/dist/release/candidates.d.ts +11 -0
- package/dist/release/candidates.d.ts.map +1 -0
- package/dist/release/candidates.js +181 -0
- package/dist/release/core.d.ts +4 -1
- package/dist/release/core.d.ts.map +1 -1
- package/dist/release/core.js +76 -9
- package/dist/release/github-release.d.ts +1 -0
- package/dist/release/github-release.d.ts.map +1 -1
- package/dist/release/github-release.js +3 -3
- package/dist/release/index.d.ts +32 -1
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +488 -64
- package/dist/release/npm-auth.d.ts +0 -1
- package/dist/release/npm-auth.d.ts.map +1 -1
- package/dist/release/npm-auth.js +4 -16
- package/dist/release/orchestration.d.ts +11 -2
- package/dist/release/orchestration.d.ts.map +1 -1
- package/dist/release/orchestration.js +41 -3
- package/dist/release/publish-plan.js +1 -1
- package/managed/raw/git-format-staged.yml +54 -0
- package/managed/raw/tooling/git-hooks/commit-msg.sh +1 -1
- package/managed/templates/github/actions/setup-devenv/action.yml +1 -7
- package/managed/templates/github/workflows/ci.yml +4 -2
- package/package.json +15 -8
- package/src/cli.ts +153 -22
- package/src/devenv/index.test.ts +49 -0
- package/src/devenv/index.ts +38 -0
- package/src/generate/index.ts +92 -0
- package/src/lib/cli-package.ts +18 -0
- package/src/lib/run.ts +44 -0
- package/src/lib/workspace.ts +112 -17
- package/src/monorepo/__tests__/publish-workflow.test.ts +16 -9
- package/src/monorepo/commit-msg.test.ts +45 -0
- package/src/monorepo/commit-msg.ts +107 -7
- package/src/monorepo/index.ts +142 -16
- package/src/monorepo/lockfile.ts +9 -0
- package/src/monorepo/managed-files.ts +1 -1
- package/src/monorepo/nx-sync.ts +9 -2
- package/src/monorepo/package-hygiene.test.ts +34 -0
- package/src/monorepo/package-hygiene.ts +26 -4
- package/src/monorepo/package-policy.test.ts +1130 -0
- package/src/monorepo/package-policy.ts +237 -114
- package/src/monorepo/packed-package.ts +89 -37
- package/src/monorepo/packs/index.test.ts +189 -0
- package/src/monorepo/packs/index.ts +311 -20
- package/src/monorepo/publish-workflow.ts +10 -19
- package/src/monorepo/setup-test-tracing.test.ts +120 -0
- package/src/monorepo/tool-validation.test.ts +261 -0
- package/src/monorepo/tool-validation.ts +462 -0
- package/src/nx/index.test.ts +73 -0
- package/src/nx/index.ts +139 -0
- package/src/release/__tests__/bootstrap-npm-packages.test.ts +127 -0
- package/src/release/__tests__/candidates.test.ts +262 -0
- package/src/release/__tests__/core-properties.test.ts +6 -6
- package/src/release/__tests__/core-scenarios.test.ts +27 -20
- package/src/release/__tests__/core.test.ts +52 -5
- package/src/release/__tests__/fixture-repo.test.ts +90 -31
- package/src/release/__tests__/github-release.test.ts +22 -24
- package/src/release/__tests__/helpers/fixture-repo.ts +1 -0
- package/src/release/__tests__/npm-auth.test.ts +12 -21
- package/src/release/__tests__/orchestration.test.ts +142 -12
- package/src/release/__tests__/publish-plan.test.ts +9 -3
- package/src/release/__tests__/retag-unpublished.test.ts +10 -10
- package/src/release/__tests__/trust-publisher.test.ts +165 -0
- package/src/release/bootstrap-npm-packages.ts +88 -0
- package/src/release/candidates.ts +225 -0
- package/src/release/core.ts +96 -10
- package/src/release/github-release.ts +3 -3
- package/src/release/index.ts +658 -74
- package/src/release/npm-auth.ts +4 -33
- package/src/release/orchestration.ts +60 -5
- package/src/release/publish-plan.ts +1 -1
- package/dist/nx-version-actions.cjs +0 -25
- package/dist/nx-version-actions.d.cts +0 -6
- package/dist/nx-version-actions.d.cts.map +0 -1
- package/managed/raw/.git-format-staged.yml +0 -47
- package/src/nx-version-actions.cts +0 -36
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { cliPackageVersion, isSmoothBricksCodebasePackageName } from '../lib/cli-package.js';
|
|
4
|
+
import { getOrCreateRecord, readJsonObject, recordProperty, setStringProperty, writeJsonObject } from '../lib/json.js';
|
|
5
|
+
import { readPackageJsonObject } from '../lib/workspace.js';
|
|
6
|
+
const rootDevDependencies = [
|
|
7
|
+
{ name: '@biomejs/biome', fallbackVersion: '^2.3.5', minimumVersion: '2.3.0', prefix: '^' },
|
|
8
|
+
{ name: '@nx/js', fallbackVersion: '22.0.3', minimumVersion: '22.0.0' },
|
|
9
|
+
{
|
|
10
|
+
name: '@smoothbricks/nx-plugin',
|
|
11
|
+
fallbackVersion: '^0.0.1',
|
|
12
|
+
minimumVersion: '0.0.1',
|
|
13
|
+
prefix: '^',
|
|
14
|
+
useWorkspaceRangeInCodebase: true,
|
|
15
|
+
},
|
|
16
|
+
{ name: 'eslint', fallbackVersion: '^9.39.1', minimumVersion: '9.39.0', prefix: '^' },
|
|
17
|
+
{
|
|
18
|
+
name: 'eslint-stdout',
|
|
19
|
+
fallbackVersion: '^1.1.1',
|
|
20
|
+
minimumVersion: '1.1.1',
|
|
21
|
+
prefix: '^',
|
|
22
|
+
useWorkspaceRangeInCodebase: true,
|
|
23
|
+
},
|
|
24
|
+
{ name: 'nx', fallbackVersion: '22.5.4', minimumVersion: '22.5.0' },
|
|
25
|
+
{ name: 'prettier', fallbackVersion: '^3.6.1', minimumVersion: '3.6.0', prefix: '^' },
|
|
26
|
+
{ name: 'typescript', fallbackVersion: '^5.9.3', minimumVersion: '5.9.0', prefix: '^' },
|
|
27
|
+
];
|
|
28
|
+
const cliPackageName = '@smoothbricks/cli';
|
|
29
|
+
const requiredDevenvPackages = ['bun', 'git', 'git-format-staged', 'jq', 'alejandra', 'coreutils', 'gnutar'];
|
|
30
|
+
const allowedNodePackages = ['nodejs_24', 'nodejs_latest'];
|
|
31
|
+
export async function applyToolConfigDefaults(root) {
|
|
32
|
+
const context = readToolContext(root);
|
|
33
|
+
await applyRootPackageToolDefaults(root, context);
|
|
34
|
+
applyToolingPackageDefaults(root, context.policy);
|
|
35
|
+
applyDevenvPackageDefaults(root);
|
|
36
|
+
}
|
|
37
|
+
export function validateToolConfig(root) {
|
|
38
|
+
const context = readToolContext(root);
|
|
39
|
+
return (validateRootDevDependencies(context.policy, context.rootPackage) +
|
|
40
|
+
validateToolingPackage(root, context.policy) +
|
|
41
|
+
validateToolingWorkspace(context.rootPackage) +
|
|
42
|
+
validateDevenvPackages(root));
|
|
43
|
+
}
|
|
44
|
+
export async function applyRootDevDependencyDefaults(root, context) {
|
|
45
|
+
const pkg = context.rootPackage;
|
|
46
|
+
if (!pkg) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
let changed = false;
|
|
50
|
+
const devDependencies = getOrCreateRecord(pkg, 'devDependencies');
|
|
51
|
+
for (const dependency of rootDevDependencies) {
|
|
52
|
+
const current = devDependencies[dependency.name];
|
|
53
|
+
if (typeof current !== 'string' || !satisfiesDependencyPolicy(context.policy, current, dependency)) {
|
|
54
|
+
const version = await resolveDependencyVersion(context.policy, dependency);
|
|
55
|
+
changed = setStringProperty(devDependencies, dependency.name, version) || changed;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (delete devDependencies['@smoothbricks/cli']) {
|
|
59
|
+
changed = true;
|
|
60
|
+
}
|
|
61
|
+
if (changed) {
|
|
62
|
+
writeJsonObject(join(root, 'package.json'), pkg);
|
|
63
|
+
console.log('updated package.json workspace tool dependencies');
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.log('unchanged package.json workspace tool dependencies');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function applyRootPackageToolDefaults(root, context) {
|
|
70
|
+
const pkg = context.rootPackage;
|
|
71
|
+
if (!pkg) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
let dependencyChanged = false;
|
|
75
|
+
let workspaceChanged = false;
|
|
76
|
+
const devDependencies = getOrCreateRecord(pkg, 'devDependencies');
|
|
77
|
+
for (const dependency of rootDevDependencies) {
|
|
78
|
+
const current = devDependencies[dependency.name];
|
|
79
|
+
if (typeof current !== 'string' || !satisfiesDependencyPolicy(context.policy, current, dependency)) {
|
|
80
|
+
const version = await resolveDependencyVersion(context.policy, dependency);
|
|
81
|
+
dependencyChanged = setStringProperty(devDependencies, dependency.name, version) || dependencyChanged;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (delete devDependencies[cliPackageName]) {
|
|
85
|
+
dependencyChanged = true;
|
|
86
|
+
}
|
|
87
|
+
workspaceChanged = addWorkspacePattern(pkg, 'tooling');
|
|
88
|
+
if (dependencyChanged || workspaceChanged) {
|
|
89
|
+
writeJsonObject(join(root, 'package.json'), pkg);
|
|
90
|
+
}
|
|
91
|
+
console.log(dependencyChanged
|
|
92
|
+
? 'updated package.json workspace tool dependencies'
|
|
93
|
+
: 'unchanged package.json workspace tool dependencies');
|
|
94
|
+
console.log(workspaceChanged
|
|
95
|
+
? 'updated package.json tooling workspace'
|
|
96
|
+
: 'unchanged package.json tooling workspace');
|
|
97
|
+
}
|
|
98
|
+
export function applyToolingPackageDefaults(root, policy) {
|
|
99
|
+
const path = join(root, 'tooling', 'package.json');
|
|
100
|
+
const pkg = readJsonObject(path) ?? { name: policy.toolingPackageName, private: true, dependencies: {} };
|
|
101
|
+
let changed = false;
|
|
102
|
+
changed = setStringProperty(pkg, 'name', policy.toolingPackageName) || changed;
|
|
103
|
+
if (pkg.private !== true) {
|
|
104
|
+
pkg.private = true;
|
|
105
|
+
changed = true;
|
|
106
|
+
}
|
|
107
|
+
const dependencies = getOrCreateRecord(pkg, 'dependencies');
|
|
108
|
+
changed = setStringProperty(dependencies, cliPackageName, policy.cliDependencyRange) || changed;
|
|
109
|
+
if (changed || !existsSync(path)) {
|
|
110
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
111
|
+
writeJsonObject(path, pkg);
|
|
112
|
+
console.log('updated tooling/package.json tooling dependencies');
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.log('unchanged tooling/package.json tooling dependencies');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
export function applyToolingWorkspaceDefault(root) {
|
|
119
|
+
const path = join(root, 'package.json');
|
|
120
|
+
const pkg = readJsonObject(path);
|
|
121
|
+
if (!pkg) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (addWorkspacePattern(pkg, 'tooling')) {
|
|
125
|
+
writeJsonObject(path, pkg);
|
|
126
|
+
console.log('updated package.json tooling workspace');
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
console.log('unchanged package.json tooling workspace');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export function applyDevenvPackageDefaults(root) {
|
|
133
|
+
const path = join(root, 'tooling', 'direnv', 'devenv.nix');
|
|
134
|
+
if (!existsSync(path)) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
let content = readFileSync(path, 'utf8');
|
|
138
|
+
let changed = false;
|
|
139
|
+
if (!allowedNodePackages.some((name) => hasNixPackage(content, name))) {
|
|
140
|
+
const next = addNixPackage(content, 'nodejs_latest', '# Node.js for workspace tooling');
|
|
141
|
+
changed = next !== content || changed;
|
|
142
|
+
content = next;
|
|
143
|
+
}
|
|
144
|
+
for (const name of requiredDevenvPackages) {
|
|
145
|
+
if (hasNixPackage(content, name)) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const next = addNixPackage(content, name, nixPackageComment(name));
|
|
149
|
+
changed = next !== content || changed;
|
|
150
|
+
content = next;
|
|
151
|
+
}
|
|
152
|
+
if (changed) {
|
|
153
|
+
writeFileSync(path, content);
|
|
154
|
+
console.log('updated tooling/direnv/devenv.nix packages');
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
console.log('unchanged tooling/direnv/devenv.nix packages');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
export function validateRootDevDependencies(policy, rootPackage) {
|
|
161
|
+
const pkg = rootPackage;
|
|
162
|
+
if (!pkg) {
|
|
163
|
+
console.error('package.json not found or invalid');
|
|
164
|
+
return 1;
|
|
165
|
+
}
|
|
166
|
+
const devDependencies = recordProperty(pkg, 'devDependencies');
|
|
167
|
+
let failures = 0;
|
|
168
|
+
for (const dependency of rootDevDependencies) {
|
|
169
|
+
const version = devDependencies?.[dependency.name];
|
|
170
|
+
if (typeof version !== 'string') {
|
|
171
|
+
console.error(`package.json devDependencies.${dependency.name} must be defined`);
|
|
172
|
+
failures++;
|
|
173
|
+
}
|
|
174
|
+
else if (!satisfiesDependencyPolicy(policy, version, dependency)) {
|
|
175
|
+
console.error(`package.json devDependencies.${dependency.name} must be ${formatExpectedDependency(policy, dependency)}; found ${version}`);
|
|
176
|
+
failures++;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (typeof devDependencies?.[cliPackageName] === 'string') {
|
|
180
|
+
console.error(`package.json devDependencies.${cliPackageName} must move to tooling/package.json dependencies`);
|
|
181
|
+
failures++;
|
|
182
|
+
}
|
|
183
|
+
return failures;
|
|
184
|
+
}
|
|
185
|
+
export function validateToolingPackage(root, policy) {
|
|
186
|
+
const path = join(root, 'tooling', 'package.json');
|
|
187
|
+
const pkg = readJsonObject(path);
|
|
188
|
+
if (!pkg) {
|
|
189
|
+
console.error('tooling/package.json not found or invalid');
|
|
190
|
+
return 1;
|
|
191
|
+
}
|
|
192
|
+
const dependencies = recordProperty(pkg, 'dependencies');
|
|
193
|
+
let failures = 0;
|
|
194
|
+
const actualName = typeof pkg.name === 'string' ? pkg.name : null;
|
|
195
|
+
if (actualName !== policy.toolingPackageName) {
|
|
196
|
+
console.error(`tooling/package.json name must be ${policy.toolingPackageName}`);
|
|
197
|
+
failures++;
|
|
198
|
+
}
|
|
199
|
+
const actualCliRange = dependencies?.[cliPackageName];
|
|
200
|
+
if (actualCliRange !== policy.cliDependencyRange) {
|
|
201
|
+
console.error(`tooling/package.json dependencies.${cliPackageName} must be ${policy.cliDependencyRange}`);
|
|
202
|
+
failures++;
|
|
203
|
+
}
|
|
204
|
+
return failures;
|
|
205
|
+
}
|
|
206
|
+
export function validateToolingWorkspace(rootPackage) {
|
|
207
|
+
const pkg = rootPackage;
|
|
208
|
+
if (!pkg) {
|
|
209
|
+
console.error('package.json not found or invalid');
|
|
210
|
+
return 1;
|
|
211
|
+
}
|
|
212
|
+
if (!hasWorkspacePattern(pkg, 'tooling')) {
|
|
213
|
+
console.error('package.json workspaces must include tooling so tooling/package.json participates in installs');
|
|
214
|
+
return 1;
|
|
215
|
+
}
|
|
216
|
+
return 0;
|
|
217
|
+
}
|
|
218
|
+
export function validateDevenvPackages(root) {
|
|
219
|
+
const path = join(root, 'tooling', 'direnv', 'devenv.nix');
|
|
220
|
+
if (!existsSync(path)) {
|
|
221
|
+
console.error('tooling/direnv/devenv.nix not found');
|
|
222
|
+
return 1;
|
|
223
|
+
}
|
|
224
|
+
const content = readFileSync(path, 'utf8');
|
|
225
|
+
let failures = 0;
|
|
226
|
+
if (!allowedNodePackages.some((name) => hasNixPackage(content, name))) {
|
|
227
|
+
console.error(`tooling/direnv/devenv.nix packages must include ${allowedNodePackages.join(' or ')}`);
|
|
228
|
+
failures++;
|
|
229
|
+
}
|
|
230
|
+
for (const name of requiredDevenvPackages) {
|
|
231
|
+
if (!hasNixPackage(content, name)) {
|
|
232
|
+
console.error(`tooling/direnv/devenv.nix packages must include ${name}`);
|
|
233
|
+
failures++;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return failures;
|
|
237
|
+
}
|
|
238
|
+
function addNixPackage(content, name, comment) {
|
|
239
|
+
const packageLine = ` ${name}${comment ? ` ${comment}` : ''}\n`;
|
|
240
|
+
if (hasNixPackage(content, name)) {
|
|
241
|
+
return content;
|
|
242
|
+
}
|
|
243
|
+
const packagesStart = content.indexOf(' packages = with pkgs; [');
|
|
244
|
+
if (packagesStart === -1) {
|
|
245
|
+
return content;
|
|
246
|
+
}
|
|
247
|
+
const insertAt = content.indexOf('\n', packagesStart) + 1;
|
|
248
|
+
return `${content.slice(0, insertAt)}${packageLine}${content.slice(insertAt)}`;
|
|
249
|
+
}
|
|
250
|
+
function hasNixPackage(content, name) {
|
|
251
|
+
return new RegExp(`(^|\\s)${escapeRegex(name)}(\\s|#|$)`, 'm').test(content);
|
|
252
|
+
}
|
|
253
|
+
function nixPackageComment(name) {
|
|
254
|
+
if (name === 'coreutils') {
|
|
255
|
+
return '# Provides fmt for commit message wrapping';
|
|
256
|
+
}
|
|
257
|
+
if (name === 'gnutar') {
|
|
258
|
+
return '# Tarball inspection for package validation';
|
|
259
|
+
}
|
|
260
|
+
if (name === 'git') {
|
|
261
|
+
return '# Git hooks and repository inspection';
|
|
262
|
+
}
|
|
263
|
+
return '';
|
|
264
|
+
}
|
|
265
|
+
function escapeRegex(value) {
|
|
266
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
267
|
+
}
|
|
268
|
+
function satisfiesDependencyPolicy(policy, version, dependency) {
|
|
269
|
+
if (workspaceDependencyExpected(policy, dependency)) {
|
|
270
|
+
return version === 'workspace:*';
|
|
271
|
+
}
|
|
272
|
+
if (dependency.minimumVersion === undefined) {
|
|
273
|
+
return version === dependency.fallbackVersion;
|
|
274
|
+
}
|
|
275
|
+
const parsed = parseVersion(version);
|
|
276
|
+
const minimum = parseVersion(dependency.minimumVersion);
|
|
277
|
+
if (!parsed || !minimum) {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
return compareVersions(parsed, minimum) >= 0;
|
|
281
|
+
}
|
|
282
|
+
function formatExpectedDependency(policy, dependency) {
|
|
283
|
+
if (workspaceDependencyExpected(policy, dependency)) {
|
|
284
|
+
return 'workspace:*';
|
|
285
|
+
}
|
|
286
|
+
return dependency.minimumVersion ? `>= ${dependency.minimumVersion}` : dependency.fallbackVersion;
|
|
287
|
+
}
|
|
288
|
+
export function readToolContext(root) {
|
|
289
|
+
const rootPackage = readPackageJsonObject(join(root, 'package.json'));
|
|
290
|
+
return { rootPackage, policy: toolPolicy(rootPackage) };
|
|
291
|
+
}
|
|
292
|
+
function toolPolicy(rootPackage) {
|
|
293
|
+
const name = typeof rootPackage?.name === 'string' ? rootPackage.name : null;
|
|
294
|
+
const isCodebase = isSmoothBricksCodebasePackageName(name ?? undefined);
|
|
295
|
+
const toolingName = toolingPackageName(name);
|
|
296
|
+
return {
|
|
297
|
+
isSmoothBricksCodebase: isCodebase,
|
|
298
|
+
toolingPackageName: toolingName,
|
|
299
|
+
cliDependencyRange: isCodebase ? 'workspace:*' : `^${cliPackageVersion}`,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
function toolingPackageName(rootName) {
|
|
303
|
+
const name = rootName;
|
|
304
|
+
const scope = name?.match(/^(@[^/]+)\//)?.[1];
|
|
305
|
+
return scope ? `${scope}/tooling` : 'tooling';
|
|
306
|
+
}
|
|
307
|
+
function workspaceDependencyExpected(policy, dependency) {
|
|
308
|
+
return dependency.useWorkspaceRangeInCodebase === true && policy.isSmoothBricksCodebase;
|
|
309
|
+
}
|
|
310
|
+
async function resolveDependencyVersion(policy, dependency) {
|
|
311
|
+
if (workspaceDependencyExpected(policy, dependency)) {
|
|
312
|
+
return 'workspace:*';
|
|
313
|
+
}
|
|
314
|
+
if (!dependency.minimumVersion) {
|
|
315
|
+
return dependency.fallbackVersion;
|
|
316
|
+
}
|
|
317
|
+
const latest = await fetchLatestPatchVersion(dependency.name, dependency.minimumVersion);
|
|
318
|
+
return `${dependency.prefix ?? ''}${latest ?? stripRangePrefix(dependency.fallbackVersion)}`;
|
|
319
|
+
}
|
|
320
|
+
async function fetchLatestPatchVersion(packageName, minimumVersion) {
|
|
321
|
+
const minorRange = sameMajorMinorRange(minimumVersion);
|
|
322
|
+
const url = `https://registry.npmjs.org/${encodeURIComponent(packageName).replace('%40', '@')}`;
|
|
323
|
+
const response = await fetch(url, { headers: { accept: 'application/vnd.npm.install-v1+json' } });
|
|
324
|
+
if (!response.ok) {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
const body = await response.json();
|
|
328
|
+
if (!isRegistryPackument(body)) {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
return latestVersionInSameMajorMinor(Object.keys(body.versions), minorRange);
|
|
332
|
+
}
|
|
333
|
+
function sameMajorMinorRange(minimumVersion) {
|
|
334
|
+
return parseVersion(minimumVersion);
|
|
335
|
+
}
|
|
336
|
+
function parseVersion(version) {
|
|
337
|
+
const match = /^[~^]?(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.exec(version.trim());
|
|
338
|
+
if (!match?.[1] || !match[2] || !match[3]) {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
return { major: Number(match[1]), minor: Number(match[2]), patch: Number(match[3]) };
|
|
342
|
+
}
|
|
343
|
+
function latestVersionInSameMajorMinor(versions, minimum) {
|
|
344
|
+
if (!minimum) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
let latest = null;
|
|
348
|
+
for (const raw of versions) {
|
|
349
|
+
const version = parseVersion(raw);
|
|
350
|
+
if (!version || version.major !== minimum.major || version.minor !== minimum.minor) {
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
if (compareVersions(version, minimum) < 0) {
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
if (!latest || compareVersions(version, latest) > 0) {
|
|
357
|
+
latest = version;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
return latest ? `${latest.major}.${latest.minor}.${latest.patch}` : null;
|
|
361
|
+
}
|
|
362
|
+
function compareVersions(left, right) {
|
|
363
|
+
return left.major - right.major || left.minor - right.minor || left.patch - right.patch;
|
|
364
|
+
}
|
|
365
|
+
function isRegistryPackument(value) {
|
|
366
|
+
return typeof value === 'object' && value !== null && 'versions' in value && isObjectRecord(value.versions);
|
|
367
|
+
}
|
|
368
|
+
function isObjectRecord(value) {
|
|
369
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
370
|
+
}
|
|
371
|
+
function stripRangePrefix(version) {
|
|
372
|
+
return version.replace(/^[~^]/, '');
|
|
373
|
+
}
|
|
374
|
+
function addWorkspacePattern(pkg, pattern) {
|
|
375
|
+
const workspaces = pkg.workspaces;
|
|
376
|
+
if (Array.isArray(workspaces)) {
|
|
377
|
+
if (workspaces.includes(pattern)) {
|
|
378
|
+
return false;
|
|
379
|
+
}
|
|
380
|
+
workspaces.push(pattern);
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
383
|
+
if (isObjectRecord(workspaces) && Array.isArray(workspaces.packages)) {
|
|
384
|
+
if (workspaces.packages.includes(pattern)) {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
workspaces.packages.push(pattern);
|
|
388
|
+
return true;
|
|
389
|
+
}
|
|
390
|
+
pkg.workspaces = ['packages/*', pattern];
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
function hasWorkspacePattern(pkg, pattern) {
|
|
394
|
+
const workspaces = pkg.workspaces;
|
|
395
|
+
if (Array.isArray(workspaces)) {
|
|
396
|
+
return workspaces.includes(pattern);
|
|
397
|
+
}
|
|
398
|
+
return isObjectRecord(workspaces) && Array.isArray(workspaces.packages) && workspaces.packages.includes(pattern);
|
|
399
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface ProjectTargets {
|
|
2
|
+
project: string;
|
|
3
|
+
targets: string[];
|
|
4
|
+
buildDependsOn?: string[];
|
|
5
|
+
}
|
|
6
|
+
export interface CommandInvocation {
|
|
7
|
+
command: string;
|
|
8
|
+
args: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare function nxResetCommand(): CommandInvocation;
|
|
11
|
+
export declare function nxShowProjectCommand(project: string): CommandInvocation;
|
|
12
|
+
export declare function nxCacheDirectories(root: string): string[];
|
|
13
|
+
export declare function targetNamesFromNxProjectJson(value: unknown): string[];
|
|
14
|
+
export declare function buildDependsOnFromNxProjectJson(value: unknown): string[] | undefined;
|
|
15
|
+
export declare function formatProjectTargetLines(projects: ProjectTargets[]): string;
|
|
16
|
+
export declare function projectNamesWithTarget(projects: ProjectTargets[], target: string): string[];
|
|
17
|
+
export declare function projectNamesFromNxShowProjectsOutput(output: string): string[];
|
|
18
|
+
export declare function listTargets(root: string): Promise<void>;
|
|
19
|
+
export declare function listProjects(root: string, options: {
|
|
20
|
+
withTarget?: string;
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
export declare function resetCache(root: string): Promise<void>;
|
|
23
|
+
export declare function cleanCache(root: string): Promise<void>;
|
|
24
|
+
export declare function readProjectTargets(root: string): Promise<ProjectTargets[]>;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nx/index.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,wBAAgB,cAAc,IAAI,iBAAiB,CAElD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEzD;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAGrE;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAOpF;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAK3E;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAK3F;AAED,wBAAgB,oCAAoC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAsB7E;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7D;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhG;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5D;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa5D;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAGhF"}
|
package/dist/nx/index.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { lstat, rm } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { $ } from 'bun';
|
|
5
|
+
import { isRecord, recordProperty } from '../lib/json.js';
|
|
6
|
+
import { decode, run } from '../lib/run.js';
|
|
7
|
+
export function nxResetCommand() {
|
|
8
|
+
return { command: 'nx', args: ['reset'] };
|
|
9
|
+
}
|
|
10
|
+
export function nxShowProjectCommand(project) {
|
|
11
|
+
return { command: 'nx', args: ['show', 'project', project, '--json'] };
|
|
12
|
+
}
|
|
13
|
+
export function nxCacheDirectories(root) {
|
|
14
|
+
return [join(root, '.nx/cache'), join(root, '.nx/workspace-data'), join(root, 'node_modules/.cache/nx')];
|
|
15
|
+
}
|
|
16
|
+
export function targetNamesFromNxProjectJson(value) {
|
|
17
|
+
const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
|
|
18
|
+
return targets ? Object.keys(targets).sort((a, b) => a.localeCompare(b)) : [];
|
|
19
|
+
}
|
|
20
|
+
export function buildDependsOnFromNxProjectJson(value) {
|
|
21
|
+
const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
|
|
22
|
+
const build = targets ? recordProperty(targets, 'build') : null;
|
|
23
|
+
if (!Array.isArray(build?.dependsOn) || !build.dependsOn.every((entry) => typeof entry === 'string')) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
return build.dependsOn;
|
|
27
|
+
}
|
|
28
|
+
export function formatProjectTargetLines(projects) {
|
|
29
|
+
return projects
|
|
30
|
+
.flatMap((project) => project.targets.map((target) => `${project.project}:${target}`))
|
|
31
|
+
.sort((a, b) => a.localeCompare(b))
|
|
32
|
+
.join('\n');
|
|
33
|
+
}
|
|
34
|
+
export function projectNamesWithTarget(projects, target) {
|
|
35
|
+
return projects
|
|
36
|
+
.filter((project) => project.targets.includes(target))
|
|
37
|
+
.map((project) => project.project)
|
|
38
|
+
.sort((a, b) => a.localeCompare(b));
|
|
39
|
+
}
|
|
40
|
+
export function projectNamesFromNxShowProjectsOutput(output) {
|
|
41
|
+
const trimmed = output.trim();
|
|
42
|
+
if (!trimmed) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
if (trimmed.startsWith('[')) {
|
|
46
|
+
try {
|
|
47
|
+
const parsed = JSON.parse(trimmed);
|
|
48
|
+
if (Array.isArray(parsed) && parsed.every((entry) => typeof entry === 'string')) {
|
|
49
|
+
return parsed.sort((a, b) => a.localeCompare(b));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Fall through to legacy newline parsing for older Nx output shapes.
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return trimmed
|
|
57
|
+
.split('\n')
|
|
58
|
+
.map((line) => line.trim())
|
|
59
|
+
.filter(Boolean)
|
|
60
|
+
.sort((a, b) => a.localeCompare(b));
|
|
61
|
+
}
|
|
62
|
+
export async function listTargets(root) {
|
|
63
|
+
const output = formatProjectTargetLines(await readProjectTargets(root));
|
|
64
|
+
if (output) {
|
|
65
|
+
console.log(output);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export async function listProjects(root, options) {
|
|
69
|
+
if (!options.withTarget) {
|
|
70
|
+
throw new Error('smoo nx list-projects requires --with-target <target>');
|
|
71
|
+
}
|
|
72
|
+
const projects = projectNamesWithTarget(await readProjectTargets(root), options.withTarget).join('\n');
|
|
73
|
+
if (projects) {
|
|
74
|
+
console.log(projects);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export async function resetCache(root) {
|
|
78
|
+
const command = nxResetCommand();
|
|
79
|
+
await run(command.command, command.args, root);
|
|
80
|
+
}
|
|
81
|
+
export async function cleanCache(root) {
|
|
82
|
+
for (const path of nxCacheDirectories(root)) {
|
|
83
|
+
if (!existsSync(path)) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const stat = await lstat(path);
|
|
87
|
+
if (!stat.isDirectory() && !stat.isSymbolicLink()) {
|
|
88
|
+
console.warn(`Skipping non-directory Nx cache path: ${path}`);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
await rm(path, { recursive: true, force: true });
|
|
92
|
+
console.log(`Removed ${path}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export async function readProjectTargets(root) {
|
|
96
|
+
const projects = await readNxProjectNames(root);
|
|
97
|
+
return Promise.all(projects.map((project) => readProjectTarget(root, project)));
|
|
98
|
+
}
|
|
99
|
+
async function readNxProjectNames(root) {
|
|
100
|
+
const result = await $ `nx show projects`.cwd(root).quiet();
|
|
101
|
+
return projectNamesFromNxShowProjectsOutput(decode(result.stdout));
|
|
102
|
+
}
|
|
103
|
+
async function readProjectTarget(root, project) {
|
|
104
|
+
const command = nxShowProjectCommand(project);
|
|
105
|
+
const result = await $ `${command.command} ${command.args}`.cwd(root).quiet();
|
|
106
|
+
const parsed = JSON.parse(decode(result.stdout));
|
|
107
|
+
return {
|
|
108
|
+
project,
|
|
109
|
+
targets: targetNamesFromNxProjectJson(parsed),
|
|
110
|
+
buildDependsOn: buildDependsOnFromNxProjectJson(parsed),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReleasePackageInfo } from './core.js';
|
|
2
|
+
export declare const NPM_BOOTSTRAP_VERSION = "0.0.0-bootstrap.0";
|
|
3
|
+
export declare const NPM_BOOTSTRAP_DIST_TAG = "bootstrap";
|
|
4
|
+
export interface BootstrapNpmPackagesOptions {
|
|
5
|
+
dryRun: boolean;
|
|
6
|
+
skipLogin: boolean;
|
|
7
|
+
packages: string[];
|
|
8
|
+
otp?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface BootstrapNpmPackagesShell<Package extends ReleasePackageInfo = ReleasePackageInfo> {
|
|
11
|
+
listReleasePackages(): Package[];
|
|
12
|
+
packageExists(name: string): Promise<boolean>;
|
|
13
|
+
login(): Promise<void>;
|
|
14
|
+
publishPlaceholder(pkg: Package, env?: Record<string, string>): Promise<void>;
|
|
15
|
+
promptOtp(packageName: string): Promise<string>;
|
|
16
|
+
log(message: string): void;
|
|
17
|
+
}
|
|
18
|
+
export declare function bootstrapNpmPackages<Package extends ReleasePackageInfo>(shell: BootstrapNpmPackagesShell<Package>, options: BootstrapNpmPackagesOptions): Promise<Package[]>;
|
|
19
|
+
//# sourceMappingURL=bootstrap-npm-packages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap-npm-packages.d.ts","sourceRoot":"","sources":["../../src/release/bootstrap-npm-packages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpD,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AACzD,eAAO,MAAM,sBAAsB,cAAc,CAAC;AAElD,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,yBAAyB,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IAChG,mBAAmB,IAAI,OAAO,EAAE,CAAC;IACjC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,oBAAoB,CAAC,OAAO,SAAS,kBAAkB,EAC3E,KAAK,EAAE,yBAAyB,CAAC,OAAO,CAAC,EACzC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,OAAO,EAAE,CAAC,CAuCpB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const NPM_BOOTSTRAP_VERSION = '0.0.0-bootstrap.0';
|
|
2
|
+
export const NPM_BOOTSTRAP_DIST_TAG = 'bootstrap';
|
|
3
|
+
export async function bootstrapNpmPackages(shell, options) {
|
|
4
|
+
const packages = selectedReleasePackages(shell.listReleasePackages(), options.packages);
|
|
5
|
+
if (packages.length === 0) {
|
|
6
|
+
throw new Error('No owned release packages found.');
|
|
7
|
+
}
|
|
8
|
+
const missing = [];
|
|
9
|
+
for (const pkg of packages) {
|
|
10
|
+
if (await shell.packageExists(pkg.name)) {
|
|
11
|
+
shell.log(`${pkg.name}: already exists on npm; skipping placeholder bootstrap.`);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
missing.push(pkg);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (missing.length === 0) {
|
|
18
|
+
shell.log('All selected owned release packages already exist on npm.');
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
shell.log(`Bootstrap npm placeholders (${NPM_BOOTSTRAP_VERSION}, dist-tag ${NPM_BOOTSTRAP_DIST_TAG}): ${missing
|
|
22
|
+
.map((pkg) => pkg.name)
|
|
23
|
+
.join(', ')}`);
|
|
24
|
+
if (options.dryRun) {
|
|
25
|
+
return missing;
|
|
26
|
+
}
|
|
27
|
+
if (!options.skipLogin) {
|
|
28
|
+
await shell.login();
|
|
29
|
+
}
|
|
30
|
+
for (const pkg of missing) {
|
|
31
|
+
shell.log(`${pkg.name}: publishing npm placeholder.`);
|
|
32
|
+
const otp = options.otp ?? (await shell.promptOtp(pkg.name));
|
|
33
|
+
await shell.publishPlaceholder(pkg, { NPM_CONFIG_OTP: otp });
|
|
34
|
+
}
|
|
35
|
+
shell.log('Bootstrap complete. Run smoo release trust-publisher before the first CI publish.');
|
|
36
|
+
return missing;
|
|
37
|
+
}
|
|
38
|
+
function selectedReleasePackages(packages, selections) {
|
|
39
|
+
if (selections.length === 0) {
|
|
40
|
+
return packages;
|
|
41
|
+
}
|
|
42
|
+
const byName = new Map(packages.map((pkg) => [pkg.name, pkg]));
|
|
43
|
+
const selected = [];
|
|
44
|
+
const unknown = [];
|
|
45
|
+
for (const name of selections) {
|
|
46
|
+
const pkg = byName.get(name);
|
|
47
|
+
if (pkg) {
|
|
48
|
+
selected.push(pkg);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
unknown.push(name);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (unknown.length > 0) {
|
|
55
|
+
throw new Error(`Unknown owned release package selection: ${unknown.join(', ')}`);
|
|
56
|
+
}
|
|
57
|
+
return selected;
|
|
58
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReleasePackageInfo } from './core.js';
|
|
2
|
+
export interface AutoReleaseCandidateShell {
|
|
3
|
+
gitRefExists(ref: string): Promise<boolean>;
|
|
4
|
+
packageChangedFilesSince(ref: string, packagePath: string): Promise<string[]>;
|
|
5
|
+
packageJsonAtRef(ref: string, packagePath: string): Promise<Record<string, unknown> | null>;
|
|
6
|
+
currentPackageJson(packagePath: string): Promise<Record<string, unknown> | null>;
|
|
7
|
+
packageBuildInputPatterns(projectName: string, packagePath: string): Promise<string[]>;
|
|
8
|
+
packageHasHistory(packagePath: string): Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
export declare function autoReleaseCandidatePackages<Package extends ReleasePackageInfo>(shell: AutoReleaseCandidateShell, packages: Package[]): Promise<Package[]>;
|
|
11
|
+
//# sourceMappingURL=candidates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"candidates.d.ts","sourceRoot":"","sources":["../../src/release/candidates.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAGpD,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9E,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAC5F,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IACjF,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACvF,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1D;AAgCD,wBAAsB,4BAA4B,CAAC,OAAO,SAAS,kBAAkB,EACnF,KAAK,EAAE,yBAAyB,EAChC,QAAQ,EAAE,OAAO,EAAE,GAClB,OAAO,CAAC,OAAO,EAAE,CAAC,CAQpB"}
|