@cardstack/boxel-cli 0.4.0-unstable.0 → 0.4.0-unstable.1
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/bundled-realms/base/card-api.gts +2 -0
- package/bundled-realms/base/components/cards-grid-layout.gts +24 -2
- package/bundled-realms/base/field-component.gts +16 -4
- package/bundled-realms/base/links-to-editor.gts +27 -3
- package/bundled-realms/base/realm-config.gts +18 -1
- package/bundled-test-harness/assets/{add-workspace-tMjv_Ar4.js → add-workspace-DBDTvtP2.js} +3 -3
- package/bundled-test-harness/assets/{add-workspace-test-B_ih3mkL.js → add-workspace-test-CE21v7jK.js} +1 -1
- package/bundled-test-harness/assets/{ai-assistant-test-CrQxlWpZ.js → ai-assistant-test-DSyMR0hY.js} +1 -1
- package/bundled-test-harness/assets/{ai-module-creation-test-CMLVMpYm.js → ai-module-creation-test-zY83EN93.js} +1 -1
- package/bundled-test-harness/assets/{aibot-message-CiwsV-h8.js → aibot-message-BfRah4Lm.js} +2 -2
- package/bundled-test-harness/assets/{app-BQLXfOdp.js → app-CPRVydcd.js} +14 -14
- package/bundled-test-harness/assets/{binary-upload-dedupe-test-B7dPaGQN.js → binary-upload-dedupe-test-nnaYqiTh.js} +1 -1
- package/bundled-test-harness/assets/{broken-link-template-test-BAc48VK4.js → broken-link-template-test-BHXrPxQ6.js} +1 -1
- package/bundled-test-harness/assets/{card-api-test-BmiwtCFR.js → card-api-test-C0HrvAuC.js} +1 -1
- package/bundled-test-harness/assets/{card-basics-test-DZs6Zh6Z.js → card-basics-test-CvITmKK-.js} +1 -1
- package/bundled-test-harness/assets/{card-catalog-test-D2mEHOpL.js → card-catalog-test-CWkfBRuQ.js} +1 -1
- package/bundled-test-harness/assets/{card-copy-test-DpSavuvN.js → card-copy-test-Co_MPCIJ.js} +1 -1
- package/bundled-test-harness/assets/{card-def-field-def-relationships-test-DYX_ubhX.js → card-def-field-def-relationships-test-7e-g4qJs.js} +1 -1
- package/bundled-test-harness/assets/{card-delete-test-Bmp8Ue48.js → card-delete-test-BcOtJYm4.js} +1 -1
- package/bundled-test-harness/assets/{card-error-detail-DuFoktdn.js → card-error-detail-Q7wtuRcv.js} +2 -2
- package/bundled-test-harness/assets/{card-search-adorn-test-CEA5iAcD.js → card-search-adorn-test-CbsnFvDF.js} +1 -1
- package/bundled-test-harness/assets/{card-search-selection-menu-test-DOLM6HU0.js → card-search-selection-menu-test-CY77b1kz.js} +1 -1
- package/bundled-test-harness/assets/{check-correctness-test-DR1rUhtU.js → check-correctness-test-D0EYMlP7.js} +1 -1
- package/bundled-test-harness/assets/{codeblocks-test-B-i0v3er.js → codeblocks-test-CFR0u5-j.js} +1 -1
- package/bundled-test-harness/assets/{commands-DoigkJc8.js → commands-BOwQjc8N.js} +3 -3
- package/bundled-test-harness/assets/{commands-test-D1X-Kikc.js → commands-test-BpFjXsiC.js} +1 -1
- package/bundled-test-harness/assets/{commands-test-C13_nhjT.js → commands-test-QSW7zRvO.js} +1 -1
- package/bundled-test-harness/assets/{components-CBfd9MIo.js → components-DYC4nC4r.js} +184 -184
- package/bundled-test-harness/assets/{components-8vaKSlYm.css → components-DgK6vTbM.css} +17 -14
- package/bundled-test-harness/assets/{container-DYJ5z0jP.js → container-DRblzvCW.js} +16 -16
- package/bundled-test-harness/assets/{convert-to-class-name-test-B7ILkHei.js → convert-to-class-name-test-BiCrnGxA.js} +1 -1
- package/bundled-test-harness/assets/{create-file-modal-BNJHELMz.js → create-file-modal-Cfvn0u5s.js} +4 -4
- package/bundled-test-harness/assets/{create-listing-modal-test-BIG3NbX-.js → create-listing-modal-test-W6LuCzaK.js} +2 -2
- package/bundled-test-harness/assets/{debug-message-test-CAzyW7l3.js → debug-message-test-CXVfUuec.js} +1 -1
- package/bundled-test-harness/assets/{error-display-test-Btk0RcqS.js → error-display-test-B6I8CYXw.js} +1 -1
- package/bundled-test-harness/assets/{externals-C65aJ_7H.js → externals-DiG6hYU9.js} +2 -2
- package/bundled-test-harness/assets/{fallback-banner-live-delete-test-I7o8HPay.js → fallback-banner-live-delete-test-Bv_OBmzY.js} +1 -1
- package/bundled-test-harness/assets/{fallback-banner-test-Bh-BDHwS.js → fallback-banner-test-TL8jNe4f.js} +1 -1
- package/bundled-test-harness/assets/{fallback-models-test-GjvpcpvS.js → fallback-models-test-DEhvKsfY.js} +1 -1
- package/bundled-test-harness/assets/{file-DUbLArQi.js → file-D8hnXC1_.js} +8 -2
- package/bundled-test-harness/assets/{file-attachment-test-CtV6jG8f.js → file-attachment-test-CkL6IaWf.js} +1 -1
- package/bundled-test-harness/assets/{file-chooser-test-C9VwTWSW.js → file-chooser-test-M1rOgltw.js} +1 -1
- package/bundled-test-harness/assets/{formatted-aibot-message-test-DRdKZ8lg.js → formatted-aibot-message-test-CNk1lVYO.js} +1 -1
- package/bundled-test-harness/assets/{general-test-pIZFE9Ii.js → general-test-B_QwZC0y.js} +1 -1
- package/bundled-test-harness/assets/{index-query-engine-test-DvgGBuTy.js → index-query-engine-test-x77vbwML.js} +1 -1
- package/bundled-test-harness/assets/{inspector-test-COfLlQnO.js → inspector-test-CtCAKlpG.js} +39 -2
- package/bundled-test-harness/assets/{instance-filter-matcher-test-DUeZ6eiv.js → instance-filter-matcher-test-YKzjZAa3.js} +1 -1
- package/bundled-test-harness/assets/{interact-submode-creation-and-permissions-test-Dr-clTrg.js → interact-submode-creation-and-permissions-test-2_4tHla6.js} +1 -1
- package/bundled-test-harness/assets/{interact-submode-setup-D23oc2q6.js → interact-submode-setup-DI2HM3S-.js} +1 -1
- package/bundled-test-harness/assets/{interact-submode-test-t8HEq7Bp.js → interact-submode-test-BUKZnm-y.js} +1 -1
- package/bundled-test-harness/assets/{item-button-CAhhwhRh.js → item-button-CepLHUN-.js} +1 -1
- package/bundled-test-harness/assets/{live-prerendered-search-kxxMxyHS.js → live-prerendered-search-DiFs_MHd.js} +1 -1
- package/bundled-test-harness/assets/{login-ou9E1DG9.js → login-DWNfbapF.js} +1 -1
- package/bundled-test-harness/assets/{login-error-text-test-BsNV9TOq.js → login-error-text-test-3lQ69Gme.js} +1 -1
- package/bundled-test-harness/assets/{main-CrtBvhng.js → main-CDat3XsY.js} +1 -1
- package/bundled-test-harness/assets/{markdown-preview-CKlpPkbc.js → markdown-preview-o2AI98EN.js} +1 -1
- package/bundled-test-harness/assets/{markdown-preview-test-BTdN_033.js → markdown-preview-test-D2YoXqUY.js} +1 -1
- package/bundled-test-harness/assets/{modal-container-wzIBYeE_.js → modal-container-BzEkpeIx.js} +1 -1
- package/bundled-test-harness/assets/{on-key-CpWVcRaS.js → on-key-C8yMINOQ.js} +1 -1
- package/bundled-test-harness/assets/{open-image-in-new-tab-test-B-jsojF0.js → open-image-in-new-tab-test-3iRCTOjd.js} +1 -1
- package/bundled-test-harness/assets/{operator-mode-acceptance-test-CXQkU0xV.js → operator-mode-acceptance-test-DoQ5Klyi.js} +2 -2
- package/bundled-test-harness/assets/{operator-mode-card-catalog-test-DjTCHu2f.js → operator-mode-card-catalog-test-Came_pKy.js} +2 -2
- package/bundled-test-harness/assets/{operator-mode-links-test-EeNC7Or8.js → operator-mode-links-test-DoTvJvpI.js} +2 -2
- package/bundled-test-harness/assets/{operator-mode-test-Cdm2eu3n.js → operator-mode-test-DeUtV1XR.js} +2 -2
- package/bundled-test-harness/assets/{operator-mode-ui-test-yWX9IF_q.js → operator-mode-ui-test-DTUMZBlw.js} +2 -2
- package/bundled-test-harness/assets/{overlay-menu-items-test-D2yM2xsl.js → overlay-menu-items-test-DhPIUwmz.js} +1 -1
- package/bundled-test-harness/assets/{panel-DBvohlmr.js → panel-DcMU_CGT.js} +5 -5
- package/bundled-test-harness/assets/{past-sessions-test-DqEv1zfI.js → past-sessions-test-BrdqlYxe.js} +1 -1
- package/bundled-test-harness/assets/{patch-code-ClPL6B_d.js → patch-code-F_7JKtTQ.js} +1 -1
- package/bundled-test-harness/assets/{patch-code-test-Y34298iq.js → patch-code-test-O5_p8vp4.js} +3 -3
- package/bundled-test-harness/assets/{prerendered-card-search-test-BTgiRYnI.js → prerendered-card-search-test-DLYUamOp.js} +1 -1
- package/bundled-test-harness/assets/{preview-format-Bb5FIkOY.js → preview-format-BqY_j3zZ.js} +1 -1
- package/bundled-test-harness/assets/{preview-format-test-DjS1vxlt.js → preview-format-test-CublqRWy.js} +1 -1
- package/bundled-test-harness/assets/{realm-config-routing-rule-edit-test-E5AhFXfq.js → realm-config-routing-rule-edit-test-T8S_2Lwq.js} +47 -4
- package/bundled-test-harness/assets/{reasoning-test-ChZJb8sD.js → reasoning-test-DcQkF04r.js} +1 -1
- package/bundled-test-harness/assets/{room-message-test-DQ2x7ymr.js → room-message-test-DuSkABnU.js} +2 -2
- package/bundled-test-harness/assets/{schema-generation-test-DxhNMqOe.js → schema-generation-test-z90uBA7r.js} +1 -1
- package/bundled-test-harness/assets/{scrolling-test-Drdch9wf.js → scrolling-test-jCKormjp.js} +2 -2
- package/bundled-test-harness/assets/{search-result-header-5VQHm_Ev.js → search-result-header-Ch7TKEzn.js} +1 -1
- package/bundled-test-harness/assets/{sending-test-6i0F6n4v.js → sending-test-Bocu5vf9.js} +2 -2
- package/bundled-test-harness/assets/{setup-DeQyrqyx.js → setup-CN-HHlT_.js} +1 -1
- package/bundled-test-harness/assets/{skills-test-Dl7uEBNz.js → skills-test-Cut0gpNU.js} +1 -1
- package/bundled-test-harness/assets/{store-test-Dkf9wBLg.js → store-test-C747NJ3O.js} +2 -2
- package/bundled-test-harness/assets/{submode-switcher-Popj4iN5.js → submode-switcher-iR4m0GzD.js} +1 -1
- package/bundled-test-harness/assets/{switch-submode-DOdRs5QD.js → switch-submode--ZVbWG3S.js} +1 -1
- package/bundled-test-harness/assets/{switch-submode-test-CX0YxbVu.js → switch-submode-test--Ncx8g_l.js} +1 -1
- package/bundled-test-harness/assets/{tests-D1v0wSnN.js → tests-Dw_agY8k.js} +60 -60
- package/bundled-test-harness/assets/{text-input-validator-test-CT3c7m8B.js → text-input-validator-test-CAlDivoV.js} +1 -1
- package/bundled-test-harness/assets/{theme-card-test-DyOWEJRn.js → theme-card-test-Q5eP-lEF.js} +1 -1
- package/bundled-test-harness/assets/{workspace-DvhB0Ltb.js → workspace-PBphyb9N.js} +2 -2
- package/bundled-test-harness/assets/{workspace-delete-summary-test-B7rnzX95.js → workspace-delete-summary-test-iqD1ae55.js} +1 -1
- package/bundled-test-harness/boxel-ui-checksum.txt +1 -1
- package/bundled-test-harness/index.html +26 -26
- package/bundled-test-harness/tests/index.html +26 -26
- package/bundled-types/base/field-component.d.ts +15 -4
- package/bundled-types/base/links-to-editor.d.ts +9 -0
- package/bundled-types/boxel-ui/components/filter-list/index.gts +4 -1
- package/dist/index.js +241 -241
- package/package.json +3 -3
- package/src/commands/realm/publish.ts +87 -16
- package/src/commands/realm/unpublish.ts +11 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardstack/boxel-cli",
|
|
3
|
-
"version": "0.4.0-unstable.
|
|
3
|
+
"version": "0.4.0-unstable.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "CLI tools for Boxel workspace management",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"ts-node": "^10.9.1",
|
|
63
63
|
"vite": "^6.3.2",
|
|
64
64
|
"vitest": "^2.1.9",
|
|
65
|
-
"@cardstack/
|
|
65
|
+
"@cardstack/postgres": "0.0.0",
|
|
66
66
|
"@cardstack/runtime-common": "1.0.0",
|
|
67
|
-
"@cardstack/
|
|
67
|
+
"@cardstack/local-types": "0.0.0"
|
|
68
68
|
},
|
|
69
69
|
"publishConfig": {
|
|
70
70
|
"access": "public",
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
2
|
import { ensureTrailingSlash } from '@cardstack/runtime-common/paths';
|
|
3
3
|
import {
|
|
4
|
+
fetchPublishabilityReport,
|
|
4
5
|
publishRealm as publishRealmOperation,
|
|
5
6
|
type PublishRealmOutput,
|
|
6
7
|
RealmOperationError,
|
|
7
8
|
waitForReady,
|
|
8
9
|
} from '@cardstack/runtime-common/realm-operations';
|
|
10
|
+
import type { PublishabilityViolation } from '@cardstack/runtime-common/publishability';
|
|
9
11
|
import { buildCliRealmClient } from '../../lib/realm-client.ts';
|
|
10
12
|
import {
|
|
11
13
|
getProfileManager,
|
|
12
14
|
type ProfileManager,
|
|
13
15
|
} from '../../lib/profile-manager.ts';
|
|
14
16
|
import { unpublishRealm } from './unpublish.ts';
|
|
17
|
+
import { cliLog } from '../../lib/cli-log.ts';
|
|
15
18
|
import { FG_CYAN, FG_GREEN, FG_RED, RESET } from '../../lib/colors.ts';
|
|
16
19
|
|
|
17
20
|
const DEFAULT_TIMEOUT_MS = 300_000;
|
|
@@ -26,6 +29,11 @@ export interface PublishOptions {
|
|
|
26
29
|
* unpublish the target URL first and retry once. Default: true.
|
|
27
30
|
*/
|
|
28
31
|
republish?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Skip the publishability gate (private-dependency / error-document check).
|
|
34
|
+
* Default: false — the gate runs and blocks publishing on violations.
|
|
35
|
+
*/
|
|
36
|
+
force?: boolean;
|
|
29
37
|
profileManager?: ProfileManager;
|
|
30
38
|
}
|
|
31
39
|
|
|
@@ -39,7 +47,9 @@ export interface PublishRealmResult {
|
|
|
39
47
|
/**
|
|
40
48
|
* Publish a source realm to a published-realm URL.
|
|
41
49
|
*
|
|
42
|
-
*
|
|
50
|
+
* Before publishing, runs the publishability gate (private-dependency /
|
|
51
|
+
* error-document check) and refuses to publish on violations unless `force`
|
|
52
|
+
* is set. Then speaks the contract documented at
|
|
43
53
|
* `packages/realm-server/handlers/handle-publish-realm.ts`: the server
|
|
44
54
|
* accepts the publish, returns `202 Accepted` with `status: "pending"`,
|
|
45
55
|
* and the client polls `/<publishedRealmURL>/_readiness-check` until
|
|
@@ -57,6 +67,18 @@ export async function publishRealm(
|
|
|
57
67
|
let normalizedSource = ensureTrailingSlash(sourceRealmURL);
|
|
58
68
|
let normalizedPublished = ensureTrailingSlash(publishedRealmURL);
|
|
59
69
|
|
|
70
|
+
// Pre-publish gate: refuse to publish a realm with private-dependency or
|
|
71
|
+
// error-document violations (which would break the published site) unless
|
|
72
|
+
// the caller forces it.
|
|
73
|
+
if (!options.force) {
|
|
74
|
+
let report = await fetchPublishabilityReport(client, {
|
|
75
|
+
realmURL: normalizedSource,
|
|
76
|
+
});
|
|
77
|
+
if (!report.publishable) {
|
|
78
|
+
throw new Error(describeViolations(report.violations));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
60
82
|
let output: PublishRealmOutput;
|
|
61
83
|
try {
|
|
62
84
|
output = await publishRealmOperation(client, {
|
|
@@ -71,7 +93,9 @@ export async function publishRealm(
|
|
|
71
93
|
(err.status === 400 || err.status === 409) &&
|
|
72
94
|
options.republish !== false
|
|
73
95
|
) {
|
|
74
|
-
|
|
96
|
+
// Progress, not payload: route to stderr via cliLog.info so it never
|
|
97
|
+
// corrupts stdout when the caller passed --json (stdout is JSON-only).
|
|
98
|
+
cliLog.info(
|
|
75
99
|
`Publish returned ${err.status} (${(err.body ?? '').slice(0, 200)}). Unpublishing and retrying.`,
|
|
76
100
|
);
|
|
77
101
|
let unpublishResult = await unpublishRealm(normalizedPublished, {
|
|
@@ -118,6 +142,8 @@ export interface PublishCliOptions {
|
|
|
118
142
|
wait?: boolean;
|
|
119
143
|
timeout?: number;
|
|
120
144
|
republish?: boolean;
|
|
145
|
+
force?: boolean;
|
|
146
|
+
json?: boolean;
|
|
121
147
|
}
|
|
122
148
|
|
|
123
149
|
export function publishCliOptsToOptions(
|
|
@@ -127,6 +153,7 @@ export function publishCliOptsToOptions(
|
|
|
127
153
|
waitForReady: opts.wait !== false,
|
|
128
154
|
timeoutMs: opts.timeout,
|
|
129
155
|
republish: opts.republish !== false,
|
|
156
|
+
force: opts.force === true,
|
|
130
157
|
};
|
|
131
158
|
}
|
|
132
159
|
|
|
@@ -134,7 +161,7 @@ export function registerPublishCommand(realm: Command): void {
|
|
|
134
161
|
realm
|
|
135
162
|
.command('publish')
|
|
136
163
|
.description(
|
|
137
|
-
'Publish a source realm to a published-realm URL,
|
|
164
|
+
'Publish a source realm to a published-realm URL: runs the publishability gate (use --force to skip), then polls readiness until ready',
|
|
138
165
|
)
|
|
139
166
|
.argument('<source-realm-url>', 'URL of the source realm to publish')
|
|
140
167
|
.argument(
|
|
@@ -151,6 +178,11 @@ export function registerPublishCommand(realm: Command): void {
|
|
|
151
178
|
'--no-republish',
|
|
152
179
|
'Do not auto-unpublish + retry when the server returns 400/409',
|
|
153
180
|
)
|
|
181
|
+
.option(
|
|
182
|
+
'--force',
|
|
183
|
+
'Publish even if the realm has publishability violations (skips the gate)',
|
|
184
|
+
)
|
|
185
|
+
.option('--json', 'Output the result as JSON')
|
|
154
186
|
.action(
|
|
155
187
|
async (
|
|
156
188
|
sourceRealmURL: string,
|
|
@@ -163,20 +195,27 @@ export function registerPublishCommand(realm: Command): void {
|
|
|
163
195
|
publishedRealmURL,
|
|
164
196
|
publishCliOptsToOptions(opts),
|
|
165
197
|
);
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
198
|
+
if (opts.json) {
|
|
199
|
+
cliLog.output(JSON.stringify(result, null, 2));
|
|
200
|
+
} else {
|
|
201
|
+
console.log(
|
|
202
|
+
`${FG_GREEN}Published:${RESET} ${FG_CYAN}${result.publishedRealmURL}${RESET}`,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
169
205
|
} catch (err) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
206
|
+
let message = err instanceof Error ? err.message : String(err);
|
|
207
|
+
if (opts.json) {
|
|
208
|
+
cliLog.output(JSON.stringify({ error: message }, null, 2));
|
|
209
|
+
} else {
|
|
210
|
+
console.error(`${FG_RED}Error:${RESET} ${message}`);
|
|
211
|
+
// Node's fetch surfaces the actual transport error (ECONNRESET,
|
|
212
|
+
// TLS failure, undici socket error, etc.) on `error.cause`. Print
|
|
213
|
+
// it so opaque "fetch failed" messages don't strand the caller.
|
|
214
|
+
// `!= null` rather than a truthy check so we don't drop
|
|
215
|
+
// falsy-but-defined causes (`''`, `0`, `false`, `NaN`).
|
|
216
|
+
if (err instanceof Error && err.cause != null) {
|
|
217
|
+
console.error(`${FG_RED}Caused by:${RESET}`, err.cause);
|
|
218
|
+
}
|
|
180
219
|
}
|
|
181
220
|
process.exit(1);
|
|
182
221
|
}
|
|
@@ -184,6 +223,38 @@ export function registerPublishCommand(realm: Command): void {
|
|
|
184
223
|
);
|
|
185
224
|
}
|
|
186
225
|
|
|
226
|
+
// Summarizes publishability violations into a single actionable error message.
|
|
227
|
+
// Mirrors the host PublishRealmCommand's gate messaging.
|
|
228
|
+
export function describeViolations(
|
|
229
|
+
violations: PublishabilityViolation[],
|
|
230
|
+
): string {
|
|
231
|
+
let privateCount = violations.filter(
|
|
232
|
+
(v) => v.kind === 'private-dependency',
|
|
233
|
+
).length;
|
|
234
|
+
let errorCount = violations.filter((v) => v.kind === 'error-document').length;
|
|
235
|
+
|
|
236
|
+
let parts: string[] = [];
|
|
237
|
+
if (privateCount) {
|
|
238
|
+
parts.push(`${privateCount} private-dependency violation(s)`);
|
|
239
|
+
}
|
|
240
|
+
if (errorCount) {
|
|
241
|
+
parts.push(`${errorCount} error-document violation(s)`);
|
|
242
|
+
}
|
|
243
|
+
let summary = parts.length
|
|
244
|
+
? parts.join(', ')
|
|
245
|
+
: `${violations.length} violation(s)`;
|
|
246
|
+
|
|
247
|
+
let resources = violations
|
|
248
|
+
.map((v) => v.resource)
|
|
249
|
+
.filter(Boolean)
|
|
250
|
+
.slice(0, 5)
|
|
251
|
+
.join(', ');
|
|
252
|
+
|
|
253
|
+
return `Realm is not publishable (${summary}). Resolve them or pass --force to override.${
|
|
254
|
+
resources ? ` Affected: ${resources}` : ''
|
|
255
|
+
}`;
|
|
256
|
+
}
|
|
257
|
+
|
|
187
258
|
function parseTimeoutOption(value: string): number {
|
|
188
259
|
let n = Number.parseInt(value, 10);
|
|
189
260
|
if (!Number.isFinite(n) || n < 0 || String(n) !== value.trim()) {
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
NO_ACTIVE_PROFILE_ERROR,
|
|
11
11
|
type ProfileManager,
|
|
12
12
|
} from '../../lib/profile-manager.ts';
|
|
13
|
+
import { cliLog } from '../../lib/cli-log.ts';
|
|
13
14
|
import { FG_CYAN, FG_GREEN, FG_RED, RESET } from '../../lib/colors.ts';
|
|
14
15
|
import { describeFetchError } from '../../lib/describe-fetch-error.ts';
|
|
15
16
|
|
|
@@ -99,6 +100,7 @@ export async function unpublishRealm(
|
|
|
99
100
|
|
|
100
101
|
interface UnpublishCliOptions {
|
|
101
102
|
tolerateMissing?: boolean;
|
|
103
|
+
json?: boolean;
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
export function registerUnpublishCommand(realm: Command): void {
|
|
@@ -110,11 +112,20 @@ export function registerUnpublishCommand(realm: Command): void {
|
|
|
110
112
|
'--tolerate-missing',
|
|
111
113
|
'Exit successfully when the realm is already unpublished',
|
|
112
114
|
)
|
|
115
|
+
.option('--json', 'Output the result as JSON')
|
|
113
116
|
.action(async (publishedRealmURL: string, opts: UnpublishCliOptions) => {
|
|
114
117
|
let result = await unpublishRealm(publishedRealmURL, {
|
|
115
118
|
tolerateMissing: opts.tolerateMissing === true,
|
|
116
119
|
});
|
|
117
120
|
|
|
121
|
+
if (opts.json) {
|
|
122
|
+
cliLog.output(JSON.stringify(result, null, 2));
|
|
123
|
+
if (result.error) {
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
118
129
|
if (result.error) {
|
|
119
130
|
console.error(`${FG_RED}Error:${RESET} ${result.error}`);
|
|
120
131
|
process.exit(1);
|