@astrojs/upgrade 0.0.0-10745-20240410180016

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/LICENSE ADDED
@@ -0,0 +1,59 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Fred K. Schott
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ """
24
+ This license applies to parts of the `packages/create-astro` and `packages/astro` subdirectories originating from the https://github.com/sveltejs/kit repository:
25
+
26
+ Copyright (c) 2020 [these people](https://github.com/sveltejs/kit/graphs/contributors)
27
+
28
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
29
+
30
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
31
+
32
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
+ """
34
+
35
+ """
36
+ This license applies to parts of the `packages/create-astro` and `packages/astro` subdirectories originating from the https://github.com/vitejs/vite repository:
37
+
38
+ MIT License
39
+
40
+ Copyright (c) 2019-present, Yuxi (Evan) You and Vite contributors
41
+
42
+ Permission is hereby granted, free of charge, to any person obtaining a copy
43
+ of this software and associated documentation files (the "Software"), to deal
44
+ in the Software without restriction, including without limitation the rights
45
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
46
+ copies of the Software, and to permit persons to whom the Software is
47
+ furnished to do so, subject to the following conditions:
48
+
49
+ The above copyright notice and this permission notice shall be included in all
50
+ copies or substantial portions of the Software.
51
+
52
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
58
+ SOFTWARE.
59
+ """
package/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # @astrojs/upgrade
2
+
3
+ A command-line tool for upgrading your Astro integrations and dependencies.
4
+
5
+ You can run this command in your terminal to upgrade your official Astro integrations at the same time you upgrade your version of Astro.
6
+
7
+ ## Usage
8
+
9
+ `@astrojs/upgrade` should not be added as a dependency to your project, but run as a temporary executable whenever you want to upgrade using [`npx`](https://docs.npmjs.com/cli/v10/commands/npx) or [`dlx`](https://pnpm.io/cli/dlx).
10
+
11
+ **With NPM:**
12
+
13
+ ```bash
14
+ npx @astrojs/upgrade
15
+ ```
16
+
17
+ **With Yarn:**
18
+
19
+ ```bash
20
+ yarn dlx @astrojs/upgrade
21
+ ```
22
+
23
+ **With PNPM:**
24
+
25
+ ```bash
26
+ pnpm dlx @astrojs/upgrade
27
+ ```
28
+
29
+ ## Options
30
+
31
+ ### tag (optional)
32
+
33
+ It is possible to pass a specific `tag` to resolve packages against. If not included, `@astrojs/upgrade` looks for the `latest` tag.
34
+
35
+ For example, Astro often releases `beta` versions prior to an upcoming major release. Upgrade an existing Astro project and it's dependencies to the `beta` version using one of the following commands:
36
+
37
+ **With NPM:**
38
+
39
+ ```bash
40
+ npx @astrojs/upgrade beta
41
+ ```
42
+
43
+ **With Yarn:**
44
+
45
+ ```bash
46
+ yarn dlx @astrojs/upgrade beta
47
+ ```
48
+
49
+ **With PNPM:**
50
+
51
+ ```bash
52
+ pnpm dlx @astrojs/upgrade beta
53
+ ```
package/dist/index.js ADDED
@@ -0,0 +1,762 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __commonJS = (cb, mod) => function __require() {
8
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
+ // If the importer is in node compatibility mode or this is not an ESM
20
+ // file that has been converted to a CommonJS file using a Babel-
21
+ // compatible transform (i.e. "__esModule" has not been set), then set
22
+ // "default" to the CommonJS "module.exports" for node compatibility.
23
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
+ mod
25
+ ));
26
+
27
+ // ../../node_modules/.pnpm/arg@5.0.2/node_modules/arg/index.js
28
+ var require_arg = __commonJS({
29
+ "../../node_modules/.pnpm/arg@5.0.2/node_modules/arg/index.js"(exports, module) {
30
+ var flagSymbol = Symbol("arg flag");
31
+ var ArgError = class _ArgError extends Error {
32
+ constructor(msg, code) {
33
+ super(msg);
34
+ this.name = "ArgError";
35
+ this.code = code;
36
+ Object.setPrototypeOf(this, _ArgError.prototype);
37
+ }
38
+ };
39
+ function arg2(opts, {
40
+ argv = process.argv.slice(2),
41
+ permissive = false,
42
+ stopAtPositional = false
43
+ } = {}) {
44
+ if (!opts) {
45
+ throw new ArgError(
46
+ "argument specification object is required",
47
+ "ARG_CONFIG_NO_SPEC"
48
+ );
49
+ }
50
+ const result = { _: [] };
51
+ const aliases = {};
52
+ const handlers = {};
53
+ for (const key of Object.keys(opts)) {
54
+ if (!key) {
55
+ throw new ArgError(
56
+ "argument key cannot be an empty string",
57
+ "ARG_CONFIG_EMPTY_KEY"
58
+ );
59
+ }
60
+ if (key[0] !== "-") {
61
+ throw new ArgError(
62
+ `argument key must start with '-' but found: '${key}'`,
63
+ "ARG_CONFIG_NONOPT_KEY"
64
+ );
65
+ }
66
+ if (key.length === 1) {
67
+ throw new ArgError(
68
+ `argument key must have a name; singular '-' keys are not allowed: ${key}`,
69
+ "ARG_CONFIG_NONAME_KEY"
70
+ );
71
+ }
72
+ if (typeof opts[key] === "string") {
73
+ aliases[key] = opts[key];
74
+ continue;
75
+ }
76
+ let type = opts[key];
77
+ let isFlag = false;
78
+ if (Array.isArray(type) && type.length === 1 && typeof type[0] === "function") {
79
+ const [fn] = type;
80
+ type = (value, name, prev = []) => {
81
+ prev.push(fn(value, name, prev[prev.length - 1]));
82
+ return prev;
83
+ };
84
+ isFlag = fn === Boolean || fn[flagSymbol] === true;
85
+ } else if (typeof type === "function") {
86
+ isFlag = type === Boolean || type[flagSymbol] === true;
87
+ } else {
88
+ throw new ArgError(
89
+ `type missing or not a function or valid array type: ${key}`,
90
+ "ARG_CONFIG_VAD_TYPE"
91
+ );
92
+ }
93
+ if (key[1] !== "-" && key.length > 2) {
94
+ throw new ArgError(
95
+ `short argument keys (with a single hyphen) must have only one character: ${key}`,
96
+ "ARG_CONFIG_SHORTOPT_TOOLONG"
97
+ );
98
+ }
99
+ handlers[key] = [type, isFlag];
100
+ }
101
+ for (let i = 0, len = argv.length; i < len; i++) {
102
+ const wholeArg = argv[i];
103
+ if (stopAtPositional && result._.length > 0) {
104
+ result._ = result._.concat(argv.slice(i));
105
+ break;
106
+ }
107
+ if (wholeArg === "--") {
108
+ result._ = result._.concat(argv.slice(i + 1));
109
+ break;
110
+ }
111
+ if (wholeArg.length > 1 && wholeArg[0] === "-") {
112
+ const separatedArguments = wholeArg[1] === "-" || wholeArg.length === 2 ? [wholeArg] : wholeArg.slice(1).split("").map((a) => `-${a}`);
113
+ for (let j = 0; j < separatedArguments.length; j++) {
114
+ const arg3 = separatedArguments[j];
115
+ const [originalArgName, argStr] = arg3[1] === "-" ? arg3.split(/=(.*)/, 2) : [arg3, void 0];
116
+ let argName = originalArgName;
117
+ while (argName in aliases) {
118
+ argName = aliases[argName];
119
+ }
120
+ if (!(argName in handlers)) {
121
+ if (permissive) {
122
+ result._.push(arg3);
123
+ continue;
124
+ } else {
125
+ throw new ArgError(
126
+ `unknown or unexpected option: ${originalArgName}`,
127
+ "ARG_UNKNOWN_OPTION"
128
+ );
129
+ }
130
+ }
131
+ const [type, isFlag] = handlers[argName];
132
+ if (!isFlag && j + 1 < separatedArguments.length) {
133
+ throw new ArgError(
134
+ `option requires argument (but was followed by another short argument): ${originalArgName}`,
135
+ "ARG_MISSING_REQUIRED_SHORTARG"
136
+ );
137
+ }
138
+ if (isFlag) {
139
+ result[argName] = type(true, argName, result[argName]);
140
+ } else if (argStr === void 0) {
141
+ if (argv.length < i + 2 || argv[i + 1].length > 1 && argv[i + 1][0] === "-" && !(argv[i + 1].match(/^-?\d*(\.(?=\d))?\d*$/) && (type === Number || // eslint-disable-next-line no-undef
142
+ typeof BigInt !== "undefined" && type === BigInt))) {
143
+ const extended = originalArgName === argName ? "" : ` (alias for ${argName})`;
144
+ throw new ArgError(
145
+ `option requires argument: ${originalArgName}${extended}`,
146
+ "ARG_MISSING_REQUIRED_LONGARG"
147
+ );
148
+ }
149
+ result[argName] = type(argv[i + 1], argName, result[argName]);
150
+ ++i;
151
+ } else {
152
+ result[argName] = type(argStr, argName, result[argName]);
153
+ }
154
+ }
155
+ } else {
156
+ result._.push(wholeArg);
157
+ }
158
+ }
159
+ return result;
160
+ }
161
+ arg2.flag = (fn) => {
162
+ fn[flagSymbol] = true;
163
+ return fn;
164
+ };
165
+ arg2.COUNT = arg2.flag((v, name, existingCount) => (existingCount || 0) + 1);
166
+ arg2.ArgError = ArgError;
167
+ module.exports = arg2;
168
+ }
169
+ });
170
+
171
+ // src/actions/context.ts
172
+ var import_arg = __toESM(require_arg(), 1);
173
+ import { pathToFileURL } from "node:url";
174
+ import { prompt } from "@astrojs/cli-kit";
175
+ import detectPackageManager from "which-pm-runs";
176
+ async function getContext(argv) {
177
+ const flags = (0, import_arg.default)(
178
+ {
179
+ "--dry-run": Boolean,
180
+ "--help": Boolean,
181
+ "-h": "--help"
182
+ },
183
+ { argv, permissive: true }
184
+ );
185
+ const packageManager = detectPackageManager()?.name ?? "npm";
186
+ const { _: [version = "latest"] = [], "--help": help2 = false, "--dry-run": dryRun } = flags;
187
+ return {
188
+ help: help2,
189
+ prompt,
190
+ packageManager,
191
+ packages: [],
192
+ cwd: new URL(pathToFileURL(process.cwd()) + "/"),
193
+ dryRun,
194
+ version,
195
+ exit(code) {
196
+ process.exit(code);
197
+ }
198
+ };
199
+ }
200
+
201
+ // src/messages.ts
202
+ import { color, label, spinner as load } from "@astrojs/cli-kit";
203
+ import { align } from "@astrojs/cli-kit/utils";
204
+ import terminalLink from "terminal-link";
205
+ import detectPackageManager2 from "which-pm-runs";
206
+
207
+ // src/shell.ts
208
+ import { spawn } from "node:child_process";
209
+ import { text as textFromStream } from "node:stream/consumers";
210
+ var text = (stream) => stream ? textFromStream(stream).then((t) => t.trimEnd()) : "";
211
+ var signal;
212
+ async function shell(command, flags, opts = {}) {
213
+ let child;
214
+ let stdout2 = "";
215
+ let stderr = "";
216
+ if (!signal) {
217
+ const controller = new AbortController();
218
+ process.once("beforeexit", () => controller.abort());
219
+ process.once("exit", () => controller.abort());
220
+ signal = controller.signal;
221
+ }
222
+ try {
223
+ child = spawn(command, flags, {
224
+ cwd: opts.cwd,
225
+ shell: true,
226
+ stdio: opts.stdio,
227
+ timeout: opts.timeout,
228
+ signal
229
+ });
230
+ const done2 = new Promise((resolve) => child.on("close", resolve));
231
+ [stdout2, stderr] = await Promise.all([text(child.stdout), text(child.stderr)]);
232
+ await done2;
233
+ } catch (e) {
234
+ throw { stdout: stdout2, stderr, exitCode: 1 };
235
+ }
236
+ const { exitCode } = child;
237
+ if (exitCode === null) {
238
+ throw new Error("Timeout");
239
+ }
240
+ if (exitCode !== 0) {
241
+ throw new Error(stderr);
242
+ }
243
+ return { stdout: stdout2, stderr, exitCode };
244
+ }
245
+
246
+ // src/messages.ts
247
+ var _registry;
248
+ async function getRegistry() {
249
+ if (_registry)
250
+ return _registry;
251
+ const fallback = "https://registry.npmjs.org";
252
+ const packageManager = detectPackageManager2()?.name || "npm";
253
+ try {
254
+ const { stdout: stdout2 } = await shell(packageManager, ["config", "get", "registry"]);
255
+ _registry = stdout2?.trim()?.replace(/\/$/, "") || fallback;
256
+ if (!new URL(_registry).host)
257
+ _registry = fallback;
258
+ } catch (e) {
259
+ _registry = fallback;
260
+ }
261
+ return _registry;
262
+ }
263
+ var stdout = process.stdout;
264
+ function setStdout(writable) {
265
+ stdout = writable;
266
+ }
267
+ async function spinner(args) {
268
+ await load(args, { stdout });
269
+ }
270
+ function pluralize(word, n) {
271
+ const [singular, plural] = Array.isArray(word) ? word : [word, word + "s"];
272
+ if (n === 1)
273
+ return singular;
274
+ return plural;
275
+ }
276
+ var celebrations = [
277
+ "Beautiful.",
278
+ "Excellent!",
279
+ "Sweet!",
280
+ "Nice!",
281
+ "Huzzah!",
282
+ "Success.",
283
+ "Nice.",
284
+ "Wonderful.",
285
+ "Lovely!",
286
+ "Lookin' good.",
287
+ "Awesome."
288
+ ];
289
+ var done = [
290
+ "You're on the latest and greatest.",
291
+ "Your integrations are up-to-date.",
292
+ "Everything is current.",
293
+ "Everything is up to date.",
294
+ "Integrations are all up to date.",
295
+ "Everything is on the latest and greatest.",
296
+ "Integrations are up to date."
297
+ ];
298
+ var bye = [
299
+ "Thanks for using Astro!",
300
+ "Have fun building!",
301
+ "Take it easy, astronaut!",
302
+ "Can't wait to see what you build.",
303
+ "Good luck out there.",
304
+ "See you around, astronaut."
305
+ ];
306
+ var log = (message) => stdout.write(message + "\n");
307
+ var newline = () => stdout.write("\n");
308
+ var banner = async () => log(
309
+ `
310
+ ${label("astro", color.bgGreen, color.black)} ${color.bold(
311
+ "Integration upgrade in progress."
312
+ )}`
313
+ );
314
+ var bannerAbort = () => log(`
315
+ ${label("astro", color.bgRed)} ${color.bold("Integration upgrade aborted.")}`);
316
+ var warn = async (prefix, text2) => {
317
+ log(`${label(prefix, color.bgCyan, color.black)} ${text2}`);
318
+ };
319
+ var info = async (prefix, text2, version = "") => {
320
+ const length = 11 + prefix.length + text2.length + version?.length;
321
+ const symbol = "\u25FC";
322
+ if (length > stdout.columns) {
323
+ log(`${" ".repeat(5)} ${color.cyan(symbol)} ${prefix}`);
324
+ log(`${" ".repeat(9)}${color.dim(text2)} ${color.reset(version)}`);
325
+ } else {
326
+ log(
327
+ `${" ".repeat(5)} ${color.cyan(symbol)} ${prefix} ${color.dim(text2)} ${color.reset(version)}`
328
+ );
329
+ }
330
+ };
331
+ var upgrade = async (packageInfo, text2) => {
332
+ const { name, isMajor = false, targetVersion } = packageInfo;
333
+ const bg = isMajor ? (v) => color.bgYellow(color.black(` ${v} `)) : color.green;
334
+ const style = isMajor ? color.yellow : color.green;
335
+ const symbol = isMajor ? "\u25B2" : "\u25CF";
336
+ const toVersion = targetVersion.replace(/^\D+/, "");
337
+ const version = `v${toVersion}`;
338
+ const length = 12 + name.length + text2.length + version.length;
339
+ if (length > stdout.columns) {
340
+ log(`${" ".repeat(5)} ${style(symbol)} ${name}`);
341
+ log(`${" ".repeat(9)}${color.dim(text2)} ${bg(version)}`);
342
+ } else {
343
+ log(`${" ".repeat(5)} ${style(symbol)} ${name} ${color.dim(text2)} ${bg(version)}`);
344
+ }
345
+ };
346
+ var title = (text2) => align(label(text2, color.bgYellow, color.black), "end", 7) + " ";
347
+ var success = async (prefix, text2) => {
348
+ const length = 10 + prefix.length + text2.length;
349
+ if (length > stdout.columns) {
350
+ log(`${" ".repeat(5)} ${color.green("\u2714")} ${prefix}`);
351
+ log(`${" ".repeat(9)}${color.dim(text2)}`);
352
+ } else {
353
+ log(`${" ".repeat(5)} ${color.green("\u2714")} ${prefix} ${color.dim(text2)}`);
354
+ }
355
+ };
356
+ var error = async (prefix, text2) => {
357
+ if (stdout.columns < 80) {
358
+ log(`${" ".repeat(5)} ${color.red("\u25B2")} ${color.red(prefix)}`);
359
+ log(`${" ".repeat(9)}${color.dim(text2)}`);
360
+ } else {
361
+ log(`${" ".repeat(5)} ${color.red("\u25B2")} ${color.red(prefix)} ${color.dim(text2)}`);
362
+ }
363
+ };
364
+ var changelog = async (name, text2, url) => {
365
+ const link = terminalLink(text2, url, { fallback: () => url });
366
+ const linkLength = terminalLink.isSupported ? text2.length : url.length;
367
+ const symbol = " ";
368
+ const length = 12 + name.length + linkLength;
369
+ if (length > stdout.columns) {
370
+ log(`${" ".repeat(5)} ${symbol} ${name}`);
371
+ log(`${" ".repeat(9)}${color.cyan(color.underline(link))}`);
372
+ } else {
373
+ log(`${" ".repeat(5)} ${symbol} ${name} ${color.cyan(color.underline(link))}`);
374
+ }
375
+ };
376
+ function printHelp({
377
+ commandName,
378
+ usage,
379
+ tables,
380
+ description
381
+ }) {
382
+ const linebreak = () => "";
383
+ const table = (rows, { padding }) => {
384
+ const split = stdout.columns < 60;
385
+ let raw = "";
386
+ for (const row of rows) {
387
+ if (split) {
388
+ raw += ` ${row[0]}
389
+ `;
390
+ } else {
391
+ raw += `${`${row[0]}`.padStart(padding)}`;
392
+ }
393
+ raw += " " + color.dim(row[1]) + "\n";
394
+ }
395
+ return raw.slice(0, -1);
396
+ };
397
+ let message = [];
398
+ if (usage) {
399
+ message.push(linebreak(), `${color.green(commandName)} ${color.bold(usage)}`);
400
+ }
401
+ if (tables) {
402
+ let calculateTablePadding2 = function(rows) {
403
+ return rows.reduce((val, [first]) => Math.max(val, first.length), 0);
404
+ };
405
+ var calculateTablePadding = calculateTablePadding2;
406
+ const tableEntries = Object.entries(tables);
407
+ const padding = Math.max(...tableEntries.map(([, rows]) => calculateTablePadding2(rows)));
408
+ for (const [, tableRows] of tableEntries) {
409
+ message.push(linebreak(), table(tableRows, { padding }));
410
+ }
411
+ }
412
+ if (description) {
413
+ message.push(linebreak(), `${description}`);
414
+ }
415
+ log(message.join("\n") + "\n");
416
+ }
417
+
418
+ // src/actions/help.ts
419
+ function help() {
420
+ printHelp({
421
+ commandName: "@astrojs/upgrade",
422
+ usage: "[version] [...flags]",
423
+ headline: "Upgrade Astro dependencies.",
424
+ tables: {
425
+ Flags: [
426
+ ["--help (-h)", "See all available flags."],
427
+ ["--dry-run", "Walk through steps without executing."]
428
+ ]
429
+ }
430
+ });
431
+ }
432
+
433
+ // src/actions/install.ts
434
+ import fs from "node:fs";
435
+ import path from "node:path";
436
+ import { fileURLToPath } from "node:url";
437
+ import { color as color2, say } from "@astrojs/cli-kit";
438
+ import { random, sleep } from "@astrojs/cli-kit/utils";
439
+ async function install(ctx) {
440
+ await banner();
441
+ newline();
442
+ const { current, dependencies, devDependencies } = filterPackages(ctx);
443
+ const toInstall = [...dependencies, ...devDependencies].sort(sortPackages);
444
+ for (const packageInfo of current.sort(sortPackages)) {
445
+ const tag = /^\d/.test(packageInfo.targetVersion) ? packageInfo.targetVersion : packageInfo.targetVersion.slice(1);
446
+ await info(`${packageInfo.name}`, `is up to date on`, `v${tag}`);
447
+ await sleep(random(50, 150));
448
+ }
449
+ if (toInstall.length === 0 && !ctx.dryRun) {
450
+ newline();
451
+ await success(random(celebrations), random(done));
452
+ return;
453
+ }
454
+ const majors = [];
455
+ for (const packageInfo of toInstall) {
456
+ const word = ctx.dryRun ? "can" : "will";
457
+ await upgrade(packageInfo, `${word} be updated to`);
458
+ if (packageInfo.isMajor) {
459
+ majors.push(packageInfo);
460
+ }
461
+ }
462
+ if (majors.length > 0) {
463
+ const { proceed } = await ctx.prompt({
464
+ name: "proceed",
465
+ type: "confirm",
466
+ label: title("wait"),
467
+ message: `${pluralize(
468
+ ["One package has", "Some packages have"],
469
+ majors.length
470
+ )} breaking changes. Continue?`,
471
+ initial: true
472
+ });
473
+ if (!proceed) {
474
+ return ctx.exit(0);
475
+ }
476
+ newline();
477
+ await warn("check", `Be sure to follow the ${pluralize("CHANGELOG", majors.length)}.`);
478
+ for (const pkg of majors.sort(sortPackages)) {
479
+ await changelog(pkg.name, pkg.changelogTitle, pkg.changelogURL);
480
+ }
481
+ }
482
+ newline();
483
+ if (ctx.dryRun) {
484
+ await info("--dry-run", `Skipping dependency installation`);
485
+ } else {
486
+ await runInstallCommand(ctx, dependencies, devDependencies);
487
+ }
488
+ }
489
+ function filterPackages(ctx) {
490
+ const current = [];
491
+ const dependencies = [];
492
+ const devDependencies = [];
493
+ for (const packageInfo of ctx.packages) {
494
+ const { currentVersion, targetVersion, isDevDependency } = packageInfo;
495
+ if (currentVersion.replace(/^\D+/, "") === targetVersion) {
496
+ current.push(packageInfo);
497
+ } else {
498
+ const arr = isDevDependency ? devDependencies : dependencies;
499
+ arr.push(packageInfo);
500
+ }
501
+ }
502
+ return { current, dependencies, devDependencies };
503
+ }
504
+ function sortPackages(a, b) {
505
+ if (a.isMajor && !b.isMajor)
506
+ return 1;
507
+ if (b.isMajor && !a.isMajor)
508
+ return -1;
509
+ if (a.name === "astro")
510
+ return -1;
511
+ if (b.name === "astro")
512
+ return 1;
513
+ if (a.name.startsWith("@astrojs") && !b.name.startsWith("@astrojs"))
514
+ return -1;
515
+ if (b.name.startsWith("@astrojs") && !a.name.startsWith("@astrojs"))
516
+ return 1;
517
+ return a.name.localeCompare(b.name);
518
+ }
519
+ async function runInstallCommand(ctx, dependencies, devDependencies) {
520
+ const cwd = fileURLToPath(ctx.cwd);
521
+ if (ctx.packageManager === "yarn")
522
+ await ensureYarnLock({ cwd });
523
+ const installCmd = ctx.packageManager === "yarn" || ctx.packageManager === "pnpm" ? "add" : "install";
524
+ await spinner({
525
+ start: `Installing dependencies with ${ctx.packageManager}...`,
526
+ end: `Installed dependencies!`,
527
+ while: async () => {
528
+ try {
529
+ if (dependencies.length > 0) {
530
+ await shell(
531
+ ctx.packageManager,
532
+ [
533
+ installCmd,
534
+ ...dependencies.map(
535
+ ({ name, targetVersion }) => `${name}@${targetVersion.replace(/^\^/, "")}`
536
+ )
537
+ ],
538
+ { cwd, timeout: 9e4, stdio: "ignore" }
539
+ );
540
+ }
541
+ if (devDependencies.length > 0) {
542
+ await shell(
543
+ ctx.packageManager,
544
+ [
545
+ installCmd,
546
+ "--save-dev",
547
+ ...devDependencies.map(
548
+ ({ name, targetVersion }) => `${name}@${targetVersion.replace(/^\^/, "")}`
549
+ )
550
+ ],
551
+ { cwd, timeout: 9e4, stdio: "ignore" }
552
+ );
553
+ }
554
+ } catch {
555
+ const packages = [...dependencies, ...devDependencies].map(({ name, targetVersion }) => `${name}@${targetVersion}`).join(" ");
556
+ newline();
557
+ error(
558
+ "error",
559
+ `Dependencies failed to install, please run the following command manually:
560
+ ${color2.bold(
561
+ `${ctx.packageManager} ${installCmd} ${packages}`
562
+ )}`
563
+ );
564
+ return ctx.exit(1);
565
+ }
566
+ }
567
+ });
568
+ await say([`${random(celebrations)} ${random(done)}`, random(bye)], { clear: false });
569
+ }
570
+ async function ensureYarnLock({ cwd }) {
571
+ const yarnLock = path.join(cwd, "yarn.lock");
572
+ if (fs.existsSync(yarnLock))
573
+ return;
574
+ return fs.promises.writeFile(yarnLock, "", { encoding: "utf-8" });
575
+ }
576
+
577
+ // src/actions/verify.ts
578
+ import dns from "node:dns/promises";
579
+ import { existsSync } from "node:fs";
580
+ import { readFile } from "node:fs/promises";
581
+ import { color as color3 } from "@astrojs/cli-kit";
582
+ import semverCoerce from "semver/functions/coerce.js";
583
+ import semverDiff from "semver/functions/diff.js";
584
+ import semverParse from "semver/functions/parse.js";
585
+ async function verify(ctx) {
586
+ const registry = await getRegistry();
587
+ if (!ctx.dryRun) {
588
+ const online = await isOnline(registry);
589
+ if (!online) {
590
+ bannerAbort();
591
+ newline();
592
+ error("error", `Unable to connect to the internet.`);
593
+ ctx.exit(1);
594
+ }
595
+ }
596
+ await verifyAstroProject(ctx);
597
+ const ok = await verifyVersions(ctx, registry);
598
+ if (!ok) {
599
+ bannerAbort();
600
+ newline();
601
+ error("error", `Version ${color3.reset(ctx.version)} ${color3.dim("could not be found!")}`);
602
+ await info("check", "https://github.com/withastro/astro/releases");
603
+ ctx.exit(1);
604
+ }
605
+ }
606
+ function isOnline(registry) {
607
+ const { host } = new URL(registry);
608
+ return dns.lookup(host).then(
609
+ () => true,
610
+ () => false
611
+ );
612
+ }
613
+ function safeJSONParse(value) {
614
+ try {
615
+ return JSON.parse(value);
616
+ } catch {
617
+ }
618
+ return {};
619
+ }
620
+ async function verifyAstroProject(ctx) {
621
+ const packageJson = new URL("./package.json", ctx.cwd);
622
+ if (!existsSync(packageJson))
623
+ return false;
624
+ const contents = await readFile(packageJson, { encoding: "utf-8" });
625
+ if (!contents.includes("astro"))
626
+ return false;
627
+ const { dependencies = {}, devDependencies = {} } = safeJSONParse(contents);
628
+ if (dependencies["astro"] === void 0 && devDependencies["astro"] === void 0)
629
+ return false;
630
+ collectPackageInfo(ctx, dependencies, devDependencies);
631
+ return true;
632
+ }
633
+ function isAstroPackage(name, _version) {
634
+ return name === "astro" || name.startsWith("@astrojs/");
635
+ }
636
+ function isAllowedPackage(name, _version) {
637
+ return name !== "@astrojs/upgrade";
638
+ }
639
+ function isValidVersion(_name, version) {
640
+ return semverCoerce(version, { loose: true }) !== null;
641
+ }
642
+ function isSupportedPackage(name, version) {
643
+ for (const validator of [isAstroPackage, isAllowedPackage, isValidVersion]) {
644
+ if (!validator(name, version))
645
+ return false;
646
+ }
647
+ return true;
648
+ }
649
+ function collectPackageInfo(ctx, dependencies = {}, devDependencies = {}) {
650
+ for (const [name, currentVersion] of Object.entries(dependencies)) {
651
+ if (!isSupportedPackage(name, currentVersion))
652
+ continue;
653
+ ctx.packages.push({
654
+ name,
655
+ currentVersion,
656
+ targetVersion: ctx.version
657
+ });
658
+ }
659
+ for (const [name, currentVersion] of Object.entries(devDependencies)) {
660
+ if (!isSupportedPackage(name, currentVersion))
661
+ continue;
662
+ ctx.packages.push({
663
+ name,
664
+ currentVersion,
665
+ targetVersion: ctx.version,
666
+ isDevDependency: true
667
+ });
668
+ }
669
+ }
670
+ async function verifyVersions(ctx, registry) {
671
+ const tasks = [];
672
+ for (const packageInfo of ctx.packages) {
673
+ tasks.push(resolveTargetVersion(packageInfo, registry));
674
+ }
675
+ try {
676
+ await Promise.all(tasks);
677
+ } catch {
678
+ return false;
679
+ }
680
+ for (const packageInfo of ctx.packages) {
681
+ if (!packageInfo.targetVersion) {
682
+ return false;
683
+ }
684
+ }
685
+ return true;
686
+ }
687
+ async function resolveTargetVersion(packageInfo, registry) {
688
+ const packageMetadata = await fetch(`${registry}/${packageInfo.name}`, {
689
+ headers: { accept: "application/vnd.npm.install-v1+json" }
690
+ });
691
+ if (packageMetadata.status >= 400) {
692
+ throw new Error(`Unable to resolve "${packageInfo.name}"`);
693
+ }
694
+ const { "dist-tags": distTags } = await packageMetadata.json();
695
+ let version = distTags[packageInfo.targetVersion];
696
+ if (version) {
697
+ packageInfo.tag = packageInfo.targetVersion;
698
+ packageInfo.targetVersion = version;
699
+ } else {
700
+ packageInfo.targetVersion = "latest";
701
+ version = distTags.latest;
702
+ }
703
+ if (packageInfo.currentVersion === version) {
704
+ return;
705
+ }
706
+ const prefix = packageInfo.targetVersion === "latest" ? "^" : "";
707
+ packageInfo.targetVersion = `${prefix}${version}`;
708
+ const fromVersion = semverCoerce(packageInfo.currentVersion);
709
+ const toVersion = semverParse(version);
710
+ const bump = semverDiff(fromVersion, toVersion);
711
+ if (bump === "major" && toVersion.prerelease.length === 0 || bump === "premajor") {
712
+ packageInfo.isMajor = true;
713
+ if (packageInfo.name === "astro") {
714
+ const upgradeGuide = `https://docs.astro.build/en/guides/upgrade-to/v${toVersion.major}/`;
715
+ const docsRes = await fetch(upgradeGuide);
716
+ if (docsRes.status === 200) {
717
+ packageInfo.changelogURL = upgradeGuide;
718
+ packageInfo.changelogTitle = `Upgrade to Astro v${toVersion.major}`;
719
+ return;
720
+ }
721
+ }
722
+ const latestMetadata = await fetch(`${registry}/${packageInfo.name}/latest`);
723
+ if (latestMetadata.status >= 400) {
724
+ throw new Error(`Unable to resolve "${packageInfo.name}"`);
725
+ }
726
+ const { repository } = await latestMetadata.json();
727
+ const branch = bump === "premajor" ? "next" : "main";
728
+ packageInfo.changelogURL = extractChangelogURLFromRepository(repository, version, branch);
729
+ packageInfo.changelogTitle = "CHANGELOG";
730
+ } else {
731
+ packageInfo.tag = void 0;
732
+ }
733
+ }
734
+ function extractChangelogURLFromRepository(repository, version, branch = "main") {
735
+ return repository.url.replace("git+", "").replace(".git", "") + `/blob/${branch}/` + repository.directory + "/CHANGELOG.md#" + version.replace(/\./g, "");
736
+ }
737
+
738
+ // src/index.ts
739
+ var exit = () => process.exit(0);
740
+ process.on("SIGINT", exit);
741
+ process.on("SIGTERM", exit);
742
+ async function main() {
743
+ const cleanArgv = process.argv.slice(2).filter((arg2) => arg2 !== "--");
744
+ const ctx = await getContext(cleanArgv);
745
+ if (ctx.help) {
746
+ help();
747
+ return;
748
+ }
749
+ const steps = [verify, install];
750
+ for (const step of steps) {
751
+ await step(ctx);
752
+ }
753
+ process.exit(0);
754
+ }
755
+ export {
756
+ collectPackageInfo,
757
+ getContext,
758
+ install,
759
+ main,
760
+ setStdout,
761
+ verify
762
+ };
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@astrojs/upgrade",
3
+ "version": "0.0.0-10745-20240410180016",
4
+ "type": "module",
5
+ "author": "withastro",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/withastro/astro.git",
10
+ "directory": "packages/upgrade"
11
+ },
12
+ "bugs": "https://github.com/withastro/astro/issues",
13
+ "homepage": "https://astro.build",
14
+ "exports": {
15
+ ".": "./upgrade.mjs"
16
+ },
17
+ "main": "./upgrade.mjs",
18
+ "bin": "./upgrade.mjs",
19
+ "files": [
20
+ "dist",
21
+ "upgrade.js"
22
+ ],
23
+ "//a": "MOST PACKAGES SHOULD GO IN DEV_DEPENDENCIES! THEY WILL BE BUNDLED.",
24
+ "//b": "DEPENDENCIES IS FOR UNBUNDLED PACKAGES",
25
+ "dependencies": {
26
+ "@astrojs/cli-kit": "^0.2.3",
27
+ "semver": "^7.5.4",
28
+ "which-pm-runs": "^1.1.0",
29
+ "terminal-link": "^3.0.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/semver": "^7.5.2",
33
+ "@types/which-pm-runs": "^1.0.0",
34
+ "arg": "^5.0.2",
35
+ "strip-ansi": "^7.1.0",
36
+ "astro-scripts": "0.0.14"
37
+ },
38
+ "engines": {
39
+ "node": "^18.17.1 || ^20.3.0 || >=21.0.0"
40
+ },
41
+ "scripts": {
42
+ "build": "astro-scripts build \"src/index.ts\" --bundle && tsc",
43
+ "build:ci": "astro-scripts build \"src/index.ts\" --bundle",
44
+ "dev": "astro-scripts dev \"src/**/*.ts\"",
45
+ "test": "astro-scripts test \"test/**/*.test.js\""
46
+ }
47
+ }
package/upgrade.mjs ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ /* eslint-disable no-console */
3
+ 'use strict';
4
+
5
+ const currentVersion = process.versions.node;
6
+ const requiredMajorVersion = parseInt(currentVersion.split('.')[0], 10);
7
+ const minimumMajorVersion = 18;
8
+
9
+ if (requiredMajorVersion < minimumMajorVersion) {
10
+ console.error(`Node.js v${currentVersion} is out of date and unsupported!`);
11
+ console.error(`Please use Node.js v${minimumMajorVersion} or higher.`);
12
+ process.exit(1);
13
+ }
14
+
15
+ import('./dist/index.js').then(({ main }) => main());