@lightnet/cli 4.4.1 → 4.4.2
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 +14 -0
- package/package.json +3 -3
- package/src/check-files.js +86 -20
- package/src/check-links.js +21 -11
- package/src/check-translations.js +16 -8
- package/src/index.js +26 -15
- package/src/support/prompt-cancel.js +13 -0
- package/src/support/r2.js +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @lightnet/cli
|
|
2
2
|
|
|
3
|
+
## 4.4.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#433](https://github.com/LightNetDev/LightNet/pull/433) [`dbde36e`](https://github.com/LightNetDev/LightNet/commit/dbde36e7a25bf6470783e9594260b666e09c2783) - Make `check-files` summaries clearer by explaining what was compared and what needs attention.
|
|
8
|
+
|
|
9
|
+
- [#433](https://github.com/LightNetDev/LightNet/pull/433) [`dbde36e`](https://github.com/LightNetDev/LightNet/commit/dbde36e7a25bf6470783e9594260b666e09c2783) - Handle Ctrl+C cancellation consistently for interactive `check-*` command prompts.
|
|
10
|
+
|
|
11
|
+
- [#433](https://github.com/LightNetDev/LightNet/pull/433) [`dbde36e`](https://github.com/LightNetDev/LightNet/commit/dbde36e7a25bf6470783e9594260b666e09c2783) - Replace `check-files --fix --no-confirm` with `check-files --fix-without-confirm` for non-interactive cleanup.
|
|
12
|
+
|
|
13
|
+
- [#433](https://github.com/LightNetDev/LightNet/pull/433) [`dbde36e`](https://github.com/LightNetDev/LightNet/commit/dbde36e7a25bf6470783e9594260b666e09c2783) - Treat warning-only `check-files` runs as successful when no local content file references are found.
|
|
14
|
+
|
|
15
|
+
- [#433](https://github.com/LightNetDev/LightNet/pull/433) [`dbde36e`](https://github.com/LightNetDev/LightNet/commit/dbde36e7a25bf6470783e9594260b666e09c2783) - Improve `check-files` and `check-links` output for long referenced paths and URLs.
|
|
16
|
+
|
|
3
17
|
## 4.4.1
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "CLI for managing LightNet projects",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "4.4.
|
|
6
|
+
"version": "4.4.2",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"CHANGELOG.md"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"
|
|
29
|
-
"
|
|
28
|
+
"@clack/prompts": "^1.7.0",
|
|
29
|
+
"commander": "^15.0.0"
|
|
30
30
|
},
|
|
31
31
|
"engines": {
|
|
32
32
|
"node": ">=22"
|
package/src/check-files.js
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
pathExists,
|
|
22
22
|
toLocalContentDisplayPath,
|
|
23
23
|
} from "./support/filesystem.js"
|
|
24
|
+
import { cancelPrompt } from "./support/prompt-cancel.js"
|
|
24
25
|
import { createR2FileStorage } from "./support/r2.js"
|
|
25
26
|
|
|
26
27
|
const supportedScopes = new Set(["content-files", "thumbnails"])
|
|
@@ -33,7 +34,7 @@ const categoryImagesDir = "src/content/categories/images"
|
|
|
33
34
|
* @typedef {{
|
|
34
35
|
* scope?: string
|
|
35
36
|
* fix?: boolean
|
|
36
|
-
*
|
|
37
|
+
* fixWithoutConfirm?: boolean
|
|
37
38
|
* r2?: boolean
|
|
38
39
|
* }} CheckFilesOptions
|
|
39
40
|
*/
|
|
@@ -170,7 +171,7 @@ export async function checkFiles(options, runtime = {}) {
|
|
|
170
171
|
orphanedContentFiles = localContentResult.orphanedFiles
|
|
171
172
|
if (localContentResult.referenceCount === 0) {
|
|
172
173
|
warnings.push(
|
|
173
|
-
'No local "/files" content file references found.
|
|
174
|
+
'No local "/files" content file references found. If your content files are stored in R2, consider re-running with "--r2".',
|
|
174
175
|
)
|
|
175
176
|
}
|
|
176
177
|
}
|
|
@@ -180,8 +181,7 @@ export async function checkFiles(options, runtime = {}) {
|
|
|
180
181
|
const thumbnailsResult = await runSpinner({
|
|
181
182
|
error: "Thumbnail check failed.",
|
|
182
183
|
start: "Checking thumbnails",
|
|
183
|
-
stop: (result) =>
|
|
184
|
-
`Checked thumbnails: ${result.orphanedMediaThumbnails.length} orphaned media, ${result.orphanedCategoryThumbnails.length} orphaned categories.`,
|
|
184
|
+
stop: (result) => formatThumbnailCheckSummary(result),
|
|
185
185
|
task: () =>
|
|
186
186
|
validateThumbnails(
|
|
187
187
|
mediaItems,
|
|
@@ -194,7 +194,7 @@ export async function checkFiles(options, runtime = {}) {
|
|
|
194
194
|
orphanedCategoryThumbnails = thumbnailsResult.orphanedCategoryThumbnails
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
if (options.fix) {
|
|
197
|
+
if (options.fix || options.fixWithoutConfirm) {
|
|
198
198
|
/** @type {{displayPath:string, target:string}[]} */
|
|
199
199
|
const deletions = []
|
|
200
200
|
/** @type {{displayPath:string, target:string}[]} */
|
|
@@ -230,10 +230,10 @@ export async function checkFiles(options, runtime = {}) {
|
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
if (deletions.length > 0) {
|
|
233
|
-
const shouldSkipConfirmation = options.
|
|
233
|
+
const shouldSkipConfirmation = options.fixWithoutConfirm === true
|
|
234
234
|
if (!shouldSkipConfirmation && !interactive) {
|
|
235
235
|
throw new CliError(
|
|
236
|
-
'Deletion requires confirmation. Re-run with "--fix
|
|
236
|
+
'Deletion requires confirmation. Re-run with "--fix-without-confirm" in non-interactive environments.',
|
|
237
237
|
)
|
|
238
238
|
}
|
|
239
239
|
const shouldDelete =
|
|
@@ -315,22 +315,21 @@ export async function checkFiles(options, runtime = {}) {
|
|
|
315
315
|
}
|
|
316
316
|
|
|
317
317
|
const hasIssues =
|
|
318
|
-
warnings.length > 0 ||
|
|
319
318
|
missingContentFiles.length > 0 ||
|
|
320
319
|
wrongTypeR2ContentFiles.length > 0 ||
|
|
321
320
|
orphanedContentFiles.length > 0 ||
|
|
322
321
|
orphanedMediaThumbnails.length > 0 ||
|
|
323
322
|
orphanedCategoryThumbnails.length > 0
|
|
324
323
|
|
|
324
|
+
for (const warning of warnings) {
|
|
325
|
+
log.warn(warning)
|
|
326
|
+
}
|
|
327
|
+
|
|
325
328
|
if (!hasIssues && removedItems.length === 0) {
|
|
326
329
|
outro("No issues found. 🎉")
|
|
327
330
|
return true
|
|
328
331
|
}
|
|
329
332
|
|
|
330
|
-
for (const warning of warnings) {
|
|
331
|
-
log.warn(warning)
|
|
332
|
-
}
|
|
333
|
-
|
|
334
333
|
printMissingReferenceSection(
|
|
335
334
|
"Missing referenced content files",
|
|
336
335
|
missingContentFiles,
|
|
@@ -378,9 +377,7 @@ function printMissingReferenceSection(title, items) {
|
|
|
378
377
|
}
|
|
379
378
|
log.error(`${title} (${items.length})`)
|
|
380
379
|
for (const item of items) {
|
|
381
|
-
log.message(
|
|
382
|
-
`• ${item.path} (referenced by ${item.sources.toSorted().join(", ")})`,
|
|
383
|
-
)
|
|
380
|
+
log.message(`• ${item.path}\n${formatReferenceSources(item.sources)}`)
|
|
384
381
|
}
|
|
385
382
|
}
|
|
386
383
|
|
|
@@ -395,11 +392,25 @@ function printWrongTypeReferenceSection(title, items) {
|
|
|
395
392
|
log.warn(`${title} (${items.length})`)
|
|
396
393
|
for (const item of items) {
|
|
397
394
|
log.message(
|
|
398
|
-
`• ${item.path}
|
|
395
|
+
`• ${item.path}\n Expected type: "upload"\n${formatReferenceSources(item.sources)}`,
|
|
399
396
|
)
|
|
400
397
|
}
|
|
401
398
|
}
|
|
402
399
|
|
|
400
|
+
/**
|
|
401
|
+
* @param {string[]} sources
|
|
402
|
+
*/
|
|
403
|
+
function formatReferenceSources(sources) {
|
|
404
|
+
const sortedSources = sources.toSorted()
|
|
405
|
+
if (sortedSources.length === 1) {
|
|
406
|
+
return ` Referenced by: ${sortedSources[0]}`
|
|
407
|
+
}
|
|
408
|
+
return [
|
|
409
|
+
" Referenced by:",
|
|
410
|
+
...sortedSources.map((source) => ` - ${source}`),
|
|
411
|
+
].join("\n")
|
|
412
|
+
}
|
|
413
|
+
|
|
403
414
|
/**
|
|
404
415
|
* @template T
|
|
405
416
|
* @param {{
|
|
@@ -425,13 +436,58 @@ async function runSpinner({ error, start, stop, task }) {
|
|
|
425
436
|
|
|
426
437
|
/**
|
|
427
438
|
* @param {{
|
|
439
|
+
* fileCount: number
|
|
428
440
|
* missingReferences: MissingReference[]
|
|
429
441
|
* orphanedFiles: string[]
|
|
430
442
|
* referenceCount: number
|
|
431
443
|
* }} result
|
|
432
444
|
*/
|
|
433
445
|
function formatContentCheckSummary(result) {
|
|
434
|
-
|
|
446
|
+
const issues = [
|
|
447
|
+
formatFindingCount(result.missingReferences.length, "missing reference"),
|
|
448
|
+
formatFindingCount(result.orphanedFiles.length, "orphaned file"),
|
|
449
|
+
]
|
|
450
|
+
|
|
451
|
+
if (result.referenceCount === 0 && result.fileCount === 0) {
|
|
452
|
+
return `Content files: none found.`
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
return `Content files: ${formatCount(result.referenceCount, "reference")}, ${formatCount(result.fileCount, "file")}; ${issues.join(", ")}.`
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* @param {{
|
|
460
|
+
* fileCount: number
|
|
461
|
+
* orphanedCategoryThumbnails: string[]
|
|
462
|
+
* orphanedMediaThumbnails: string[]
|
|
463
|
+
* referenceCount: number
|
|
464
|
+
* }} result
|
|
465
|
+
*/
|
|
466
|
+
function formatThumbnailCheckSummary(result) {
|
|
467
|
+
const orphanedThumbnails =
|
|
468
|
+
result.orphanedMediaThumbnails.length +
|
|
469
|
+
result.orphanedCategoryThumbnails.length
|
|
470
|
+
|
|
471
|
+
return `Thumbnails: ${formatCount(result.referenceCount, "reference")}, ${formatCount(result.fileCount, "file")}; orphaned: ${orphanedThumbnails} (${result.orphanedMediaThumbnails.length} media, ${result.orphanedCategoryThumbnails.length} categories).`
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* @param {number} count
|
|
476
|
+
* @param {string} singular
|
|
477
|
+
*/
|
|
478
|
+
function formatFindingCount(count, singular) {
|
|
479
|
+
if (count === 0) {
|
|
480
|
+
return `no ${singular}s`
|
|
481
|
+
}
|
|
482
|
+
return formatCount(count, singular)
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* @param {number} count
|
|
487
|
+
* @param {string} singular
|
|
488
|
+
*/
|
|
489
|
+
function formatCount(count, singular) {
|
|
490
|
+
return `${count} ${singular}${count === 1 ? "" : "s"}`
|
|
435
491
|
}
|
|
436
492
|
|
|
437
493
|
/**
|
|
@@ -515,12 +571,14 @@ async function validateThumbnails(
|
|
|
515
571
|
])
|
|
516
572
|
|
|
517
573
|
return {
|
|
574
|
+
fileCount: mediaFiles.length + categoryFiles.length,
|
|
518
575
|
orphanedMediaThumbnails: mediaFiles.filter(
|
|
519
576
|
(file) => !mediaReferences.has(file),
|
|
520
577
|
),
|
|
521
578
|
orphanedCategoryThumbnails: categoryFiles.filter(
|
|
522
579
|
(file) => !categoryReferences.has(file),
|
|
523
580
|
),
|
|
581
|
+
referenceCount: mediaReferences.size + categoryReferences.size,
|
|
524
582
|
}
|
|
525
583
|
}
|
|
526
584
|
|
|
@@ -542,8 +600,10 @@ async function validateContentFiles({
|
|
|
542
600
|
initializedStorage,
|
|
543
601
|
{ includeLinkReferences },
|
|
544
602
|
)
|
|
603
|
+
const files = await initializedStorage.list()
|
|
545
604
|
if (references.size === 0) {
|
|
546
605
|
return {
|
|
606
|
+
fileCount: files.length,
|
|
547
607
|
missingReferences: /** @type {MissingReference[]} */ ([]),
|
|
548
608
|
orphanedFiles: /** @type {string[]} */ ([]),
|
|
549
609
|
referenceCount: 0,
|
|
@@ -551,7 +611,6 @@ async function validateContentFiles({
|
|
|
551
611
|
}
|
|
552
612
|
}
|
|
553
613
|
|
|
554
|
-
const files = await initializedStorage.list()
|
|
555
614
|
const fileSet = new Set(files)
|
|
556
615
|
|
|
557
616
|
const missingReferences = [...references.entries()]
|
|
@@ -575,6 +634,7 @@ async function validateContentFiles({
|
|
|
575
634
|
.sort((a, b) => a.path.localeCompare(b.path))
|
|
576
635
|
|
|
577
636
|
return {
|
|
637
|
+
fileCount: files.length,
|
|
578
638
|
missingReferences,
|
|
579
639
|
orphanedFiles,
|
|
580
640
|
referenceCount: references.size,
|
|
@@ -695,7 +755,10 @@ function toPosixPath(filePath) {
|
|
|
695
755
|
*/
|
|
696
756
|
async function defaultPromptText(message) {
|
|
697
757
|
const answer = await text({ message })
|
|
698
|
-
|
|
758
|
+
if (isCancel(answer)) {
|
|
759
|
+
cancelPrompt()
|
|
760
|
+
}
|
|
761
|
+
return String(answer)
|
|
699
762
|
}
|
|
700
763
|
|
|
701
764
|
/**
|
|
@@ -706,5 +769,8 @@ async function defaultPromptConfirm(message) {
|
|
|
706
769
|
message,
|
|
707
770
|
initialValue: false,
|
|
708
771
|
})
|
|
709
|
-
|
|
772
|
+
if (isCancel(answer)) {
|
|
773
|
+
cancelPrompt()
|
|
774
|
+
}
|
|
775
|
+
return answer
|
|
710
776
|
}
|
package/src/check-links.js
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
import { CliError } from "./support/cli-error.js"
|
|
14
14
|
import { contentCollections } from "./support/content-collections.js"
|
|
15
15
|
import { pathExists } from "./support/filesystem.js"
|
|
16
|
+
import { cancelPrompt } from "./support/prompt-cancel.js"
|
|
16
17
|
|
|
17
18
|
const mediaDir = "src/content/media"
|
|
18
19
|
const defaultConcurrency = 24
|
|
@@ -126,11 +127,7 @@ export async function checkLinks(options, runtime = {}) {
|
|
|
126
127
|
log.error(`Unavailable links (${unavailableLinks.length})`)
|
|
127
128
|
for (const { reference, result } of unavailableLinks) {
|
|
128
129
|
log.message(
|
|
129
|
-
|
|
130
|
-
...reference.sources,
|
|
131
|
-
]
|
|
132
|
-
.toSorted()
|
|
133
|
-
.join(", ")})`,
|
|
130
|
+
`• ${reference.displayUrl}\n Result: ${formatFailure(result)}\n${formatReferenceSources(reference.sources)}`,
|
|
134
131
|
)
|
|
135
132
|
}
|
|
136
133
|
|
|
@@ -332,15 +329,25 @@ function printProtectedLinks(links) {
|
|
|
332
329
|
log.warn(`Protected or forbidden links (${links.length})`)
|
|
333
330
|
for (const { reference, result } of links) {
|
|
334
331
|
log.message(
|
|
335
|
-
|
|
336
|
-
...reference.sources,
|
|
337
|
-
]
|
|
338
|
-
.toSorted()
|
|
339
|
-
.join(", ")})`,
|
|
332
|
+
`• ${reference.displayUrl}\n Result: ${formatFailure(result)}\n${formatReferenceSources(reference.sources)}`,
|
|
340
333
|
)
|
|
341
334
|
}
|
|
342
335
|
}
|
|
343
336
|
|
|
337
|
+
/**
|
|
338
|
+
* @param {Set<string>} sources
|
|
339
|
+
*/
|
|
340
|
+
function formatReferenceSources(sources) {
|
|
341
|
+
const sortedSources = [...sources].toSorted()
|
|
342
|
+
if (sortedSources.length === 1) {
|
|
343
|
+
return ` Referenced by: ${sortedSources[0]}`
|
|
344
|
+
}
|
|
345
|
+
return [
|
|
346
|
+
" Referenced by:",
|
|
347
|
+
...sortedSources.map((source) => ` - ${source}`),
|
|
348
|
+
].join("\n")
|
|
349
|
+
}
|
|
350
|
+
|
|
344
351
|
/**
|
|
345
352
|
* @param {string} url
|
|
346
353
|
* @param {{
|
|
@@ -483,7 +490,10 @@ function toPosixPath(filePath) {
|
|
|
483
490
|
*/
|
|
484
491
|
async function defaultPromptText(message) {
|
|
485
492
|
const answer = await text({ message })
|
|
486
|
-
|
|
493
|
+
if (isCancel(answer)) {
|
|
494
|
+
cancelPrompt()
|
|
495
|
+
}
|
|
496
|
+
return String(answer)
|
|
487
497
|
}
|
|
488
498
|
|
|
489
499
|
/**
|
|
@@ -5,7 +5,9 @@ import { readFile } from "node:fs/promises"
|
|
|
5
5
|
import { resolve } from "node:path"
|
|
6
6
|
import { cwd } from "node:process"
|
|
7
7
|
|
|
8
|
-
import { confirm, intro, log, outro, taskLog } from "@clack/prompts"
|
|
8
|
+
import { confirm, intro, isCancel, log, outro, taskLog } from "@clack/prompts"
|
|
9
|
+
|
|
10
|
+
import { cancelPrompt } from "./support/prompt-cancel.js"
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* @typedef {{
|
|
@@ -100,13 +102,7 @@ export async function checkTranslations(options = {}) {
|
|
|
100
102
|
* @returns
|
|
101
103
|
*/
|
|
102
104
|
async function runBuild(build) {
|
|
103
|
-
const shouldRunBuild =
|
|
104
|
-
build ??
|
|
105
|
-
(await confirm({
|
|
106
|
-
message:
|
|
107
|
-
"Run pnpm build now? Command requires an up-to-date dist/ directory.",
|
|
108
|
-
initialValue: false,
|
|
109
|
-
}))
|
|
105
|
+
const shouldRunBuild = build ?? (await promptRunBuild())
|
|
110
106
|
if (!shouldRunBuild) {
|
|
111
107
|
return true
|
|
112
108
|
}
|
|
@@ -158,6 +154,18 @@ async function runBuild(build) {
|
|
|
158
154
|
}
|
|
159
155
|
}
|
|
160
156
|
|
|
157
|
+
async function promptRunBuild() {
|
|
158
|
+
const answer = await confirm({
|
|
159
|
+
message:
|
|
160
|
+
"Run pnpm build now? Command requires an up-to-date dist/ directory.",
|
|
161
|
+
initialValue: false,
|
|
162
|
+
})
|
|
163
|
+
if (isCancel(answer)) {
|
|
164
|
+
cancelPrompt()
|
|
165
|
+
}
|
|
166
|
+
return answer
|
|
167
|
+
}
|
|
168
|
+
|
|
161
169
|
/**
|
|
162
170
|
*
|
|
163
171
|
* @param {{title:string, action:string}} source
|
package/src/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { checkFiles } from "./check-files.js"
|
|
|
8
8
|
import { checkLinks } from "./check-links.js"
|
|
9
9
|
import { checkTranslations } from "./check-translations.js"
|
|
10
10
|
import { CliError } from "./support/cli-error.js"
|
|
11
|
+
import { PromptCancelled } from "./support/prompt-cancel.js"
|
|
11
12
|
const { version } = pkg
|
|
12
13
|
|
|
13
14
|
const program = new Command()
|
|
@@ -24,8 +25,12 @@ program
|
|
|
24
25
|
.option("--build", "run pnpm build before checking translations")
|
|
25
26
|
.option("--no-build", "skip the build prompt and use the latest dist/ output")
|
|
26
27
|
.action(async (options) => {
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
try {
|
|
29
|
+
const checkSuccessful = await checkTranslations(options)
|
|
30
|
+
commandExitCode = checkSuccessful ? 0 : 1
|
|
31
|
+
} catch (error) {
|
|
32
|
+
handleCommandError(error)
|
|
33
|
+
}
|
|
29
34
|
})
|
|
30
35
|
|
|
31
36
|
program
|
|
@@ -34,7 +39,7 @@ program
|
|
|
34
39
|
"check for missing and orphaned content files and thumbnails in a LightNet site",
|
|
35
40
|
)
|
|
36
41
|
.option("--fix", "remove orphaned files")
|
|
37
|
-
.option("--
|
|
42
|
+
.option("--fix-without-confirm", "remove orphaned files without confirmation")
|
|
38
43
|
.option(
|
|
39
44
|
"--r2",
|
|
40
45
|
"validate remote content files in Cloudflare R2 instead of public/files",
|
|
@@ -48,12 +53,7 @@ program
|
|
|
48
53
|
const checkSuccessful = await checkFiles(options)
|
|
49
54
|
commandExitCode = checkSuccessful ? 0 : 1
|
|
50
55
|
} catch (error) {
|
|
51
|
-
|
|
52
|
-
console.error(error.message)
|
|
53
|
-
commandExitCode = 1
|
|
54
|
-
return
|
|
55
|
-
}
|
|
56
|
-
throw error
|
|
56
|
+
handleCommandError(error)
|
|
57
57
|
}
|
|
58
58
|
})
|
|
59
59
|
|
|
@@ -66,14 +66,25 @@ program
|
|
|
66
66
|
const checkSuccessful = await checkLinks(options)
|
|
67
67
|
commandExitCode = checkSuccessful ? 0 : 1
|
|
68
68
|
} catch (error) {
|
|
69
|
-
|
|
70
|
-
console.error(error.message)
|
|
71
|
-
commandExitCode = 1
|
|
72
|
-
return
|
|
73
|
-
}
|
|
74
|
-
throw error
|
|
69
|
+
handleCommandError(error)
|
|
75
70
|
}
|
|
76
71
|
})
|
|
77
72
|
|
|
78
73
|
await program.parseAsync()
|
|
79
74
|
process.exitCode = commandExitCode
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @param {unknown} error
|
|
78
|
+
*/
|
|
79
|
+
function handleCommandError(error) {
|
|
80
|
+
if (error instanceof PromptCancelled) {
|
|
81
|
+
commandExitCode = 0
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
if (error instanceof CliError) {
|
|
85
|
+
console.error(error.message)
|
|
86
|
+
commandExitCode = 1
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
throw error
|
|
90
|
+
}
|
package/src/support/r2.js
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
writeCliConfig,
|
|
16
16
|
} from "./cli-config.js"
|
|
17
17
|
import { CliError } from "./cli-error.js"
|
|
18
|
+
import { cancelPrompt } from "./prompt-cancel.js"
|
|
18
19
|
|
|
19
20
|
const execFileAsync = promisify(execFile)
|
|
20
21
|
const sessionSecretEnvName = "LIGHTNET_R2_SECRET_ACCESS_KEY"
|
|
@@ -412,7 +413,7 @@ async function promptRequiredSecret() {
|
|
|
412
413
|
message: "R2 secretAccessKey:",
|
|
413
414
|
})
|
|
414
415
|
if (isCancel(value)) {
|
|
415
|
-
|
|
416
|
+
cancelPrompt()
|
|
416
417
|
}
|
|
417
418
|
if (value.trim()) {
|
|
418
419
|
processEnv[sessionSecretEnvName] = value
|