@smoothbricks/cli 0.10.1 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -13
- package/dist/cli.js +24 -0
- package/dist/github-ci/index.d.ts +17 -2
- package/dist/github-ci/index.d.ts.map +1 -1
- package/dist/github-ci/index.js +145 -14
- package/dist/github-ci/outputs.d.ts +22 -0
- package/dist/github-ci/outputs.d.ts.map +1 -0
- package/dist/github-ci/outputs.js +649 -0
- package/dist/lib/conflict-markers.d.ts.map +1 -1
- package/dist/lib/workspace.d.ts +1 -1
- package/dist/lib/workspace.d.ts.map +1 -1
- package/dist/monorepo/ci-workflow.d.ts.map +1 -1
- package/dist/monorepo/ci-workflow.js +2 -1
- package/dist/monorepo/managed-files.d.ts +2 -0
- package/dist/monorepo/managed-files.d.ts.map +1 -1
- package/dist/monorepo/managed-files.js +50 -5
- package/dist/monorepo/package-policy.d.ts.map +1 -1
- package/dist/monorepo/package-policy.js +26 -0
- package/dist/monorepo/packs/index.d.ts +3 -0
- package/dist/monorepo/packs/index.d.ts.map +1 -1
- package/dist/monorepo/packs/index.js +5 -2
- package/dist/monorepo/publish-workflow.d.ts +1 -0
- package/dist/monorepo/publish-workflow.d.ts.map +1 -1
- package/dist/monorepo/publish-workflow.js +240 -2
- package/dist/monorepo/tool-validation.d.ts.map +1 -1
- package/dist/monorepo/tool-validation.js +20 -7
- package/dist/nx/index.d.ts +6 -0
- package/dist/nx/index.d.ts.map +1 -1
- package/dist/nx/index.js +55 -5
- package/dist/release/github-release.d.ts +5 -2
- package/dist/release/github-release.d.ts.map +1 -1
- package/dist/release/github-release.js +11 -0
- package/dist/release/index.d.ts +19 -1
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +140 -31
- package/dist/release/orchestration.d.ts +8 -1
- package/dist/release/orchestration.d.ts.map +1 -1
- package/dist/release/orchestration.js +38 -1
- package/dist/wrangler/prepare-env.d.ts.map +1 -1
- package/dist/wrangler/prepare-env.js +1 -1
- package/dist/wrangler/scaffold.d.ts.map +1 -1
- package/dist/wrangler/scaffold.js +1 -1
- package/managed/raw/tooling/direnv/github-actions-bootstrap.sh +5 -0
- package/managed/raw/tooling/direnv/setup-environment.ts +32 -1
- package/managed/templates/github/actions/cache-nix-devenv/action.yml +12 -10
- package/managed/templates/github/actions/cache-node-modules/action.yml +3 -2
- package/managed/templates/github/actions/cache-nx/action.yml +2 -2
- package/managed/templates/github/actions/save-nix-devenv/action.yml +11 -3
- package/package.json +7 -14
- package/src/cli.ts +30 -4
- package/src/github-ci/index.test.ts +486 -0
- package/src/github-ci/index.ts +177 -16
- package/src/github-ci/outputs.ts +506 -0
- package/src/monorepo/__tests__/ci-workflow.test.ts +13 -0
- package/src/monorepo/__tests__/publish-workflow.test.ts +234 -5
- package/src/monorepo/ci-workflow.ts +3 -1
- package/src/monorepo/managed-files.test.ts +75 -0
- package/src/monorepo/managed-files.ts +61 -5
- package/src/monorepo/package-policy.test.ts +57 -38
- package/src/monorepo/package-policy.ts +28 -0
- package/src/monorepo/packs/index.test.ts +18 -1
- package/src/monorepo/packs/index.ts +7 -3
- package/src/monorepo/publish-workflow.ts +481 -2
- package/src/monorepo/tool-validation.test.ts +59 -24
- package/src/monorepo/tool-validation.ts +21 -7
- package/src/monorepo/wrangler.test.ts +9 -2
- package/src/nx/index.test.ts +39 -0
- package/src/nx/index.ts +65 -5
- package/src/release/__tests__/fixture-repo.test.ts +18 -16
- package/src/release/__tests__/github-release.test.ts +11 -0
- package/src/release/__tests__/orchestration.test.ts +57 -2
- package/src/release/__tests__/trust-publisher.test.ts +91 -2
- package/src/release/github-release.ts +12 -0
- package/src/release/index.ts +218 -40
- package/src/release/orchestration.ts +55 -3
- package/src/wrangler/prepare-env.ts +14 -4
- package/src/wrangler/scaffold.ts +8 -3
|
@@ -0,0 +1,649 @@
|
|
|
1
|
+
import * as _assertGuard_1 from "typia/lib/internal/_assertGuard";
|
|
2
|
+
import * as _accessExpressionAsString_1 from "typia/lib/internal/_accessExpressionAsString";
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { createReadStream } from 'node:fs';
|
|
5
|
+
import { copyFile, lstat, mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
|
|
6
|
+
import { isAbsolute, relative, resolve, sep } from 'node:path';
|
|
7
|
+
import { isRecord } from '@smoothbricks/validation';
|
|
8
|
+
import typia from 'typia';
|
|
9
|
+
import { readProjectTargets } from '../nx/index.js';
|
|
10
|
+
const parseManifest = (() => {
|
|
11
|
+
const _ao0 = (input, _path, _exceptionable = true) => (1 === input.version || _assertGuard_1._assertGuard(_exceptionable, {
|
|
12
|
+
method: "typia.json.createAssertParse",
|
|
13
|
+
path: _path + ".version",
|
|
14
|
+
expected: "1",
|
|
15
|
+
value: input.version
|
|
16
|
+
}, _errorFactory)) && ("string" === typeof input.sourceSha || _assertGuard_1._assertGuard(_exceptionable, {
|
|
17
|
+
method: "typia.json.createAssertParse",
|
|
18
|
+
path: _path + ".sourceSha",
|
|
19
|
+
expected: "string",
|
|
20
|
+
value: input.sourceSha
|
|
21
|
+
}, _errorFactory)) && ((Array.isArray(input.files) || _assertGuard_1._assertGuard(_exceptionable, {
|
|
22
|
+
method: "typia.json.createAssertParse",
|
|
23
|
+
path: _path + ".files",
|
|
24
|
+
expected: "Array<CollectedOutputFile>",
|
|
25
|
+
value: input.files
|
|
26
|
+
}, _errorFactory)) && input.files.every((elem, _index2) => ("object" === typeof elem && null !== elem || _assertGuard_1._assertGuard(_exceptionable, {
|
|
27
|
+
method: "typia.json.createAssertParse",
|
|
28
|
+
path: _path + ".files[" + _index2 + "]",
|
|
29
|
+
expected: "CollectedOutputFile",
|
|
30
|
+
value: elem
|
|
31
|
+
}, _errorFactory)) && _ao1(elem, _path + ".files[" + _index2 + "]", true && _exceptionable) || _assertGuard_1._assertGuard(_exceptionable, {
|
|
32
|
+
method: "typia.json.createAssertParse",
|
|
33
|
+
path: _path + ".files[" + _index2 + "]",
|
|
34
|
+
expected: "CollectedOutputFile",
|
|
35
|
+
value: elem
|
|
36
|
+
}, _errorFactory)) || _assertGuard_1._assertGuard(_exceptionable, {
|
|
37
|
+
method: "typia.json.createAssertParse",
|
|
38
|
+
path: _path + ".files",
|
|
39
|
+
expected: "Array<CollectedOutputFile>",
|
|
40
|
+
value: input.files
|
|
41
|
+
}, _errorFactory));
|
|
42
|
+
const _ao1 = (input, _path, _exceptionable = true) => ("string" === typeof input.project || _assertGuard_1._assertGuard(_exceptionable, {
|
|
43
|
+
method: "typia.json.createAssertParse",
|
|
44
|
+
path: _path + ".project",
|
|
45
|
+
expected: "string",
|
|
46
|
+
value: input.project
|
|
47
|
+
}, _errorFactory)) && ("string" === typeof input.target || _assertGuard_1._assertGuard(_exceptionable, {
|
|
48
|
+
method: "typia.json.createAssertParse",
|
|
49
|
+
path: _path + ".target",
|
|
50
|
+
expected: "string",
|
|
51
|
+
value: input.target
|
|
52
|
+
}, _errorFactory)) && ("string" === typeof input.output || _assertGuard_1._assertGuard(_exceptionable, {
|
|
53
|
+
method: "typia.json.createAssertParse",
|
|
54
|
+
path: _path + ".output",
|
|
55
|
+
expected: "string",
|
|
56
|
+
value: input.output
|
|
57
|
+
}, _errorFactory)) && ("string" === typeof input.path || _assertGuard_1._assertGuard(_exceptionable, {
|
|
58
|
+
method: "typia.json.createAssertParse",
|
|
59
|
+
path: _path + ".path",
|
|
60
|
+
expected: "string",
|
|
61
|
+
value: input.path
|
|
62
|
+
}, _errorFactory)) && ("number" === typeof input.size || _assertGuard_1._assertGuard(_exceptionable, {
|
|
63
|
+
method: "typia.json.createAssertParse",
|
|
64
|
+
path: _path + ".size",
|
|
65
|
+
expected: "number",
|
|
66
|
+
value: input.size
|
|
67
|
+
}, _errorFactory)) && ("string" === typeof input.sha256 || _assertGuard_1._assertGuard(_exceptionable, {
|
|
68
|
+
method: "typia.json.createAssertParse",
|
|
69
|
+
path: _path + ".sha256",
|
|
70
|
+
expected: "string",
|
|
71
|
+
value: input.sha256
|
|
72
|
+
}, _errorFactory));
|
|
73
|
+
const _io0 = input => 1 === input.version && "string" === typeof input.sourceSha && (Array.isArray(input.files) && input.files.every(elem => "object" === typeof elem && null !== elem && _io1(elem)));
|
|
74
|
+
const _io1 = input => "string" === typeof input.project && "string" === typeof input.target && "string" === typeof input.output && "string" === typeof input.path && "number" === typeof input.size && "string" === typeof input.sha256;
|
|
75
|
+
const __is = input => "object" === typeof input && null !== input && _io0(input);
|
|
76
|
+
let _errorFactory;
|
|
77
|
+
const __assert = (input, errorFactory) => {
|
|
78
|
+
if (false === __is(input)) {
|
|
79
|
+
_errorFactory = errorFactory;
|
|
80
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _assertGuard_1._assertGuard(true, {
|
|
81
|
+
method: "typia.json.createAssertParse",
|
|
82
|
+
path: _path + "",
|
|
83
|
+
expected: "CollectedOutputsManifest",
|
|
84
|
+
value: input
|
|
85
|
+
}, _errorFactory)) && _ao0(input, _path + "", true) || _assertGuard_1._assertGuard(true, {
|
|
86
|
+
method: "typia.json.createAssertParse",
|
|
87
|
+
path: _path + "",
|
|
88
|
+
expected: "CollectedOutputsManifest",
|
|
89
|
+
value: input
|
|
90
|
+
}, _errorFactory))(input, "$input", true);
|
|
91
|
+
}
|
|
92
|
+
return input;
|
|
93
|
+
};
|
|
94
|
+
return (input, errorFactory) => __assert(JSON.parse(input), errorFactory);
|
|
95
|
+
})();
|
|
96
|
+
const assertExactManifest = (() => {
|
|
97
|
+
const _ao0 = (input, _path, _exceptionable = true) => (1 === input.version || _assertGuard_1._assertGuard(_exceptionable, {
|
|
98
|
+
method: "typia.createAssertEquals",
|
|
99
|
+
path: _path + ".version",
|
|
100
|
+
expected: "1",
|
|
101
|
+
value: input.version
|
|
102
|
+
}, _errorFactory)) && ("string" === typeof input.sourceSha || _assertGuard_1._assertGuard(_exceptionable, {
|
|
103
|
+
method: "typia.createAssertEquals",
|
|
104
|
+
path: _path + ".sourceSha",
|
|
105
|
+
expected: "string",
|
|
106
|
+
value: input.sourceSha
|
|
107
|
+
}, _errorFactory)) && ((Array.isArray(input.files) || _assertGuard_1._assertGuard(_exceptionable, {
|
|
108
|
+
method: "typia.createAssertEquals",
|
|
109
|
+
path: _path + ".files",
|
|
110
|
+
expected: "Array<CollectedOutputFile>",
|
|
111
|
+
value: input.files
|
|
112
|
+
}, _errorFactory)) && input.files.every((elem, _index2) => ("object" === typeof elem && null !== elem || _assertGuard_1._assertGuard(_exceptionable, {
|
|
113
|
+
method: "typia.createAssertEquals",
|
|
114
|
+
path: _path + ".files[" + _index2 + "]",
|
|
115
|
+
expected: "CollectedOutputFile",
|
|
116
|
+
value: elem
|
|
117
|
+
}, _errorFactory)) && _ao1(elem, _path + ".files[" + _index2 + "]", true && _exceptionable) || _assertGuard_1._assertGuard(_exceptionable, {
|
|
118
|
+
method: "typia.createAssertEquals",
|
|
119
|
+
path: _path + ".files[" + _index2 + "]",
|
|
120
|
+
expected: "CollectedOutputFile",
|
|
121
|
+
value: elem
|
|
122
|
+
}, _errorFactory)) || _assertGuard_1._assertGuard(_exceptionable, {
|
|
123
|
+
method: "typia.createAssertEquals",
|
|
124
|
+
path: _path + ".files",
|
|
125
|
+
expected: "Array<CollectedOutputFile>",
|
|
126
|
+
value: input.files
|
|
127
|
+
}, _errorFactory)) && (3 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).every(key => {
|
|
128
|
+
if (["version", "sourceSha", "files"].some(prop => key === prop))
|
|
129
|
+
return true;
|
|
130
|
+
const value = input[key];
|
|
131
|
+
if (undefined === value)
|
|
132
|
+
return true;
|
|
133
|
+
return _assertGuard_1._assertGuard(_exceptionable, {
|
|
134
|
+
method: "typia.createAssertEquals",
|
|
135
|
+
path: _path + _accessExpressionAsString_1._accessExpressionAsString(key),
|
|
136
|
+
expected: "undefined",
|
|
137
|
+
value: value
|
|
138
|
+
}, _errorFactory);
|
|
139
|
+
})));
|
|
140
|
+
const _ao1 = (input, _path, _exceptionable = true) => ("string" === typeof input.project || _assertGuard_1._assertGuard(_exceptionable, {
|
|
141
|
+
method: "typia.createAssertEquals",
|
|
142
|
+
path: _path + ".project",
|
|
143
|
+
expected: "string",
|
|
144
|
+
value: input.project
|
|
145
|
+
}, _errorFactory)) && ("string" === typeof input.target || _assertGuard_1._assertGuard(_exceptionable, {
|
|
146
|
+
method: "typia.createAssertEquals",
|
|
147
|
+
path: _path + ".target",
|
|
148
|
+
expected: "string",
|
|
149
|
+
value: input.target
|
|
150
|
+
}, _errorFactory)) && ("string" === typeof input.output || _assertGuard_1._assertGuard(_exceptionable, {
|
|
151
|
+
method: "typia.createAssertEquals",
|
|
152
|
+
path: _path + ".output",
|
|
153
|
+
expected: "string",
|
|
154
|
+
value: input.output
|
|
155
|
+
}, _errorFactory)) && ("string" === typeof input.path || _assertGuard_1._assertGuard(_exceptionable, {
|
|
156
|
+
method: "typia.createAssertEquals",
|
|
157
|
+
path: _path + ".path",
|
|
158
|
+
expected: "string",
|
|
159
|
+
value: input.path
|
|
160
|
+
}, _errorFactory)) && ("number" === typeof input.size || _assertGuard_1._assertGuard(_exceptionable, {
|
|
161
|
+
method: "typia.createAssertEquals",
|
|
162
|
+
path: _path + ".size",
|
|
163
|
+
expected: "number",
|
|
164
|
+
value: input.size
|
|
165
|
+
}, _errorFactory)) && ("string" === typeof input.sha256 || _assertGuard_1._assertGuard(_exceptionable, {
|
|
166
|
+
method: "typia.createAssertEquals",
|
|
167
|
+
path: _path + ".sha256",
|
|
168
|
+
expected: "string",
|
|
169
|
+
value: input.sha256
|
|
170
|
+
}, _errorFactory)) && (6 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).every(key => {
|
|
171
|
+
if (["project", "target", "output", "path", "size", "sha256"].some(prop => key === prop))
|
|
172
|
+
return true;
|
|
173
|
+
const value = input[key];
|
|
174
|
+
if (undefined === value)
|
|
175
|
+
return true;
|
|
176
|
+
return _assertGuard_1._assertGuard(_exceptionable, {
|
|
177
|
+
method: "typia.createAssertEquals",
|
|
178
|
+
path: _path + _accessExpressionAsString_1._accessExpressionAsString(key),
|
|
179
|
+
expected: "undefined",
|
|
180
|
+
value: value
|
|
181
|
+
}, _errorFactory);
|
|
182
|
+
})));
|
|
183
|
+
const _io0 = (input, _exceptionable = true) => 1 === input.version && "string" === typeof input.sourceSha && (Array.isArray(input.files) && input.files.every((elem, _index1) => "object" === typeof elem && null !== elem && _io1(elem, true && _exceptionable))) && (3 === Object.keys(input).length || Object.keys(input).every(key => {
|
|
184
|
+
if (["version", "sourceSha", "files"].some(prop => key === prop))
|
|
185
|
+
return true;
|
|
186
|
+
const value = input[key];
|
|
187
|
+
if (undefined === value)
|
|
188
|
+
return true;
|
|
189
|
+
return false;
|
|
190
|
+
}));
|
|
191
|
+
const _io1 = (input, _exceptionable = true) => "string" === typeof input.project && "string" === typeof input.target && "string" === typeof input.output && "string" === typeof input.path && "number" === typeof input.size && "string" === typeof input.sha256 && (6 === Object.keys(input).length || Object.keys(input).every(key => {
|
|
192
|
+
if (["project", "target", "output", "path", "size", "sha256"].some(prop => key === prop))
|
|
193
|
+
return true;
|
|
194
|
+
const value = input[key];
|
|
195
|
+
if (undefined === value)
|
|
196
|
+
return true;
|
|
197
|
+
return false;
|
|
198
|
+
}));
|
|
199
|
+
const __is = (input, _exceptionable = true) => "object" === typeof input && null !== input && _io0(input, true);
|
|
200
|
+
let _errorFactory;
|
|
201
|
+
return (input, errorFactory) => {
|
|
202
|
+
if (false === __is(input)) {
|
|
203
|
+
_errorFactory = errorFactory;
|
|
204
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _assertGuard_1._assertGuard(true, {
|
|
205
|
+
method: "typia.createAssertEquals",
|
|
206
|
+
path: _path + "",
|
|
207
|
+
expected: "CollectedOutputsManifest",
|
|
208
|
+
value: input
|
|
209
|
+
}, _errorFactory)) && _ao0(input, _path + "", true) || _assertGuard_1._assertGuard(true, {
|
|
210
|
+
method: "typia.createAssertEquals",
|
|
211
|
+
path: _path + "",
|
|
212
|
+
expected: "CollectedOutputsManifest",
|
|
213
|
+
value: input
|
|
214
|
+
}, _errorFactory))(input, "$input", true);
|
|
215
|
+
}
|
|
216
|
+
return input;
|
|
217
|
+
};
|
|
218
|
+
})();
|
|
219
|
+
const GLOB_MAGIC = /[*?{[]/;
|
|
220
|
+
const GIT_SHA = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/i;
|
|
221
|
+
export async function collectNxOutputs(root, destination, runs, sourceSha) {
|
|
222
|
+
assertGitSha(sourceSha, 'Collected output source SHA');
|
|
223
|
+
const pending = [];
|
|
224
|
+
const claimedPaths = new Map();
|
|
225
|
+
for (const run of runs) {
|
|
226
|
+
for (const project of run.projects) {
|
|
227
|
+
const outputs = project.targetOutputs?.get(run.target);
|
|
228
|
+
if (!outputs || outputs.length === 0) {
|
|
229
|
+
throw new Error(`Nx target ${project.project}:${run.target} declares no outputs.`);
|
|
230
|
+
}
|
|
231
|
+
for (const declaredOutput of outputs) {
|
|
232
|
+
const output = resolveDeclaredOutput(declaredOutput, project);
|
|
233
|
+
const matchedFiles = await filesMatchingOutput(root, output);
|
|
234
|
+
if (matchedFiles.length === 0) {
|
|
235
|
+
throw new Error(`Declared output ${declaredOutput} for ${project.project}:${run.target} is missing.`);
|
|
236
|
+
}
|
|
237
|
+
for (const path of matchedFiles) {
|
|
238
|
+
const claimed = claimedPaths.get(path);
|
|
239
|
+
if (claimed) {
|
|
240
|
+
if (claimed.project === project.project &&
|
|
241
|
+
targetTransitivelyDependsOn(project, run.target, claimed.target, new Set())) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
throw new Error(`Output collision: ${path} is declared by more than one project target or output.`);
|
|
245
|
+
}
|
|
246
|
+
claimedPaths.set(path, { project: project.project, target: run.target });
|
|
247
|
+
const source = resolveWorkspacePath(root, path, 'output file');
|
|
248
|
+
const stat = await lstat(source);
|
|
249
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
250
|
+
throw new Error(`Output file must be a regular file: ${path}`);
|
|
251
|
+
}
|
|
252
|
+
pending.push({
|
|
253
|
+
project: project.project,
|
|
254
|
+
target: run.target,
|
|
255
|
+
output: declaredOutput,
|
|
256
|
+
path,
|
|
257
|
+
size: stat.size,
|
|
258
|
+
sha256: await sha256File(source),
|
|
259
|
+
source,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
pending.sort((left, right) => left.path.localeCompare(right.path));
|
|
266
|
+
await requireEmptyDestination(destination);
|
|
267
|
+
const workspace = resolve(destination, 'workspace');
|
|
268
|
+
await mkdir(workspace);
|
|
269
|
+
for (const file of pending) {
|
|
270
|
+
const staged = await prepareSafeOutputPath(workspace, file.path, 'staged output file');
|
|
271
|
+
await copyFile(file.source, staged);
|
|
272
|
+
}
|
|
273
|
+
const manifest = {
|
|
274
|
+
version: 1,
|
|
275
|
+
sourceSha,
|
|
276
|
+
files: pending.map(({ source: _source, ...file }) => file),
|
|
277
|
+
};
|
|
278
|
+
await writeFile(resolve(destination, 'manifest.json'), `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
|
|
279
|
+
return manifest;
|
|
280
|
+
}
|
|
281
|
+
export async function applyCollectedOutputs(root, directories, expectedSourceSha, projects) {
|
|
282
|
+
if (directories.length === 0) {
|
|
283
|
+
throw new Error('At least one collected output directory is required.');
|
|
284
|
+
}
|
|
285
|
+
assertGitSha(expectedSourceSha, 'Expected source SHA');
|
|
286
|
+
const resolvedProjects = projects ?? (await readProjectTargets(root));
|
|
287
|
+
const projectsByName = new Map(resolvedProjects.map((project) => [project.project, project]));
|
|
288
|
+
const overlays = [];
|
|
289
|
+
const claimedPaths = new Set();
|
|
290
|
+
for (const directory of directories) {
|
|
291
|
+
const manifestPath = resolve(directory, 'manifest.json');
|
|
292
|
+
let manifest;
|
|
293
|
+
try {
|
|
294
|
+
manifest = assertExactManifest(parseManifest(await readFile(manifestPath, 'utf8')));
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
throw new Error(`Invalid collected output manifest ${manifestPath}.`, { cause: error });
|
|
298
|
+
}
|
|
299
|
+
assertGitSha(manifest.sourceSha, `Manifest source SHA in ${manifestPath}`);
|
|
300
|
+
if (manifest.sourceSha !== expectedSourceSha) {
|
|
301
|
+
throw new Error(`Source SHA mismatch in ${manifestPath}: expected ${expectedSourceSha}, received ${manifest.sourceSha}.`);
|
|
302
|
+
}
|
|
303
|
+
const workspace = resolve(directory, 'workspace');
|
|
304
|
+
const declaredPaths = new Set();
|
|
305
|
+
for (const file of manifest.files) {
|
|
306
|
+
assertExactManifestName(file.project, 'Manifest project');
|
|
307
|
+
assertExactManifestName(file.target, 'Manifest target');
|
|
308
|
+
const project = projectsByName.get(file.project);
|
|
309
|
+
if (!project) {
|
|
310
|
+
throw new Error(`Manifest references unknown Nx project ${file.project}.`);
|
|
311
|
+
}
|
|
312
|
+
if (!project.targets.includes(file.target)) {
|
|
313
|
+
throw new Error(`Manifest references unknown Nx target ${file.project}:${file.target}.`);
|
|
314
|
+
}
|
|
315
|
+
const declaredOutputs = project.targetOutputs?.get(file.target) ?? [];
|
|
316
|
+
if (!declaredOutputs.includes(file.output)) {
|
|
317
|
+
throw new Error(`Manifest output ${file.output} is not declared by Nx target ${file.project}:${file.target}.`);
|
|
318
|
+
}
|
|
319
|
+
const path = validateWorkspaceRelativePath(file.path, 'manifest file path');
|
|
320
|
+
const output = resolveDeclaredOutput(file.output, project);
|
|
321
|
+
if (!outputContainsPath(output, path)) {
|
|
322
|
+
throw new Error(`Manifest file ${path} is not contained by declared output ${file.output}.`);
|
|
323
|
+
}
|
|
324
|
+
if (declaredPaths.has(path)) {
|
|
325
|
+
throw new Error(`Manifest contains a duplicate output file: ${path}`);
|
|
326
|
+
}
|
|
327
|
+
if (claimedPaths.has(path)) {
|
|
328
|
+
throw new Error(`Output collision across collected trees: ${path}`);
|
|
329
|
+
}
|
|
330
|
+
declaredPaths.add(path);
|
|
331
|
+
claimedPaths.add(path);
|
|
332
|
+
const source = resolveWorkspacePath(workspace, path, 'staged output file');
|
|
333
|
+
let stat;
|
|
334
|
+
try {
|
|
335
|
+
stat = await lstat(source);
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
throw new Error(`Staged output file is missing: ${path}`, { cause: error });
|
|
339
|
+
}
|
|
340
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
341
|
+
throw new Error(`Staged output must be a regular file: ${path}`);
|
|
342
|
+
}
|
|
343
|
+
if (stat.size !== file.size) {
|
|
344
|
+
throw new Error(`Size mismatch for staged output ${path}: expected ${file.size}, received ${stat.size}.`);
|
|
345
|
+
}
|
|
346
|
+
const checksum = await sha256File(source);
|
|
347
|
+
if (checksum !== file.sha256) {
|
|
348
|
+
throw new Error(`SHA-256 mismatch for staged output ${path}.`);
|
|
349
|
+
}
|
|
350
|
+
overlays.push({ source, destination: path });
|
|
351
|
+
}
|
|
352
|
+
let workspaceStat;
|
|
353
|
+
try {
|
|
354
|
+
workspaceStat = await lstat(workspace);
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
// Artifact transports omit empty directories, so an empty manifest is the complete transferable contract.
|
|
358
|
+
if (manifest.files.length === 0 && isMissingPathError(error)) {
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
throw new Error(`Collected output workspace is missing: ${workspace}`, { cause: error });
|
|
362
|
+
}
|
|
363
|
+
if (workspaceStat.isSymbolicLink() || !workspaceStat.isDirectory()) {
|
|
364
|
+
throw new Error(`Collected output workspace must be a real directory: ${workspace}`);
|
|
365
|
+
}
|
|
366
|
+
const stagedFiles = await listRegularFiles(workspace);
|
|
367
|
+
for (const stagedFile of stagedFiles) {
|
|
368
|
+
const path = workspaceRelativePath(workspace, stagedFile, 'staged output file');
|
|
369
|
+
if (!declaredPaths.has(path)) {
|
|
370
|
+
throw new Error(`Undeclared staged output file: ${path}`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
for (const overlay of overlays) {
|
|
375
|
+
const destination = await prepareSafeOutputPath(root, overlay.destination, 'workspace output file');
|
|
376
|
+
await copyFile(overlay.source, destination);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
export function resolveDeclaredOutput(declaredOutput, project) {
|
|
380
|
+
if (!project.root) {
|
|
381
|
+
throw new Error(`Nx project ${project.project} is missing its resolved root.`);
|
|
382
|
+
}
|
|
383
|
+
const substituted = declaredOutput
|
|
384
|
+
.replaceAll('{workspaceRoot}/', '')
|
|
385
|
+
.replaceAll('{workspaceRoot}', '.')
|
|
386
|
+
.replaceAll('{projectRoot}/', `${project.root}/`)
|
|
387
|
+
.replaceAll('{projectRoot}', project.root);
|
|
388
|
+
if (hasUnsupportedOutputBraces(substituted)) {
|
|
389
|
+
throw new Error(`Unsupported Nx output placeholder in ${project.project}:${declaredOutput}`);
|
|
390
|
+
}
|
|
391
|
+
return validateWorkspaceRelativePattern(substituted, `output for ${project.project}`);
|
|
392
|
+
}
|
|
393
|
+
function hasUnsupportedOutputBraces(value) {
|
|
394
|
+
let cursor = 0;
|
|
395
|
+
while (cursor < value.length) {
|
|
396
|
+
const character = value.charCodeAt(cursor);
|
|
397
|
+
if (character === 0x7d) {
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
if (character !== 0x7b) {
|
|
401
|
+
cursor += 1;
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
let hasAlternative = false;
|
|
405
|
+
cursor += 1;
|
|
406
|
+
while (cursor < value.length && value.charCodeAt(cursor) !== 0x7d) {
|
|
407
|
+
const inner = value.charCodeAt(cursor);
|
|
408
|
+
if (inner === 0x7b) {
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
411
|
+
hasAlternative ||= inner === 0x2c;
|
|
412
|
+
cursor += 1;
|
|
413
|
+
}
|
|
414
|
+
if (cursor === value.length || !hasAlternative) {
|
|
415
|
+
return true;
|
|
416
|
+
}
|
|
417
|
+
cursor += 1;
|
|
418
|
+
}
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
421
|
+
function targetTransitivelyDependsOn(project, target, candidate, visited) {
|
|
422
|
+
if (visited.has(target)) {
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
visited.add(target);
|
|
426
|
+
for (const dependency of project.targetDependencies?.get(target) ?? []) {
|
|
427
|
+
if (dependency.startsWith('^')) {
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
const targets = GLOB_MAGIC.test(dependency)
|
|
431
|
+
? project.targets.filter((entry) => new Bun.Glob(dependency).match(entry))
|
|
432
|
+
: [dependency];
|
|
433
|
+
if (targets.includes(candidate) ||
|
|
434
|
+
targets.some((dependencyTarget) => targetTransitivelyDependsOn(project, dependencyTarget, candidate, visited))) {
|
|
435
|
+
return true;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return false;
|
|
439
|
+
}
|
|
440
|
+
async function filesMatchingOutput(root, output) {
|
|
441
|
+
if (!GLOB_MAGIC.test(output)) {
|
|
442
|
+
const path = resolveWorkspacePath(root, output, 'declared output');
|
|
443
|
+
try {
|
|
444
|
+
await assertNoSymlinkTraversal(root, output, 'declared output');
|
|
445
|
+
const stat = await lstat(path);
|
|
446
|
+
if (stat.isSymbolicLink()) {
|
|
447
|
+
throw new Error(`Declared output must not be a symbolic link: ${output}`);
|
|
448
|
+
}
|
|
449
|
+
if (stat.isFile()) {
|
|
450
|
+
return [output];
|
|
451
|
+
}
|
|
452
|
+
if (stat.isDirectory()) {
|
|
453
|
+
return (await listRegularFiles(path)).map((file) => workspaceRelativePath(root, file, 'output file')).sort();
|
|
454
|
+
}
|
|
455
|
+
return [];
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
if (isMissingPathError(error)) {
|
|
459
|
+
return [];
|
|
460
|
+
}
|
|
461
|
+
throw error;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
const globBase = output.slice(0, output.search(GLOB_MAGIC)).replace(/\/+$/, '');
|
|
465
|
+
if (globBase) {
|
|
466
|
+
try {
|
|
467
|
+
await assertNoSymlinkTraversal(root, globBase, 'declared output');
|
|
468
|
+
}
|
|
469
|
+
catch (error) {
|
|
470
|
+
if (isMissingPathError(error)) {
|
|
471
|
+
return [];
|
|
472
|
+
}
|
|
473
|
+
throw error;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
const files = new Set();
|
|
477
|
+
for await (const match of new Bun.Glob(output).scan({
|
|
478
|
+
cwd: root,
|
|
479
|
+
dot: true,
|
|
480
|
+
followSymlinks: false,
|
|
481
|
+
onlyFiles: false,
|
|
482
|
+
})) {
|
|
483
|
+
const path = resolveWorkspacePath(root, match, 'globbed output');
|
|
484
|
+
await assertNoSymlinkTraversal(root, match, 'globbed output');
|
|
485
|
+
const stat = await lstat(path);
|
|
486
|
+
if (stat.isSymbolicLink()) {
|
|
487
|
+
throw new Error(`Declared output must not contain a symbolic link: ${match}`);
|
|
488
|
+
}
|
|
489
|
+
if (stat.isFile()) {
|
|
490
|
+
files.add(validateWorkspaceRelativePath(match, 'globbed output'));
|
|
491
|
+
}
|
|
492
|
+
else if (stat.isDirectory()) {
|
|
493
|
+
for (const file of await listRegularFiles(path)) {
|
|
494
|
+
files.add(workspaceRelativePath(root, file, 'output file'));
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
return [...files].sort((left, right) => left.localeCompare(right));
|
|
499
|
+
}
|
|
500
|
+
async function listRegularFiles(directory) {
|
|
501
|
+
let entries;
|
|
502
|
+
try {
|
|
503
|
+
entries = await readdir(directory, { withFileTypes: true });
|
|
504
|
+
}
|
|
505
|
+
catch (error) {
|
|
506
|
+
if (isMissingPathError(error)) {
|
|
507
|
+
return [];
|
|
508
|
+
}
|
|
509
|
+
throw error;
|
|
510
|
+
}
|
|
511
|
+
entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
512
|
+
const files = [];
|
|
513
|
+
for (const entry of entries) {
|
|
514
|
+
const path = resolve(directory, entry.name);
|
|
515
|
+
if (entry.isSymbolicLink()) {
|
|
516
|
+
throw new Error(`Collected outputs must not contain symbolic links: ${path}`);
|
|
517
|
+
}
|
|
518
|
+
if (entry.isDirectory()) {
|
|
519
|
+
files.push(...(await listRegularFiles(path)));
|
|
520
|
+
}
|
|
521
|
+
else if (entry.isFile()) {
|
|
522
|
+
files.push(path);
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
throw new Error(`Collected outputs must contain only regular files: ${path}`);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
return files;
|
|
529
|
+
}
|
|
530
|
+
function assertExactManifestName(value, description) {
|
|
531
|
+
if (!value || GLOB_MAGIC.test(value)) {
|
|
532
|
+
throw new Error(`${description} must be an exact Nx name: ${value}`);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
function validateWorkspaceRelativePattern(value, description) {
|
|
536
|
+
const normalized = value
|
|
537
|
+
.replaceAll('\\', '/')
|
|
538
|
+
.replace(/^\.\//, '')
|
|
539
|
+
.replace(/\/{2,}/g, '/');
|
|
540
|
+
if (!normalized || normalized === '.' || isAbsolute(normalized) || normalized.split('/').includes('..')) {
|
|
541
|
+
throw new Error(`${description} escapes the workspace: ${value}`);
|
|
542
|
+
}
|
|
543
|
+
return normalized;
|
|
544
|
+
}
|
|
545
|
+
function validateWorkspaceRelativePath(value, description) {
|
|
546
|
+
const normalized = validateWorkspaceRelativePattern(value, description);
|
|
547
|
+
if (GLOB_MAGIC.test(normalized)) {
|
|
548
|
+
throw new Error(`${description} must not contain glob syntax: ${value}`);
|
|
549
|
+
}
|
|
550
|
+
return normalized;
|
|
551
|
+
}
|
|
552
|
+
function resolveWorkspacePath(root, path, description) {
|
|
553
|
+
const validated = validateWorkspaceRelativePath(path, description);
|
|
554
|
+
const resolvedRoot = resolve(root);
|
|
555
|
+
const resolvedPath = resolve(resolvedRoot, ...validated.split('/'));
|
|
556
|
+
const fromRoot = relative(resolvedRoot, resolvedPath);
|
|
557
|
+
if (fromRoot === '..' || fromRoot.startsWith(`..${sep}`) || isAbsolute(fromRoot)) {
|
|
558
|
+
throw new Error(`${description} escapes the workspace: ${path}`);
|
|
559
|
+
}
|
|
560
|
+
return resolvedPath;
|
|
561
|
+
}
|
|
562
|
+
function workspaceRelativePath(root, path, description) {
|
|
563
|
+
return validateWorkspaceRelativePath(relative(resolve(root), resolve(path)).replaceAll(sep, '/'), description);
|
|
564
|
+
}
|
|
565
|
+
function outputContainsPath(output, path) {
|
|
566
|
+
return GLOB_MAGIC.test(output) ? new Bun.Glob(output).match(path) : path === output || path.startsWith(`${output}/`);
|
|
567
|
+
}
|
|
568
|
+
async function requireEmptyDestination(destination) {
|
|
569
|
+
try {
|
|
570
|
+
const stat = await lstat(destination);
|
|
571
|
+
if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
|
572
|
+
throw new Error(`Output collection path must be a real directory: ${destination}`);
|
|
573
|
+
}
|
|
574
|
+
const entries = await readdir(destination);
|
|
575
|
+
if (entries.length > 0) {
|
|
576
|
+
throw new Error(`Output collection directory must be empty: ${destination}`);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
catch (error) {
|
|
580
|
+
if (!isMissingPathError(error)) {
|
|
581
|
+
throw error;
|
|
582
|
+
}
|
|
583
|
+
await mkdir(destination, { recursive: true });
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
async function assertNoSymlinkTraversal(root, path, description) {
|
|
587
|
+
const validated = validateWorkspaceRelativePath(path, description);
|
|
588
|
+
let current = resolve(root);
|
|
589
|
+
const rootStat = await lstat(current);
|
|
590
|
+
if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
|
|
591
|
+
throw new Error(`${description} root must be a real directory: ${current}`);
|
|
592
|
+
}
|
|
593
|
+
for (const segment of validated.split('/')) {
|
|
594
|
+
current = resolve(current, segment);
|
|
595
|
+
const stat = await lstat(current);
|
|
596
|
+
if (stat.isSymbolicLink()) {
|
|
597
|
+
throw new Error(`${description} must not traverse a symbolic link: ${path}`);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
async function prepareSafeOutputPath(root, path, description) {
|
|
602
|
+
const validated = validateWorkspaceRelativePath(path, description);
|
|
603
|
+
const resolvedRoot = resolve(root);
|
|
604
|
+
const rootStat = await lstat(resolvedRoot);
|
|
605
|
+
if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
|
|
606
|
+
throw new Error(`${description} root must be a real directory: ${resolvedRoot}`);
|
|
607
|
+
}
|
|
608
|
+
let current = resolvedRoot;
|
|
609
|
+
const segments = validated.split('/');
|
|
610
|
+
for (const [index, segment] of segments.entries()) {
|
|
611
|
+
current = resolve(current, segment);
|
|
612
|
+
const isDestination = index === segments.length - 1;
|
|
613
|
+
try {
|
|
614
|
+
const stat = await lstat(current);
|
|
615
|
+
if (stat.isSymbolicLink()) {
|
|
616
|
+
throw new Error(`${description} must not traverse a symbolic link: ${path}`);
|
|
617
|
+
}
|
|
618
|
+
if (isDestination ? !stat.isFile() : !stat.isDirectory()) {
|
|
619
|
+
throw new Error(`${description} has an invalid existing path component: ${path}`);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
catch (error) {
|
|
623
|
+
if (!isMissingPathError(error)) {
|
|
624
|
+
throw error;
|
|
625
|
+
}
|
|
626
|
+
if (!isDestination) {
|
|
627
|
+
await mkdir(current);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
return current;
|
|
632
|
+
}
|
|
633
|
+
function assertGitSha(value, description) {
|
|
634
|
+
if (!GIT_SHA.test(value)) {
|
|
635
|
+
throw new Error(`${description} must be a 40- or 64-character hexadecimal Git SHA.`);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
function isMissingPathError(error) {
|
|
639
|
+
return isRecord(error) && error.code === 'ENOENT';
|
|
640
|
+
}
|
|
641
|
+
function sha256File(path) {
|
|
642
|
+
return new Promise((resolveHash, reject) => {
|
|
643
|
+
const hash = createHash('sha256');
|
|
644
|
+
const stream = createReadStream(path);
|
|
645
|
+
stream.on('data', (chunk) => hash.update(chunk));
|
|
646
|
+
stream.on('error', reject);
|
|
647
|
+
stream.on('end', () => resolveHash(hash.digest('hex')));
|
|
648
|
+
});
|
|
649
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict-markers.d.ts","sourceRoot":"","sources":["../../src/lib/conflict-markers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,gDAAgD,CAAC;AAIrF,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAStD;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,CACP,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClE;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAW9B;AAED,uFAAuF;AACvF,qBAAa,oBAAqB,SAAQ,KAAK;IAE3C,QAAQ,CAAC,IAAI,EAAE,iBAAiB,EAAE;
|
|
1
|
+
{"version":3,"file":"conflict-markers.d.ts","sourceRoot":"","sources":["../../src/lib/conflict-markers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,gDAAgD,CAAC;AAIrF,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAStD;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,CACP,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClE;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAW9B;AAED,uFAAuF;AACvF,qBAAa,oBAAqB,SAAQ,KAAK;IAE3C,QAAQ,CAAC,IAAI,EAAE,iBAAiB,EAAE;IADpC,YACW,IAAI,EAAE,iBAAiB,EAAE,EAClC,OAAO,EAAE,MAAM,EAIhB;CACF;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKlH;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAkB9B;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAAE,CA2BhE;AAED,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAElE"}
|
package/dist/lib/workspace.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export interface RepositoryInfo {
|
|
|
30
30
|
type: string;
|
|
31
31
|
url: string;
|
|
32
32
|
}
|
|
33
|
-
export declare const workspaceDependencyFields: readonly [
|
|
33
|
+
export declare const workspaceDependencyFields: readonly ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'];
|
|
34
34
|
export declare function listPublicPackages(root: string): PackageInfo[];
|
|
35
35
|
export declare function listReleasePackages(root: string, rootPackage?: PackageInfo | null): PackageInfo[];
|
|
36
36
|
export declare function rootRepositoryInfo(root: string): RepositoryInfo | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/lib/workspace.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,WAAY,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,yBAAyB,
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/lib/workspace.ts"],"names":[],"mappings":"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"}
|