@backstage/cli-node 0.2.19-next.0 → 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/CHANGELOG.md +31 -0
- package/config/nodeTransform.cjs +87 -0
- package/config/nodeTransformHooks.mjs +294 -0
- package/dist/auth/CliAuth.cjs.js +108 -0
- package/dist/auth/CliAuth.cjs.js.map +1 -0
- package/dist/auth/authIdentifiers.cjs.js +8 -0
- package/dist/auth/authIdentifiers.cjs.js.map +1 -0
- package/dist/auth/httpJson.cjs.js +21 -0
- package/dist/auth/httpJson.cjs.js.map +1 -0
- package/dist/auth/secretStore.cjs.js +96 -0
- package/dist/auth/secretStore.cjs.js.map +1 -0
- package/dist/auth/storage.cjs.js +161 -0
- package/dist/auth/storage.cjs.js.map +1 -0
- package/dist/cache/SuccessCache.cjs.js +85 -0
- package/dist/cache/SuccessCache.cjs.js.map +1 -0
- package/dist/cli-internal/src/InternalCliModule.cjs.js +11 -0
- package/dist/cli-internal/src/InternalCliModule.cjs.js.map +1 -0
- package/dist/cli-internal/src/InternalCommandNode.cjs.js +25 -0
- package/dist/cli-internal/src/InternalCommandNode.cjs.js.map +1 -0
- package/dist/cli-internal/src/knownPluginPackages.cjs.js +40 -0
- package/dist/cli-internal/src/knownPluginPackages.cjs.js.map +1 -0
- package/dist/cli-module/createCliModule.cjs.js +25 -0
- package/dist/cli-module/createCliModule.cjs.js.map +1 -0
- package/dist/cli-module/runCliModule.cjs.js +138 -0
- package/dist/cli-module/runCliModule.cjs.js.map +1 -0
- package/dist/index.cjs.js +14 -4
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +320 -57
- package/dist/monorepo/Lockfile.cjs.js +20 -2
- package/dist/monorepo/Lockfile.cjs.js.map +1 -1
- package/dist/monorepo/isMonoRepo.cjs.js +1 -1
- package/dist/monorepo/isMonoRepo.cjs.js.map +1 -1
- package/dist/opaque-internal/src/OpaqueType.cjs.js +105 -0
- package/dist/opaque-internal/src/OpaqueType.cjs.js.map +1 -0
- package/dist/roles/PackageRoles.cjs.js +22 -17
- package/dist/roles/PackageRoles.cjs.js.map +1 -1
- package/dist/yarn/yarnPlugin.cjs.js +49 -0
- package/dist/yarn/yarnPlugin.cjs.js.map +1 -0
- package/package.json +29 -9
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,310 @@
|
|
|
1
1
|
import { Package } from '@manypkg/get-packages';
|
|
2
2
|
import { JsonValue } from '@backstage/types';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Options for creating a {@link CliAuth} instance.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
interface CliAuthCreateOptions {
|
|
10
|
+
/**
|
|
11
|
+
* An explicit instance name to resolve. When omitted the currently
|
|
12
|
+
* selected instance is used.
|
|
13
|
+
*/
|
|
14
|
+
instanceName?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Manages authentication state for Backstage CLI commands.
|
|
18
|
+
*
|
|
19
|
+
* Reads the currently selected (or explicitly named) auth instance from
|
|
20
|
+
* the on-disk instance store, transparently refreshes expired access
|
|
21
|
+
* tokens, and exposes helpers that other CLI modules need to talk to a
|
|
22
|
+
* Backstage backend.
|
|
23
|
+
*
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
declare class CliAuth {
|
|
27
|
+
#private;
|
|
28
|
+
/**
|
|
29
|
+
* Resolve the current auth instance and return a ready-to-use
|
|
30
|
+
* {@link CliAuth} object. Throws when no instance can be found.
|
|
31
|
+
*/
|
|
32
|
+
static create(options?: CliAuthCreateOptions): Promise<CliAuth>;
|
|
33
|
+
private constructor();
|
|
34
|
+
/** Returns the name of the resolved auth instance. */
|
|
35
|
+
getInstanceName(): string;
|
|
36
|
+
/** Returns the base URL of the resolved auth instance. */
|
|
37
|
+
getBaseUrl(): string;
|
|
38
|
+
/**
|
|
39
|
+
* Returns a valid access token, refreshing it first if the current
|
|
40
|
+
* token is expired or about to expire.
|
|
41
|
+
*/
|
|
42
|
+
getAccessToken(): Promise<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Reads a per-instance metadata value previously stored by the
|
|
45
|
+
* auth module (e.g. `pluginSources`).
|
|
46
|
+
*/
|
|
47
|
+
getMetadata(key: string): Promise<unknown>;
|
|
48
|
+
/**
|
|
49
|
+
* Writes a per-instance metadata value to the on-disk instance store.
|
|
50
|
+
*/
|
|
51
|
+
setMetadata(key: string, value: unknown): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* A file-system-based cache that tracks successful operations by storing
|
|
56
|
+
* timestamped marker files.
|
|
57
|
+
*
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
declare class SuccessCache {
|
|
61
|
+
#private;
|
|
62
|
+
/**
|
|
63
|
+
* Trim any occurrences of the workspace root path from the input string. This
|
|
64
|
+
* is useful to ensure stable hashes that don't vary based on the workspace
|
|
65
|
+
* location.
|
|
66
|
+
*/
|
|
67
|
+
static trimPaths(input: string): string;
|
|
68
|
+
static create(options: {
|
|
69
|
+
name: string;
|
|
70
|
+
basePath?: string;
|
|
71
|
+
}): SuccessCache;
|
|
72
|
+
private constructor();
|
|
73
|
+
read(): Promise<Set<string>>;
|
|
74
|
+
write(newEntries: Iterable<string>): Promise<void>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The context provided to a CLI command at the time of execution.
|
|
79
|
+
*
|
|
80
|
+
* Contains the parsed arguments and metadata about the command being run.
|
|
81
|
+
*
|
|
82
|
+
* @public
|
|
83
|
+
*/
|
|
84
|
+
interface CliCommandContext {
|
|
85
|
+
/**
|
|
86
|
+
* The remaining arguments passed to the command after the command path
|
|
87
|
+
* has been resolved. This includes both positional arguments and flags.
|
|
88
|
+
*
|
|
89
|
+
* For example, running `backstage-cli repo test --verbose src/` would
|
|
90
|
+
* result in `args` being `['--verbose', 'src/']`.
|
|
91
|
+
*/
|
|
92
|
+
args: string[];
|
|
93
|
+
/**
|
|
94
|
+
* Metadata about the command being executed.
|
|
95
|
+
*/
|
|
96
|
+
info: {
|
|
97
|
+
/**
|
|
98
|
+
* The full usage string of the command including the program name,
|
|
99
|
+
* for example `"backstage-cli repo test"`.
|
|
100
|
+
*/
|
|
101
|
+
usage: string;
|
|
102
|
+
/**
|
|
103
|
+
* The name of the command as defined by its path,
|
|
104
|
+
* for example `"repo test"`.
|
|
105
|
+
*/
|
|
106
|
+
name: string;
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A command definition for a Backstage CLI plugin.
|
|
111
|
+
*
|
|
112
|
+
* Each command is identified by a `path` that determines its position in
|
|
113
|
+
* the command tree. For example, a path of `['repo', 'test']` registers
|
|
114
|
+
* the command as `backstage-cli repo test`.
|
|
115
|
+
*
|
|
116
|
+
* Commands can either provide an `execute` function directly, or use a
|
|
117
|
+
* `loader` for deferred loading of the implementation. The loader pattern
|
|
118
|
+
* is recommended for commands with heavy dependencies, as it avoids
|
|
119
|
+
* loading the implementation until the command is actually invoked.
|
|
120
|
+
*
|
|
121
|
+
* @public
|
|
122
|
+
*/
|
|
123
|
+
interface CliCommand {
|
|
124
|
+
/**
|
|
125
|
+
* The path segments that define the command's position in the CLI tree.
|
|
126
|
+
* For example, `['repo', 'test']` maps to `backstage-cli repo test`.
|
|
127
|
+
*/
|
|
128
|
+
path: string[];
|
|
129
|
+
/**
|
|
130
|
+
* A short description of the command, displayed in help output.
|
|
131
|
+
*/
|
|
132
|
+
description: string;
|
|
133
|
+
/**
|
|
134
|
+
* If `true`, the command is deprecated and will be hidden from help output
|
|
135
|
+
* but can still be invoked.
|
|
136
|
+
*/
|
|
137
|
+
deprecated?: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* If `true`, the command is experimental and will be hidden from help
|
|
140
|
+
* output but can still be invoked.
|
|
141
|
+
*/
|
|
142
|
+
experimental?: boolean;
|
|
143
|
+
/**
|
|
144
|
+
* The command implementation, either as a direct function or as a loader
|
|
145
|
+
* that returns the implementation as a default export. The loader form
|
|
146
|
+
* is useful for deferring heavy imports until the command is invoked.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* Direct execution:
|
|
150
|
+
* ```
|
|
151
|
+
* execute: async ({ args }) => { ... }
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* Deferred loading:
|
|
156
|
+
* ```
|
|
157
|
+
* execute: { loader: () => import('./my-command') }
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
execute: ((context: CliCommandContext) => Promise<void>) | {
|
|
161
|
+
loader: () => Promise<{
|
|
162
|
+
default: (context: CliCommandContext) => Promise<void>;
|
|
163
|
+
}>;
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* An opaque representation of a Backstage CLI plugin, created
|
|
168
|
+
* using {@link createCliModule}.
|
|
169
|
+
*
|
|
170
|
+
* @public
|
|
171
|
+
*/
|
|
172
|
+
interface CliModule {
|
|
173
|
+
readonly $$type: '@backstage/CliModule';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Creates a new CLI plugin that provides commands to the Backstage CLI.
|
|
178
|
+
*
|
|
179
|
+
* The `init` callback is invoked immediately at creation time and is used
|
|
180
|
+
* to register commands via the provided registry. The commands are then
|
|
181
|
+
* made available to the CLI host once the returned promise resolves.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```
|
|
185
|
+
* import { createCliModule } from '@backstage/cli-node';
|
|
186
|
+
* import packageJson from '../package.json';
|
|
187
|
+
*
|
|
188
|
+
* export default createCliModule({
|
|
189
|
+
* packageJson,
|
|
190
|
+
* init: async reg => {
|
|
191
|
+
* reg.addCommand({
|
|
192
|
+
* path: ['repo', 'test'],
|
|
193
|
+
* description: 'Run tests across the repository',
|
|
194
|
+
* execute: { loader: () => import('./commands/test') },
|
|
195
|
+
* });
|
|
196
|
+
* },
|
|
197
|
+
* });
|
|
198
|
+
* ```
|
|
199
|
+
*
|
|
200
|
+
* @public
|
|
201
|
+
*/
|
|
202
|
+
declare function createCliModule(options: {
|
|
203
|
+
/** The `package.json` contents of the plugin package, used to identify the plugin. */
|
|
204
|
+
packageJson: {
|
|
205
|
+
name: string;
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* An initialization callback that registers commands with the CLI.
|
|
209
|
+
* Called immediately when the plugin is created.
|
|
210
|
+
*/
|
|
211
|
+
init: (registry: {
|
|
212
|
+
/** Registers a new command with the CLI. */
|
|
213
|
+
addCommand: (command: CliCommand) => void;
|
|
214
|
+
}) => Promise<void>;
|
|
215
|
+
}): CliModule;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Runs a CLI module as a standalone program.
|
|
219
|
+
*
|
|
220
|
+
* This helper extracts the commands from a {@link CliModule} and exposes
|
|
221
|
+
* them as a fully functional CLI with help output and argument parsing.
|
|
222
|
+
* It is intended to be called from a module package's `bin` entry point
|
|
223
|
+
* so that the module can be executed directly without being wired into
|
|
224
|
+
* a larger CLI host.
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```ts
|
|
228
|
+
* #!/usr/bin/env node
|
|
229
|
+
* import { runCliModule } from '@backstage/cli-node';
|
|
230
|
+
* import cliModule from './index';
|
|
231
|
+
*
|
|
232
|
+
* runCliModule({
|
|
233
|
+
* module: cliModule,
|
|
234
|
+
* name: 'backstage-auth',
|
|
235
|
+
* version: require('../package.json').version,
|
|
236
|
+
* });
|
|
237
|
+
* ```
|
|
238
|
+
*
|
|
239
|
+
* @public
|
|
240
|
+
*/
|
|
241
|
+
declare function runCliModule(options: {
|
|
242
|
+
/** The CLI module to run. */
|
|
243
|
+
module: CliModule;
|
|
244
|
+
/** The program name shown in help output and usage strings. */
|
|
245
|
+
name: string;
|
|
246
|
+
/** The version string shown when `--version` is passed. */
|
|
247
|
+
version?: string;
|
|
248
|
+
}): Promise<void>;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Options for {@link runConcurrentTasks}.
|
|
252
|
+
*
|
|
253
|
+
* @public
|
|
254
|
+
*/
|
|
255
|
+
type ConcurrentTasksOptions<TItem> = {
|
|
256
|
+
/**
|
|
257
|
+
* Decides the number of concurrent workers by multiplying
|
|
258
|
+
* this with the configured concurrency.
|
|
259
|
+
*
|
|
260
|
+
* Defaults to 1.
|
|
261
|
+
*/
|
|
262
|
+
concurrencyFactor?: number;
|
|
263
|
+
items: Iterable<TItem>;
|
|
264
|
+
worker: (item: TItem) => Promise<void>;
|
|
265
|
+
};
|
|
266
|
+
/**
|
|
267
|
+
* Runs items through a worker function concurrently across multiple async workers.
|
|
268
|
+
*
|
|
269
|
+
* @public
|
|
270
|
+
*/
|
|
271
|
+
declare function runConcurrentTasks<TItem>(options: ConcurrentTasksOptions<TItem>): Promise<void>;
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Options for {@link runWorkerQueueThreads}.
|
|
275
|
+
*
|
|
276
|
+
* @public
|
|
277
|
+
*/
|
|
278
|
+
type WorkerQueueThreadsOptions<TItem, TResult, TContext> = {
|
|
279
|
+
/** The items to process */
|
|
280
|
+
items: Iterable<TItem>;
|
|
281
|
+
/**
|
|
282
|
+
* A function that will be called within each worker thread at startup,
|
|
283
|
+
* which should return the worker function that will be called for each item.
|
|
284
|
+
*
|
|
285
|
+
* This function must be defined as an arrow function or using the
|
|
286
|
+
* function keyword, and must be entirely self contained, not referencing
|
|
287
|
+
* any variables outside of its scope. This is because the function source
|
|
288
|
+
* is stringified and evaluated in the worker thread.
|
|
289
|
+
*
|
|
290
|
+
* To pass data to the worker, use the `context` option and `items`, but
|
|
291
|
+
* note that they are both copied by value into the worker thread, except for
|
|
292
|
+
* types that are explicitly shareable across threads, such as `SharedArrayBuffer`.
|
|
293
|
+
*/
|
|
294
|
+
workerFactory: (context: TContext) => ((item: TItem) => Promise<TResult>) | Promise<(item: TItem) => Promise<TResult>>;
|
|
295
|
+
/** Context data supplied to each worker factory */
|
|
296
|
+
context?: TContext;
|
|
297
|
+
};
|
|
298
|
+
/**
|
|
299
|
+
* Spawns one or more worker threads using the `worker_threads` module.
|
|
300
|
+
* Each thread processes one item at a time from the provided `options.items`.
|
|
301
|
+
*
|
|
302
|
+
* @public
|
|
303
|
+
*/
|
|
304
|
+
declare function runWorkerQueueThreads<TItem, TResult, TContext>(options: WorkerQueueThreadsOptions<TItem, TResult, TContext>): Promise<{
|
|
305
|
+
results: TResult[];
|
|
306
|
+
}>;
|
|
307
|
+
|
|
4
308
|
/**
|
|
5
309
|
* Utilities for working with git.
|
|
6
310
|
*
|
|
@@ -19,7 +323,10 @@ declare class GitUtils {
|
|
|
19
323
|
}
|
|
20
324
|
|
|
21
325
|
/**
|
|
22
|
-
* Returns
|
|
326
|
+
* Returns true if the current project is a monorepo.
|
|
327
|
+
*
|
|
328
|
+
* Uses a simple presence check on the `workspaces` field. Empty or invalid
|
|
329
|
+
* workspace config is treated as a monorepo; we do not validate patterns.
|
|
23
330
|
*
|
|
24
331
|
* @public
|
|
25
332
|
*/
|
|
@@ -30,7 +337,7 @@ declare function isMonoRepo(): Promise<boolean>;
|
|
|
30
337
|
*
|
|
31
338
|
* @public
|
|
32
339
|
*/
|
|
33
|
-
type PackageRole = 'frontend' | 'backend' | 'cli' | 'web-library' | 'node-library' | 'common-library' | 'frontend-plugin' | 'frontend-plugin-module' | 'backend-plugin' | 'backend-plugin-module';
|
|
340
|
+
type PackageRole = 'frontend' | 'backend' | 'cli' | 'cli-module' | 'web-library' | 'node-library' | 'common-library' | 'frontend-plugin' | 'frontend-plugin-module' | 'backend-plugin' | 'backend-plugin-module';
|
|
34
341
|
/**
|
|
35
342
|
* A type of platform that a package can be built for.
|
|
36
343
|
*
|
|
@@ -286,11 +593,16 @@ declare class Lockfile {
|
|
|
286
593
|
static parse(content: string): Lockfile;
|
|
287
594
|
private readonly packages;
|
|
288
595
|
private readonly data;
|
|
596
|
+
private readonly legacy;
|
|
289
597
|
private constructor();
|
|
290
598
|
/** Returns the name of all packages available in the lockfile */
|
|
291
599
|
get(name: string): LockfileQueryEntry[] | undefined;
|
|
292
600
|
/** Get the entries for a single package in the lockfile */
|
|
293
601
|
keys(): IterableIterator<string>;
|
|
602
|
+
/**
|
|
603
|
+
* Serialize the lockfile back to a string.
|
|
604
|
+
*/
|
|
605
|
+
toString(): string;
|
|
294
606
|
/**
|
|
295
607
|
* Creates a simplified dependency graph from the lockfile data, where each
|
|
296
608
|
* key is a package, and the value is a set of all packages that it depends on
|
|
@@ -309,62 +621,13 @@ declare class Lockfile {
|
|
|
309
621
|
}
|
|
310
622
|
|
|
311
623
|
/**
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
* @public
|
|
315
|
-
*/
|
|
316
|
-
type ConcurrentTasksOptions<TItem> = {
|
|
317
|
-
/**
|
|
318
|
-
* Decides the number of concurrent workers by multiplying
|
|
319
|
-
* this with the configured concurrency.
|
|
320
|
-
*
|
|
321
|
-
* Defaults to 1.
|
|
322
|
-
*/
|
|
323
|
-
concurrencyFactor?: number;
|
|
324
|
-
items: Iterable<TItem>;
|
|
325
|
-
worker: (item: TItem) => Promise<void>;
|
|
326
|
-
};
|
|
327
|
-
/**
|
|
328
|
-
* Runs items through a worker function concurrently across multiple async workers.
|
|
329
|
-
*
|
|
330
|
-
* @public
|
|
331
|
-
*/
|
|
332
|
-
declare function runConcurrentTasks<TItem>(options: ConcurrentTasksOptions<TItem>): Promise<void>;
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Options for {@link runWorkerQueueThreads}.
|
|
336
|
-
*
|
|
337
|
-
* @public
|
|
338
|
-
*/
|
|
339
|
-
type WorkerQueueThreadsOptions<TItem, TResult, TContext> = {
|
|
340
|
-
/** The items to process */
|
|
341
|
-
items: Iterable<TItem>;
|
|
342
|
-
/**
|
|
343
|
-
* A function that will be called within each worker thread at startup,
|
|
344
|
-
* which should return the worker function that will be called for each item.
|
|
345
|
-
*
|
|
346
|
-
* This function must be defined as an arrow function or using the
|
|
347
|
-
* function keyword, and must be entirely self contained, not referencing
|
|
348
|
-
* any variables outside of its scope. This is because the function source
|
|
349
|
-
* is stringified and evaluated in the worker thread.
|
|
350
|
-
*
|
|
351
|
-
* To pass data to the worker, use the `context` option and `items`, but
|
|
352
|
-
* note that they are both copied by value into the worker thread, except for
|
|
353
|
-
* types that are explicitly shareable across threads, such as `SharedArrayBuffer`.
|
|
354
|
-
*/
|
|
355
|
-
workerFactory: (context: TContext) => ((item: TItem) => Promise<TResult>) | Promise<(item: TItem) => Promise<TResult>>;
|
|
356
|
-
/** Context data supplied to each worker factory */
|
|
357
|
-
context?: TContext;
|
|
358
|
-
};
|
|
359
|
-
/**
|
|
360
|
-
* Spawns one or more worker threads using the `worker_threads` module.
|
|
361
|
-
* Each thread processes one item at a time from the provided `options.items`.
|
|
624
|
+
* Detects whether the Backstage Yarn plugin is installed in the given workspace directory.
|
|
362
625
|
*
|
|
626
|
+
* @param workspaceDir - The workspace root directory to check. Defaults to the target root.
|
|
627
|
+
* @returns Promise resolving to true if the plugin is installed, false otherwise
|
|
363
628
|
* @public
|
|
364
629
|
*/
|
|
365
|
-
declare function
|
|
366
|
-
results: TResult[];
|
|
367
|
-
}>;
|
|
630
|
+
declare function hasBackstageYarnPlugin(workspaceDir?: string): Promise<boolean>;
|
|
368
631
|
|
|
369
|
-
export { GitUtils, Lockfile, PackageGraph, PackageRoles, isMonoRepo, packageFeatureType, runConcurrentTasks, runWorkerQueueThreads };
|
|
370
|
-
export type { BackstagePackage, BackstagePackageFeatureType, BackstagePackageJson, ConcurrentTasksOptions, LockfileDiff, LockfileDiffEntry, LockfileQueryEntry, PackageGraphNode, PackageOutputType, PackagePlatform, PackageRole, PackageRoleInfo, WorkerQueueThreadsOptions };
|
|
632
|
+
export { CliAuth, GitUtils, Lockfile, PackageGraph, PackageRoles, SuccessCache, createCliModule, hasBackstageYarnPlugin, isMonoRepo, packageFeatureType, runCliModule, runConcurrentTasks, runWorkerQueueThreads };
|
|
633
|
+
export type { BackstagePackage, BackstagePackageFeatureType, BackstagePackageJson, CliAuthCreateOptions, CliCommand, CliCommandContext, CliModule, ConcurrentTasksOptions, LockfileDiff, LockfileDiffEntry, LockfileQueryEntry, PackageGraphNode, PackageOutputType, PackagePlatform, PackageRole, PackageRoleInfo, WorkerQueueThreadsOptions };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var parsers = require('@yarnpkg/parsers');
|
|
4
|
+
var lockfile = require('@yarnpkg/lockfile');
|
|
4
5
|
var crypto = require('node:crypto');
|
|
5
6
|
var fs = require('fs-extra');
|
|
6
7
|
|
|
@@ -10,6 +11,14 @@ var crypto__default = /*#__PURE__*/_interopDefaultCompat(crypto);
|
|
|
10
11
|
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
11
12
|
|
|
12
13
|
const ENTRY_PATTERN = /^((?:@[^/]+\/)?[^@/]+)@(.+)$/;
|
|
14
|
+
const NEW_HEADER = `${[
|
|
15
|
+
`# This file is generated by running "yarn install" inside your project.
|
|
16
|
+
`,
|
|
17
|
+
`# Manual changes might be lost - proceed with caution!
|
|
18
|
+
`
|
|
19
|
+
].join(``)}
|
|
20
|
+
`;
|
|
21
|
+
const LEGACY_REGEX = /^(#.*(\r?\n))*?#\s+yarn\s+lockfile\s+v1\r?\n/i;
|
|
13
22
|
const SPECIAL_OBJECT_KEYS = [
|
|
14
23
|
`__metadata`,
|
|
15
24
|
`version`,
|
|
@@ -34,6 +43,7 @@ class Lockfile {
|
|
|
34
43
|
* @public
|
|
35
44
|
*/
|
|
36
45
|
static parse(content) {
|
|
46
|
+
const legacy = LEGACY_REGEX.test(content);
|
|
37
47
|
let data;
|
|
38
48
|
try {
|
|
39
49
|
data = parsers.parseSyml(content);
|
|
@@ -62,13 +72,15 @@ class Lockfile {
|
|
|
62
72
|
queries.push({ range, version: value.version, dataKey: key });
|
|
63
73
|
}
|
|
64
74
|
}
|
|
65
|
-
return new Lockfile(packages, data);
|
|
75
|
+
return new Lockfile(packages, data, legacy);
|
|
66
76
|
}
|
|
67
77
|
packages;
|
|
68
78
|
data;
|
|
69
|
-
|
|
79
|
+
legacy;
|
|
80
|
+
constructor(packages, data, legacy = false) {
|
|
70
81
|
this.packages = packages;
|
|
71
82
|
this.data = data;
|
|
83
|
+
this.legacy = legacy;
|
|
72
84
|
}
|
|
73
85
|
/** Returns the name of all packages available in the lockfile */
|
|
74
86
|
get(name) {
|
|
@@ -78,6 +90,12 @@ class Lockfile {
|
|
|
78
90
|
keys() {
|
|
79
91
|
return this.packages.keys();
|
|
80
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Serialize the lockfile back to a string.
|
|
95
|
+
*/
|
|
96
|
+
toString() {
|
|
97
|
+
return this.legacy ? lockfile.stringify(this.data) : NEW_HEADER + parsers.stringifySyml(this.data);
|
|
98
|
+
}
|
|
81
99
|
/**
|
|
82
100
|
* Creates a simplified dependency graph from the lockfile data, where each
|
|
83
101
|
* key is a package, and the value is a set of all packages that it depends on
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Lockfile.cjs.js","sources":["../../src/monorepo/Lockfile.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { parseSyml } from '@yarnpkg/parsers';\nimport crypto from 'node:crypto';\nimport fs from 'fs-extra';\n\nconst ENTRY_PATTERN = /^((?:@[^/]+\\/)?[^@/]+)@(.+)$/;\n\n/** @internal */\ntype LockfileData = {\n [entry: string]: {\n version: string;\n resolved?: string;\n integrity?: string /* old */;\n checksum?: string /* new */;\n dependencies?: { [name: string]: string };\n peerDependencies?: { [name: string]: string };\n };\n};\n\n/**\n * A single entry in a {@link Lockfile}.\n *\n * @public\n */\nexport type LockfileQueryEntry = {\n range: string;\n version: string;\n dataKey: string;\n};\n\n/**\n * An entry for a single difference between two {@link Lockfile}s.\n *\n * @public\n */\nexport type LockfileDiffEntry = {\n name: string;\n range: string;\n};\n\n/**\n * Represents the difference between two {@link Lockfile}s.\n *\n * @public\n */\nexport type LockfileDiff = {\n added: LockfileDiffEntry[];\n changed: LockfileDiffEntry[];\n removed: LockfileDiffEntry[];\n};\n\n// these are special top level yarn keys.\n// https://github.com/yarnpkg/berry/blob/9bd61fbffb83d0b8166a9cc26bec3a58743aa453/packages/yarnpkg-parsers/sources/syml.ts#L9\nconst SPECIAL_OBJECT_KEYS = [\n `__metadata`,\n `version`,\n `resolution`,\n `dependencies`,\n `peerDependencies`,\n `dependenciesMeta`,\n `peerDependenciesMeta`,\n `binaries`,\n];\n\n/**\n * Represents a package manager lockfile.\n *\n * @public\n */\nexport class Lockfile {\n /**\n * Load a {@link Lockfile} from a file path.\n */\n static async load(path: string): Promise<Lockfile> {\n const lockfileContents = await fs.readFile(path, 'utf8');\n return Lockfile.parse(lockfileContents);\n }\n\n /**\n * Parse lockfile contents into a {@link Lockfile}.\n *\n * @public\n */\n static parse(content: string): Lockfile {\n let data: LockfileData;\n try {\n data = parseSyml(content);\n } catch (err) {\n throw new Error(`Failed yarn.lock parse, ${err}`);\n }\n\n const packages = new Map<string, LockfileQueryEntry[]>();\n\n for (const [key, value] of Object.entries(data)) {\n if (SPECIAL_OBJECT_KEYS.includes(key)) continue;\n\n const [, name, ranges] = ENTRY_PATTERN.exec(key) ?? [];\n if (!name) {\n throw new Error(`Failed to parse yarn.lock entry '${key}'`);\n }\n\n let queries = packages.get(name);\n if (!queries) {\n queries = [];\n packages.set(name, queries);\n }\n for (let range of ranges.split(/\\s*,\\s*/)) {\n if (range.startsWith(`${name}@`)) {\n range = range.slice(`${name}@`.length);\n }\n if (range.startsWith('npm:')) {\n range = range.slice('npm:'.length);\n }\n queries.push({ range, version: value.version, dataKey: key });\n }\n }\n\n return new Lockfile(packages, data);\n }\n\n private readonly packages: Map<string, LockfileQueryEntry[]>;\n private readonly data: LockfileData;\n\n private constructor(\n packages: Map<string, LockfileQueryEntry[]>,\n data: LockfileData,\n ) {\n this.packages = packages;\n this.data = data;\n }\n\n /** Returns the name of all packages available in the lockfile */\n get(name: string): LockfileQueryEntry[] | undefined {\n return this.packages.get(name);\n }\n\n /** Get the entries for a single package in the lockfile */\n keys(): IterableIterator<string> {\n return this.packages.keys();\n }\n\n /**\n * Creates a simplified dependency graph from the lockfile data, where each\n * key is a package, and the value is a set of all packages that it depends on\n * across all versions.\n */\n createSimplifiedDependencyGraph(): Map<string, Set<string>> {\n const graph = new Map<string, Set<string>>();\n\n for (const [name, entries] of this.packages) {\n const dependencies = new Set(\n entries.flatMap(e => {\n const data = this.data[e.dataKey];\n return [\n ...Object.keys(data?.dependencies ?? {}),\n ...Object.keys(data?.peerDependencies ?? {}),\n ];\n }),\n );\n graph.set(name, dependencies);\n }\n\n return graph;\n }\n\n /**\n * Diff with another lockfile, returning entries that have been\n * added, changed, and removed compared to the other lockfile.\n */\n diff(otherLockfile: Lockfile): LockfileDiff {\n const diff = {\n added: new Array<{ name: string; range: string }>(),\n changed: new Array<{ name: string; range: string }>(),\n removed: new Array<{ name: string; range: string }>(),\n };\n\n // Keeps track of packages that only exist in this lockfile\n const remainingOldNames = new Set(this.packages.keys());\n\n for (const [name, otherQueries] of otherLockfile.packages) {\n remainingOldNames.delete(name);\n\n const thisQueries = this.packages.get(name);\n // If the packages doesn't exist in this lockfile, add all entries\n if (!thisQueries) {\n diff.removed.push(...otherQueries.map(q => ({ name, range: q.range })));\n continue;\n }\n\n const remainingOldRanges = new Set(thisQueries.map(q => q.range));\n\n for (const otherQuery of otherQueries) {\n remainingOldRanges.delete(otherQuery.range);\n\n const thisQuery = thisQueries.find(q => q.range === otherQuery.range);\n if (!thisQuery) {\n diff.removed.push({ name, range: otherQuery.range });\n continue;\n }\n\n const otherPkg = otherLockfile.data[otherQuery.dataKey];\n const thisPkg = this.data[thisQuery.dataKey];\n if (otherPkg && thisPkg) {\n const thisCheck = thisPkg.integrity || thisPkg.checksum;\n const otherCheck = otherPkg.integrity || otherPkg.checksum;\n if (thisCheck !== otherCheck) {\n diff.changed.push({ name, range: otherQuery.range });\n }\n }\n }\n\n for (const thisRange of remainingOldRanges) {\n diff.added.push({ name, range: thisRange });\n }\n }\n\n for (const name of remainingOldNames) {\n const queries = this.packages.get(name) ?? [];\n diff.added.push(...queries.map(q => ({ name, range: q.range })));\n }\n\n return diff;\n }\n\n /**\n * Generates a sha1 hex hash of the dependency graph for a package.\n */\n getDependencyTreeHash(startName: string): string {\n if (!this.packages.has(startName)) {\n throw new Error(`Package '${startName}' not found in lockfile`);\n }\n\n const hash = crypto.createHash('sha1');\n\n const queue = [startName];\n const seen = new Set<string>();\n\n while (queue.length > 0) {\n const name = queue.pop()!;\n\n if (seen.has(name)) {\n continue;\n }\n seen.add(name);\n\n const entries = this.packages.get(name);\n if (!entries) {\n continue; // In case of missing optional peer dependencies\n }\n\n hash.update(`pkg:${name}`);\n hash.update('\\0');\n\n // TODO(Rugvip): This uses the same simplified lookup as createSimplifiedDependencyGraph()\n // we could match version queries to make the resulting tree a bit smaller.\n const deps = new Array<string>();\n for (const entry of entries) {\n // We're not being particular about stable ordering here. If the lockfile ordering changes, so will likely hash.\n hash.update(entry.version);\n\n const data = this.data[entry.dataKey];\n if (!data) {\n continue;\n }\n\n const checksum = data.checksum || data.integrity;\n if (checksum) {\n hash.update('#');\n hash.update(checksum);\n }\n\n hash.update(' ');\n\n deps.push(...Object.keys(data.dependencies ?? {}));\n deps.push(...Object.keys(data.peerDependencies ?? {}));\n }\n\n queue.push(...new Set(deps));\n }\n\n return hash.digest('hex');\n }\n}\n"],"names":["fs","parseSyml","crypto"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Lockfile.cjs.js","sources":["../../src/monorepo/Lockfile.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { parseSyml, stringifySyml } from '@yarnpkg/parsers';\nimport { stringify as legacyStringifyLockfile } from '@yarnpkg/lockfile';\nimport crypto from 'node:crypto';\nimport fs from 'fs-extra';\n\nconst ENTRY_PATTERN = /^((?:@[^/]+\\/)?[^@/]+)@(.+)$/;\n\n// https://github.com/yarnpkg/berry/blob/0c5974f193a9397630e9aee2b3876cca62611149/packages/yarnpkg-core/sources/Project.ts#L1741-L1746\nconst NEW_HEADER = `${[\n `# This file is generated by running \"yarn install\" inside your project.\\n`,\n `# Manual changes might be lost - proceed with caution!\\n`,\n].join(``)}\\n`;\n\n// https://github.com/yarnpkg/berry/blob/0c5974f193a9397630e9aee2b3876cca62611149/packages/yarnpkg-parsers/sources/syml.ts#L136\nconst LEGACY_REGEX = /^(#.*(\\r?\\n))*?#\\s+yarn\\s+lockfile\\s+v1\\r?\\n/i;\n\n/** @internal */\ntype LockfileData = {\n [entry: string]: {\n version: string;\n resolved?: string;\n integrity?: string /* old */;\n checksum?: string /* new */;\n dependencies?: { [name: string]: string };\n peerDependencies?: { [name: string]: string };\n };\n};\n\n/**\n * A single entry in a {@link Lockfile}.\n *\n * @public\n */\nexport type LockfileQueryEntry = {\n range: string;\n version: string;\n dataKey: string;\n};\n\n/**\n * An entry for a single difference between two {@link Lockfile}s.\n *\n * @public\n */\nexport type LockfileDiffEntry = {\n name: string;\n range: string;\n};\n\n/**\n * Represents the difference between two {@link Lockfile}s.\n *\n * @public\n */\nexport type LockfileDiff = {\n added: LockfileDiffEntry[];\n changed: LockfileDiffEntry[];\n removed: LockfileDiffEntry[];\n};\n\n// these are special top level yarn keys.\n// https://github.com/yarnpkg/berry/blob/9bd61fbffb83d0b8166a9cc26bec3a58743aa453/packages/yarnpkg-parsers/sources/syml.ts#L9\nconst SPECIAL_OBJECT_KEYS = [\n `__metadata`,\n `version`,\n `resolution`,\n `dependencies`,\n `peerDependencies`,\n `dependenciesMeta`,\n `peerDependenciesMeta`,\n `binaries`,\n];\n\n/**\n * Represents a package manager lockfile.\n *\n * @public\n */\nexport class Lockfile {\n /**\n * Load a {@link Lockfile} from a file path.\n */\n static async load(path: string): Promise<Lockfile> {\n const lockfileContents = await fs.readFile(path, 'utf8');\n return Lockfile.parse(lockfileContents);\n }\n\n /**\n * Parse lockfile contents into a {@link Lockfile}.\n *\n * @public\n */\n static parse(content: string): Lockfile {\n const legacy = LEGACY_REGEX.test(content);\n\n let data: LockfileData;\n try {\n data = parseSyml(content);\n } catch (err) {\n throw new Error(`Failed yarn.lock parse, ${err}`);\n }\n\n const packages = new Map<string, LockfileQueryEntry[]>();\n\n for (const [key, value] of Object.entries(data)) {\n if (SPECIAL_OBJECT_KEYS.includes(key)) continue;\n\n const [, name, ranges] = ENTRY_PATTERN.exec(key) ?? [];\n if (!name) {\n throw new Error(`Failed to parse yarn.lock entry '${key}'`);\n }\n\n let queries = packages.get(name);\n if (!queries) {\n queries = [];\n packages.set(name, queries);\n }\n for (let range of ranges.split(/\\s*,\\s*/)) {\n if (range.startsWith(`${name}@`)) {\n range = range.slice(`${name}@`.length);\n }\n if (range.startsWith('npm:')) {\n range = range.slice('npm:'.length);\n }\n queries.push({ range, version: value.version, dataKey: key });\n }\n }\n\n return new Lockfile(packages, data, legacy);\n }\n\n private readonly packages: Map<string, LockfileQueryEntry[]>;\n private readonly data: LockfileData;\n private readonly legacy: boolean;\n\n private constructor(\n packages: Map<string, LockfileQueryEntry[]>,\n data: LockfileData,\n legacy: boolean = false,\n ) {\n this.packages = packages;\n this.data = data;\n this.legacy = legacy;\n }\n\n /** Returns the name of all packages available in the lockfile */\n get(name: string): LockfileQueryEntry[] | undefined {\n return this.packages.get(name);\n }\n\n /** Get the entries for a single package in the lockfile */\n keys(): IterableIterator<string> {\n return this.packages.keys();\n }\n\n /**\n * Serialize the lockfile back to a string.\n */\n toString(): string {\n return this.legacy\n ? legacyStringifyLockfile(this.data)\n : NEW_HEADER + stringifySyml(this.data);\n }\n\n /**\n * Creates a simplified dependency graph from the lockfile data, where each\n * key is a package, and the value is a set of all packages that it depends on\n * across all versions.\n */\n createSimplifiedDependencyGraph(): Map<string, Set<string>> {\n const graph = new Map<string, Set<string>>();\n\n for (const [name, entries] of this.packages) {\n const dependencies = new Set(\n entries.flatMap(e => {\n const data = this.data[e.dataKey];\n return [\n ...Object.keys(data?.dependencies ?? {}),\n ...Object.keys(data?.peerDependencies ?? {}),\n ];\n }),\n );\n graph.set(name, dependencies);\n }\n\n return graph;\n }\n\n /**\n * Diff with another lockfile, returning entries that have been\n * added, changed, and removed compared to the other lockfile.\n */\n diff(otherLockfile: Lockfile): LockfileDiff {\n const diff = {\n added: new Array<{ name: string; range: string }>(),\n changed: new Array<{ name: string; range: string }>(),\n removed: new Array<{ name: string; range: string }>(),\n };\n\n // Keeps track of packages that only exist in this lockfile\n const remainingOldNames = new Set(this.packages.keys());\n\n for (const [name, otherQueries] of otherLockfile.packages) {\n remainingOldNames.delete(name);\n\n const thisQueries = this.packages.get(name);\n // If the packages doesn't exist in this lockfile, add all entries\n if (!thisQueries) {\n diff.removed.push(...otherQueries.map(q => ({ name, range: q.range })));\n continue;\n }\n\n const remainingOldRanges = new Set(thisQueries.map(q => q.range));\n\n for (const otherQuery of otherQueries) {\n remainingOldRanges.delete(otherQuery.range);\n\n const thisQuery = thisQueries.find(q => q.range === otherQuery.range);\n if (!thisQuery) {\n diff.removed.push({ name, range: otherQuery.range });\n continue;\n }\n\n const otherPkg = otherLockfile.data[otherQuery.dataKey];\n const thisPkg = this.data[thisQuery.dataKey];\n if (otherPkg && thisPkg) {\n const thisCheck = thisPkg.integrity || thisPkg.checksum;\n const otherCheck = otherPkg.integrity || otherPkg.checksum;\n if (thisCheck !== otherCheck) {\n diff.changed.push({ name, range: otherQuery.range });\n }\n }\n }\n\n for (const thisRange of remainingOldRanges) {\n diff.added.push({ name, range: thisRange });\n }\n }\n\n for (const name of remainingOldNames) {\n const queries = this.packages.get(name) ?? [];\n diff.added.push(...queries.map(q => ({ name, range: q.range })));\n }\n\n return diff;\n }\n\n /**\n * Generates a sha1 hex hash of the dependency graph for a package.\n */\n getDependencyTreeHash(startName: string): string {\n if (!this.packages.has(startName)) {\n throw new Error(`Package '${startName}' not found in lockfile`);\n }\n\n const hash = crypto.createHash('sha1');\n\n const queue = [startName];\n const seen = new Set<string>();\n\n while (queue.length > 0) {\n const name = queue.pop()!;\n\n if (seen.has(name)) {\n continue;\n }\n seen.add(name);\n\n const entries = this.packages.get(name);\n if (!entries) {\n continue; // In case of missing optional peer dependencies\n }\n\n hash.update(`pkg:${name}`);\n hash.update('\\0');\n\n // TODO(Rugvip): This uses the same simplified lookup as createSimplifiedDependencyGraph()\n // we could match version queries to make the resulting tree a bit smaller.\n const deps = new Array<string>();\n for (const entry of entries) {\n // We're not being particular about stable ordering here. If the lockfile ordering changes, so will likely hash.\n hash.update(entry.version);\n\n const data = this.data[entry.dataKey];\n if (!data) {\n continue;\n }\n\n const checksum = data.checksum || data.integrity;\n if (checksum) {\n hash.update('#');\n hash.update(checksum);\n }\n\n hash.update(' ');\n\n deps.push(...Object.keys(data.dependencies ?? {}));\n deps.push(...Object.keys(data.peerDependencies ?? {}));\n }\n\n queue.push(...new Set(deps));\n }\n\n return hash.digest('hex');\n }\n}\n"],"names":["fs","parseSyml","legacyStringifyLockfile","stringifySyml","crypto"],"mappings":";;;;;;;;;;;;AAqBA,MAAM,aAAA,GAAgB,8BAAA;AAGtB,MAAM,aAAa,CAAA,EAAG;AAAA,EACpB,CAAA;AAAA,CAAA;AAAA,EACA,CAAA;AAAA;AACF,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC;AAAA,CAAA;AAGV,MAAM,YAAA,GAAe,+CAAA;AAgDrB,MAAM,mBAAA,GAAsB;AAAA,EAC1B,CAAA,UAAA,CAAA;AAAA,EACA,CAAA,OAAA,CAAA;AAAA,EACA,CAAA,UAAA,CAAA;AAAA,EACA,CAAA,YAAA,CAAA;AAAA,EACA,CAAA,gBAAA,CAAA;AAAA,EACA,CAAA,gBAAA,CAAA;AAAA,EACA,CAAA,oBAAA,CAAA;AAAA,EACA,CAAA,QAAA;AACF,CAAA;AAOO,MAAM,QAAA,CAAS;AAAA;AAAA;AAAA;AAAA,EAIpB,aAAa,KAAK,IAAA,EAAiC;AACjD,IAAA,MAAM,gBAAA,GAAmB,MAAMA,mBAAA,CAAG,QAAA,CAAS,MAAM,MAAM,CAAA;AACvD,IAAA,OAAO,QAAA,CAAS,MAAM,gBAAgB,CAAA;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,MAAM,OAAA,EAA2B;AACtC,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AAExC,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,IAAA,GAAOC,kBAAU,OAAO,CAAA;AAAA,IAC1B,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,GAAG,CAAA,CAAE,CAAA;AAAA,IAClD;AAEA,IAAA,MAAM,QAAA,uBAAe,GAAA,EAAkC;AAEvD,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,EAAG;AAC/C,MAAA,IAAI,mBAAA,CAAoB,QAAA,CAAS,GAAG,CAAA,EAAG;AAEvC,MAAA,MAAM,GAAG,IAAA,EAAM,MAAM,IAAI,aAAA,CAAc,IAAA,CAAK,GAAG,CAAA,IAAK,EAAC;AACrD,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoC,GAAG,CAAA,CAAA,CAAG,CAAA;AAAA,MAC5D;AAEA,MAAA,IAAI,OAAA,GAAU,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAC/B,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,OAAA,GAAU,EAAC;AACX,QAAA,QAAA,CAAS,GAAA,CAAI,MAAM,OAAO,CAAA;AAAA,MAC5B;AACA,MAAA,KAAA,IAAS,KAAA,IAAS,MAAA,CAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACzC,QAAA,IAAI,KAAA,CAAM,UAAA,CAAW,CAAA,EAAG,IAAI,GAAG,CAAA,EAAG;AAChC,UAAA,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,IAAI,IAAI,MAAM,CAAA;AAAA,QACvC;AACA,QAAA,IAAI,KAAA,CAAM,UAAA,CAAW,MAAM,CAAA,EAAG;AAC5B,UAAA,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA;AAAA,QACnC;AACA,QAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,KAAA,EAAO,OAAA,EAAS,MAAM,OAAA,EAAS,OAAA,EAAS,KAAK,CAAA;AAAA,MAC9D;AAAA,IACF;AAEA,IAAA,OAAO,IAAI,QAAA,CAAS,QAAA,EAAU,IAAA,EAAM,MAAM,CAAA;AAAA,EAC5C;AAAA,EAEiB,QAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EAET,WAAA,CACN,QAAA,EACA,IAAA,EACA,MAAA,GAAkB,KAAA,EAClB;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA;AAAA,EAGA,IAAI,IAAA,EAAgD;AAClD,IAAA,OAAO,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAAA,EAC/B;AAAA;AAAA,EAGA,IAAA,GAAiC;AAC/B,IAAA,OAAO,IAAA,CAAK,SAAS,IAAA,EAAK;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAAmB;AACjB,IAAA,OAAO,IAAA,CAAK,SACRC,kBAAA,CAAwB,IAAA,CAAK,IAAI,CAAA,GACjC,UAAA,GAAaC,qBAAA,CAAc,IAAA,CAAK,IAAI,CAAA;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,+BAAA,GAA4D;AAC1D,IAAA,MAAM,KAAA,uBAAY,GAAA,EAAyB;AAE3C,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,OAAO,CAAA,IAAK,KAAK,QAAA,EAAU;AAC3C,MAAA,MAAM,eAAe,IAAI,GAAA;AAAA,QACvB,OAAA,CAAQ,QAAQ,CAAA,CAAA,KAAK;AACnB,UAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,CAAA,CAAE,OAAO,CAAA;AAChC,UAAA,OAAO;AAAA,YACL,GAAG,MAAA,CAAO,IAAA,CAAK,IAAA,EAAM,YAAA,IAAgB,EAAE,CAAA;AAAA,YACvC,GAAG,MAAA,CAAO,IAAA,CAAK,IAAA,EAAM,gBAAA,IAAoB,EAAE;AAAA,WAC7C;AAAA,QACF,CAAC;AAAA,OACH;AACA,MAAA,KAAA,CAAM,GAAA,CAAI,MAAM,YAAY,CAAA;AAAA,IAC9B;AAEA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,aAAA,EAAuC;AAC1C,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,KAAA,EAAO,IAAI,KAAA,EAAuC;AAAA,MAClD,OAAA,EAAS,IAAI,KAAA,EAAuC;AAAA,MACpD,OAAA,EAAS,IAAI,KAAA;AAAuC,KACtD;AAGA,IAAA,MAAM,oBAAoB,IAAI,GAAA,CAAI,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA;AAEtD,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,YAAY,CAAA,IAAK,cAAc,QAAA,EAAU;AACzD,MAAA,iBAAA,CAAkB,OAAO,IAAI,CAAA;AAE7B,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAE1C,MAAA,IAAI,CAAC,WAAA,EAAa;AAChB,QAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,GAAG,YAAA,CAAa,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,CAAA,CAAE,KAAA,EAAM,CAAE,CAAC,CAAA;AACtE,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,kBAAA,GAAqB,IAAI,GAAA,CAAI,WAAA,CAAY,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,KAAK,CAAC,CAAA;AAEhE,MAAA,KAAA,MAAW,cAAc,YAAA,EAAc;AACrC,QAAA,kBAAA,CAAmB,MAAA,CAAO,WAAW,KAAK,CAAA;AAE1C,QAAA,MAAM,YAAY,WAAA,CAAY,IAAA,CAAK,OAAK,CAAA,CAAE,KAAA,KAAU,WAAW,KAAK,CAAA;AACpE,QAAA,IAAI,CAAC,SAAA,EAAW;AACd,UAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,EAAE,MAAM,KAAA,EAAO,UAAA,CAAW,OAAO,CAAA;AACnD,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,QAAA,GAAW,aAAA,CAAc,IAAA,CAAK,UAAA,CAAW,OAAO,CAAA;AACtD,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA;AAC3C,QAAA,IAAI,YAAY,OAAA,EAAS;AACvB,UAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,SAAA,IAAa,OAAA,CAAQ,QAAA;AAC/C,UAAA,MAAM,UAAA,GAAa,QAAA,CAAS,SAAA,IAAa,QAAA,CAAS,QAAA;AAClD,UAAA,IAAI,cAAc,UAAA,EAAY;AAC5B,YAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,EAAE,MAAM,KAAA,EAAO,UAAA,CAAW,OAAO,CAAA;AAAA,UACrD;AAAA,QACF;AAAA,MACF;AAEA,MAAA,KAAA,MAAW,aAAa,kBAAA,EAAoB;AAC1C,QAAA,IAAA,CAAK,MAAM,IAAA,CAAK,EAAE,IAAA,EAAM,KAAA,EAAO,WAAW,CAAA;AAAA,MAC5C;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,QAAQ,iBAAA,EAAmB;AACpC,MAAA,MAAM,UAAU,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAI,KAAK,EAAC;AAC5C,MAAA,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAG,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,CAAA,CAAE,KAAA,EAAM,CAAE,CAAC,CAAA;AAAA,IACjE;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,SAAA,EAA2B;AAC/C,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA,EAAG;AACjC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,SAAA,EAAY,SAAS,CAAA,uBAAA,CAAyB,CAAA;AAAA,IAChE;AAEA,IAAA,MAAM,IAAA,GAAOC,uBAAA,CAAO,UAAA,CAAW,MAAM,CAAA;AAErC,IAAA,MAAM,KAAA,GAAQ,CAAC,SAAS,CAAA;AACxB,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAE7B,IAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACvB,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,EAAI;AAEvB,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,EAAG;AAClB,QAAA;AAAA,MACF;AACA,MAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AAEb,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AACtC,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA;AAAA,MACF;AAEA,MAAA,IAAA,CAAK,MAAA,CAAO,CAAA,IAAA,EAAO,IAAI,CAAA,CAAE,CAAA;AACzB,MAAA,IAAA,CAAK,OAAO,IAAI,CAAA;AAIhB,MAAA,MAAM,IAAA,GAAO,IAAI,KAAA,EAAc;AAC/B,MAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAE3B,QAAA,IAAA,CAAK,MAAA,CAAO,MAAM,OAAO,CAAA;AAEzB,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AACpC,QAAA,IAAI,CAAC,IAAA,EAAM;AACT,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,SAAA;AACvC,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,IAAA,CAAK,OAAO,GAAG,CAAA;AACf,UAAA,IAAA,CAAK,OAAO,QAAQ,CAAA;AAAA,QACtB;AAEA,QAAA,IAAA,CAAK,OAAO,GAAG,CAAA;AAEf,QAAA,IAAA,CAAK,IAAA,CAAK,GAAG,MAAA,CAAO,IAAA,CAAK,KAAK,YAAA,IAAgB,EAAE,CAAC,CAAA;AACjD,QAAA,IAAA,CAAK,IAAA,CAAK,GAAG,MAAA,CAAO,IAAA,CAAK,KAAK,gBAAA,IAAoB,EAAE,CAAC,CAAA;AAAA,MACvD;AAEA,MAAA,KAAA,CAAM,IAAA,CAAK,GAAG,IAAI,GAAA,CAAI,IAAI,CAAC,CAAA;AAAA,IAC7B;AAEA,IAAA,OAAO,IAAA,CAAK,OAAO,KAAK,CAAA;AAAA,EAC1B;AACF;;;;"}
|
|
@@ -11,7 +11,7 @@ async function isMonoRepo() {
|
|
|
11
11
|
const rootPackageJsonPath = cliCommon.targetPaths.resolveRoot("package.json");
|
|
12
12
|
try {
|
|
13
13
|
const pkg = await fs__default.default.readJson(rootPackageJsonPath);
|
|
14
|
-
return Boolean(pkg?.workspaces
|
|
14
|
+
return Boolean(pkg?.workspaces);
|
|
15
15
|
} catch (error) {
|
|
16
16
|
return false;
|
|
17
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isMonoRepo.cjs.js","sources":["../../src/monorepo/isMonoRepo.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { targetPaths } from '@backstage/cli-common';\nimport fs from 'fs-extra';\n\n/**\n * Returns
|
|
1
|
+
{"version":3,"file":"isMonoRepo.cjs.js","sources":["../../src/monorepo/isMonoRepo.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { targetPaths } from '@backstage/cli-common';\nimport fs from 'fs-extra';\n\n/**\n * Returns true if the current project is a monorepo.\n *\n * Uses a simple presence check on the `workspaces` field. Empty or invalid\n * workspace config is treated as a monorepo; we do not validate patterns.\n *\n * @public\n */\nexport async function isMonoRepo(): Promise<boolean> {\n const rootPackageJsonPath = targetPaths.resolveRoot('package.json');\n try {\n const pkg = await fs.readJson(rootPackageJsonPath);\n return Boolean(pkg?.workspaces);\n } catch (error) {\n return false;\n }\n}\n"],"names":["targetPaths","fs"],"mappings":";;;;;;;;;AA2BA,eAAsB,UAAA,GAA+B;AACnD,EAAA,MAAM,mBAAA,GAAsBA,qBAAA,CAAY,WAAA,CAAY,cAAc,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAMC,mBAAA,CAAG,QAAA,CAAS,mBAAmB,CAAA;AACjD,IAAA,OAAO,OAAA,CAAQ,KAAK,UAAU,CAAA;AAAA,EAChC,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,KAAA;AAAA,EACT;AACF;;;;"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
class OpaqueType {
|
|
4
|
+
/**
|
|
5
|
+
* Creates a new opaque type.
|
|
6
|
+
*
|
|
7
|
+
* @param options.type The type identifier of the opaque type
|
|
8
|
+
* @param options.versions The available versions of the opaque type
|
|
9
|
+
* @returns A new opaque type helper
|
|
10
|
+
*/
|
|
11
|
+
static create(options) {
|
|
12
|
+
return new OpaqueType(options.type, new Set(options.versions));
|
|
13
|
+
}
|
|
14
|
+
#type;
|
|
15
|
+
#versions;
|
|
16
|
+
constructor(type, versions) {
|
|
17
|
+
this.#type = type;
|
|
18
|
+
this.#versions = versions;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The internal version of the opaque type, used like this: `typeof MyOpaqueType.TPublic`
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
*
|
|
25
|
+
* This property is only useful for type checking, its runtime value is `undefined`.
|
|
26
|
+
*/
|
|
27
|
+
TPublic = void 0;
|
|
28
|
+
/**
|
|
29
|
+
* The internal version of the opaque type, used like this: `typeof MyOpaqueType.TInternal`
|
|
30
|
+
*
|
|
31
|
+
* @remarks
|
|
32
|
+
*
|
|
33
|
+
* This property is only useful for type checking, its runtime value is `undefined`.
|
|
34
|
+
*/
|
|
35
|
+
TInternal = void 0;
|
|
36
|
+
/**
|
|
37
|
+
* @param value Input value expected to be an instance of this opaque type
|
|
38
|
+
* @returns True if the value matches this opaque type
|
|
39
|
+
*/
|
|
40
|
+
isType = (value) => {
|
|
41
|
+
return this.#isThisInternalType(value);
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* @param value Input value expected to be an instance of this opaque type
|
|
45
|
+
* @throws If the value is not an instance of this opaque type or is of an unsupported version
|
|
46
|
+
* @returns The internal version of the opaque type
|
|
47
|
+
*/
|
|
48
|
+
toInternal = (value) => {
|
|
49
|
+
if (!this.#isThisInternalType(value)) {
|
|
50
|
+
throw new TypeError(
|
|
51
|
+
`Invalid opaque type, expected '${this.#type}', but got '${this.#stringifyUnknown(value)}'`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
if (!this.#versions.has(value.version)) {
|
|
55
|
+
const versions = Array.from(this.#versions).map(this.#stringifyVersion);
|
|
56
|
+
if (versions.length > 1) {
|
|
57
|
+
versions[versions.length - 1] = `or ${versions[versions.length - 1]}`;
|
|
58
|
+
}
|
|
59
|
+
const expected = versions.length > 2 ? versions.join(", ") : versions.join(" ");
|
|
60
|
+
throw new TypeError(
|
|
61
|
+
`Invalid opaque type instance, got version ${this.#stringifyVersion(
|
|
62
|
+
value.version
|
|
63
|
+
)}, expected ${expected}`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
return value;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Creates an instance of the opaque type, returning the public type.
|
|
70
|
+
*
|
|
71
|
+
* @param version The version of the instance to create
|
|
72
|
+
* @param value The remaining public and internal properties of the instance
|
|
73
|
+
* @returns An instance of the opaque type
|
|
74
|
+
*/
|
|
75
|
+
createInstance(version, props) {
|
|
76
|
+
return Object.assign(props, {
|
|
77
|
+
$$type: this.#type,
|
|
78
|
+
...version && { version }
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
#isThisInternalType(value) {
|
|
82
|
+
if (value === null || typeof value !== "object") {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
return value.$$type === this.#type;
|
|
86
|
+
}
|
|
87
|
+
#stringifyUnknown(value) {
|
|
88
|
+
if (typeof value !== "object") {
|
|
89
|
+
return `<${typeof value}>`;
|
|
90
|
+
}
|
|
91
|
+
if (value === null) {
|
|
92
|
+
return "<null>";
|
|
93
|
+
}
|
|
94
|
+
if ("$$type" in value) {
|
|
95
|
+
return String(value.$$type);
|
|
96
|
+
}
|
|
97
|
+
return String(value);
|
|
98
|
+
}
|
|
99
|
+
#stringifyVersion = (version) => {
|
|
100
|
+
return version ? `'${version}'` : "undefined";
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
exports.OpaqueType = OpaqueType;
|
|
105
|
+
//# sourceMappingURL=OpaqueType.cjs.js.map
|