@sanity/workbench-cli 1.10.0 → 2.0.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/dist/_exports/build.d.ts +2 -3
- package/dist/_exports/deploy.d.ts +48 -8
- package/dist/_exports/deploy.js +1 -0
- package/dist/_exports/deploy.js.map +1 -1
- package/dist/_exports/index.d.ts +0 -11
- package/dist/_exports/index.js +0 -1
- package/dist/_exports/index.js.map +1 -1
- package/dist/_exports/undeploy.d.ts +12 -9
- package/dist/actions/deploy/deployConfig.js +2 -2
- package/dist/actions/deploy/deployConfig.js.map +1 -1
- package/dist/actions/deploy/deployPayload.js +29 -0
- package/dist/actions/deploy/deployPayload.js.map +1 -0
- package/dist/actions/deploy/deployWorkbenchApp.js +8 -7
- package/dist/actions/deploy/deployWorkbenchApp.js.map +1 -1
- package/dist/actions/deploy/summarizeInterfaces.js +10 -13
- package/dist/actions/deploy/summarizeInterfaces.js.map +1 -1
- package/dist/actions/dev/startDevServerRegistration.js +13 -10
- package/dist/actions/dev/startDevServerRegistration.js.map +1 -1
- package/dist/actions/preview/startWorkbenchPreview.js +2 -5
- package/dist/actions/preview/startWorkbenchPreview.js.map +1 -1
- package/dist/actions/undeploy/workbenchUndeployAdapter.js +20 -24
- package/dist/actions/undeploy/workbenchUndeployAdapter.js.map +1 -1
- package/dist/appId.js +2 -11
- package/dist/appId.js.map +1 -1
- package/dist/services/applications.js +5 -2
- package/dist/services/applications.js.map +1 -1
- package/package.json +3 -3
package/dist/_exports/build.d.ts
CHANGED
|
@@ -14,9 +14,8 @@ declare type AssetSourceView = Extract<
|
|
|
14
14
|
/**
|
|
15
15
|
* The `build`/`start` id — a hash of the app's declared shape (its identity, not
|
|
16
16
|
* its code), so the bundle inlined by `sanity build` and the registry entry
|
|
17
|
-
* advertised by `sanity start` resolve to the same id.
|
|
18
|
-
*
|
|
19
|
-
* home. `sanity deploy` resolves its own id from the applications API.
|
|
17
|
+
* advertised by `sanity start` resolve to the same id. `sanity deploy` resolves
|
|
18
|
+
* its own id from the applications API.
|
|
20
19
|
*/
|
|
21
20
|
export declare function buildAppId(app: ResolvedWorkbenchApp): Promise<string>;
|
|
22
21
|
|
|
@@ -21,6 +21,15 @@ declare type AssetSourceView = Extract<
|
|
|
21
21
|
}
|
|
22
22
|
>;
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* A resource a deployment may interact with, as Brett stores it. Per-deployment
|
|
26
|
+
* and forbidden for singletons (the server 400s).
|
|
27
|
+
*/
|
|
28
|
+
export declare interface BrettAccess {
|
|
29
|
+
resourceId: string;
|
|
30
|
+
resourceType: "canvas" | "dashboard" | "dataset" | "media-library";
|
|
31
|
+
}
|
|
32
|
+
|
|
24
33
|
/** A studio workspace as Brett stores it. */
|
|
25
34
|
export declare interface BrettWorkspace {
|
|
26
35
|
dataset: string;
|
|
@@ -57,13 +66,11 @@ export declare function createCoreApp(options: {
|
|
|
57
66
|
}): Promise<CreatedApplication>;
|
|
58
67
|
|
|
59
68
|
/**
|
|
60
|
-
*
|
|
61
|
-
* The caller builds and deploys with the id, and calls `rollback` if a later
|
|
62
|
-
* step fails so the record isn't stranded at its slug.
|
|
69
|
+
* `rollback` undoes the creation, so a later failure leaves no record stranded at the slug.
|
|
63
70
|
* @internal
|
|
64
71
|
*/
|
|
65
72
|
export declare interface CreatedApplication {
|
|
66
|
-
|
|
73
|
+
application: Application;
|
|
67
74
|
rollback: () => Promise<void>;
|
|
68
75
|
}
|
|
69
76
|
|
|
@@ -273,7 +280,7 @@ export declare function deployConfig(options: {
|
|
|
273
280
|
}): Promise<void>;
|
|
274
281
|
|
|
275
282
|
/** A view or service as the deploy report and `--json` output surface it. */
|
|
276
|
-
export declare interface
|
|
283
|
+
export declare interface DeployedInterface {
|
|
277
284
|
name: string;
|
|
278
285
|
src: string;
|
|
279
286
|
title: string;
|
|
@@ -292,6 +299,7 @@ export declare interface DeployedExpose {
|
|
|
292
299
|
* @internal
|
|
293
300
|
*/
|
|
294
301
|
export declare function deployWorkbenchApp(options: {
|
|
302
|
+
access?: readonly BrettAccess[];
|
|
295
303
|
app: CliConfig["app"];
|
|
296
304
|
applicationId: string;
|
|
297
305
|
icon?: string;
|
|
@@ -374,16 +382,16 @@ export declare function summarizeConfig(config: {
|
|
|
374
382
|
}): string;
|
|
375
383
|
|
|
376
384
|
/**
|
|
377
|
-
*
|
|
378
|
-
* and one report line per non-empty group (for the human report).
|
|
385
|
+
* One report line per non-empty group, alongside the records `--json` reports.
|
|
379
386
|
* @internal
|
|
380
387
|
*/
|
|
381
388
|
export declare function summarizeInterfaces({
|
|
382
389
|
services,
|
|
383
390
|
views,
|
|
384
391
|
}: WorkbenchExposes): {
|
|
385
|
-
exposes: DeployedExpose[];
|
|
386
392
|
lines: string[];
|
|
393
|
+
services: DeployedInterface[];
|
|
394
|
+
views: DeployedInterface[];
|
|
387
395
|
};
|
|
388
396
|
|
|
389
397
|
/** The `tile` variant of an app's `views`. @public */
|
|
@@ -394,6 +402,26 @@ declare type TileView = Extract<
|
|
|
394
402
|
}
|
|
395
403
|
>;
|
|
396
404
|
|
|
405
|
+
/**
|
|
406
|
+
* Gated once so a plain app can't pick up a stray key: without a workbench
|
|
407
|
+
* there is nothing to contribute. `views` and `services` travel together.
|
|
408
|
+
*/
|
|
409
|
+
export declare function toWorkbenchPayload(
|
|
410
|
+
workbench: DeployableWorkbenchApp | null,
|
|
411
|
+
{
|
|
412
|
+
config,
|
|
413
|
+
interfaces,
|
|
414
|
+
title,
|
|
415
|
+
}: {
|
|
416
|
+
config?: string;
|
|
417
|
+
interfaces: {
|
|
418
|
+
services: DeployedInterface[];
|
|
419
|
+
views: DeployedInterface[];
|
|
420
|
+
} | null;
|
|
421
|
+
title: string;
|
|
422
|
+
},
|
|
423
|
+
): Partial<WorkbenchDeployPayload>;
|
|
424
|
+
|
|
397
425
|
declare type ViewDeploymentPayload = z.infer<
|
|
398
426
|
typeof viewDeploymentPayloadSchema
|
|
399
427
|
>;
|
|
@@ -443,6 +471,18 @@ declare const WORKBENCH_APP: unique symbol;
|
|
|
443
471
|
declare type WorkbenchApp = DefineAppResult &
|
|
444
472
|
z.output<typeof DefineAppInputSchema>;
|
|
445
473
|
|
|
474
|
+
/** What a workbench app contributes to a deploy payload. */
|
|
475
|
+
export declare interface WorkbenchDeployPayload {
|
|
476
|
+
slug: string;
|
|
477
|
+
title: string;
|
|
478
|
+
/** Media-library config summary. */
|
|
479
|
+
config?: string;
|
|
480
|
+
isSingleton?: boolean;
|
|
481
|
+
services?: DeployedInterface[];
|
|
482
|
+
views?: DeployedInterface[];
|
|
483
|
+
visibility?: string;
|
|
484
|
+
}
|
|
485
|
+
|
|
446
486
|
/**
|
|
447
487
|
* Bundled so adding a declaration family touches this type and the artifact
|
|
448
488
|
* expanders, not every hop of build/dev plumbing in between.
|
package/dist/_exports/deploy.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { checkBuiltOutput } from '../actions/deploy/checkBuiltOutput.js';
|
|
2
2
|
export { deployConfig, resolveInstallationId, summarizeConfig } from '../actions/deploy/deployConfig.js';
|
|
3
|
+
export { toWorkbenchPayload } from '../actions/deploy/deployPayload.js';
|
|
3
4
|
export { createCoreApp, createStudio, deployWorkbenchApp } from '../actions/deploy/deployWorkbenchApp.js';
|
|
4
5
|
export { getWorkbench } from '../actions/deploy/getWorkbench.js';
|
|
5
6
|
export { summarizeInterfaces } from '../actions/deploy/summarizeInterfaces.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/_exports/deploy.ts"],"sourcesContent":["export {checkBuiltOutput} from '../actions/deploy/checkBuiltOutput.js'\nexport {\n deployConfig,\n resolveInstallationId,\n summarizeConfig,\n} from '../actions/deploy/deployConfig.js'\nexport {\n createCoreApp,\n type CreatedApplication,\n createStudio,\n deployWorkbenchApp,\n} from '../actions/deploy/deployWorkbenchApp.js'\nexport {getWorkbench} from '../actions/deploy/getWorkbench.js'\nexport {type
|
|
1
|
+
{"version":3,"sources":["../../src/_exports/deploy.ts"],"sourcesContent":["export {checkBuiltOutput} from '../actions/deploy/checkBuiltOutput.js'\nexport {\n deployConfig,\n resolveInstallationId,\n summarizeConfig,\n} from '../actions/deploy/deployConfig.js'\nexport {toWorkbenchPayload, type WorkbenchDeployPayload} from '../actions/deploy/deployPayload.js'\nexport {\n createCoreApp,\n type CreatedApplication,\n createStudio,\n deployWorkbenchApp,\n} from '../actions/deploy/deployWorkbenchApp.js'\nexport {getWorkbench} from '../actions/deploy/getWorkbench.js'\nexport {type DeployedInterface, summarizeInterfaces} from '../actions/deploy/summarizeInterfaces.js'\nexport {\n type Application,\n type BrettAccess,\n type BrettWorkspace,\n getApplication,\n getApplicationUrl,\n getWorkbenchUrl,\n listApplications,\n} from '../services/applications.js'\n"],"names":["checkBuiltOutput","deployConfig","resolveInstallationId","summarizeConfig","toWorkbenchPayload","createCoreApp","createStudio","deployWorkbenchApp","getWorkbench","summarizeInterfaces","getApplication","getApplicationUrl","getWorkbenchUrl","listApplications"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wCAAuC;AACtE,SACEC,YAAY,EACZC,qBAAqB,EACrBC,eAAe,QACV,oCAAmC;AAC1C,SAAQC,kBAAkB,QAAoC,qCAAoC;AAClG,SACEC,aAAa,EAEbC,YAAY,EACZC,kBAAkB,QACb,0CAAyC;AAChD,SAAQC,YAAY,QAAO,oCAAmC;AAC9D,SAAgCC,mBAAmB,QAAO,2CAA0C;AACpG,SAIEC,cAAc,EACdC,iBAAiB,EACjBC,eAAe,EACfC,gBAAgB,QACX,8BAA6B"}
|
package/dist/_exports/index.d.ts
CHANGED
|
@@ -290,17 +290,6 @@ export declare type PanelViewProps = ViewComponentBaseProps<{
|
|
|
290
290
|
type: "panel";
|
|
291
291
|
}>;
|
|
292
292
|
|
|
293
|
-
/**
|
|
294
|
-
* The dev id for a workbench app — the address the server bound. `sanity dev`
|
|
295
|
-
* keys on where the app is served so a running app can't collide with its
|
|
296
|
-
* deployed twin. Sync and dependency-free: it's re-exported from the package's
|
|
297
|
-
* browser-facing entry, so it must not pull in `node:crypto`.
|
|
298
|
-
*/
|
|
299
|
-
export declare function resolveAppId(source: {
|
|
300
|
-
host: string;
|
|
301
|
-
port: number;
|
|
302
|
-
}): string;
|
|
303
|
-
|
|
304
293
|
/** @internal */
|
|
305
294
|
declare const SERVICE_CONTRACT_VERSION = 1;
|
|
306
295
|
|
package/dist/_exports/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/_exports/index.ts"],"sourcesContent":["export
|
|
1
|
+
{"version":3,"sources":["../../src/_exports/index.ts"],"sourcesContent":["export type {InterfaceType, ServiceType, TileSize} from '../contract.js'\nexport {isWorkbenchApp, unstable_defineApp, unstable_defineMediaLibrary} from '../defineApp.js'\nexport type {\n DefineAppInput,\n DefineAppResult,\n DefineMediaLibraryInput,\n DockGroup,\n MediaLibraryField,\n WorkbenchApp,\n} from '../defineApp.js'\nexport {unstable_defineService} from '../defineService.js'\nexport type {\n DefinedService,\n ServiceCallback,\n ServiceContext,\n ServiceInfo,\n} from '../defineService.js'\nexport {unstable_defineView} from '../defineView.js'\nexport type {\n AssetSourceComponent,\n AssetSourceViewComponents,\n DefinedView,\n PanelComponent,\n PanelViewComponents,\n PanelViewProps,\n TileComponent,\n TileViewComponents,\n TileViewProps,\n ViewComponentsByType,\n} from '../defineView.js'\n"],"names":["isWorkbenchApp","unstable_defineApp","unstable_defineMediaLibrary","unstable_defineService","unstable_defineView"],"mappings":"AACA,SAAQA,cAAc,EAAEC,kBAAkB,EAAEC,2BAA2B,QAAO,kBAAiB;AAS/F,SAAQC,sBAAsB,QAAO,sBAAqB;AAO1D,SAAQC,mBAAmB,QAAO,mBAAkB"}
|
|
@@ -12,6 +12,14 @@ declare type AssetSourceView = Extract<
|
|
|
12
12
|
}
|
|
13
13
|
>;
|
|
14
14
|
|
|
15
|
+
declare interface ConfigSnapshot {
|
|
16
|
+
id: string;
|
|
17
|
+
createdAt?: string;
|
|
18
|
+
deployedBy?: string;
|
|
19
|
+
/** Whether this snapshot is the one being served; at most one per installation. */
|
|
20
|
+
isActive?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
15
23
|
/**
|
|
16
24
|
* The undeploy adapter for workbench apps, mirroring what a workbench deploy
|
|
17
25
|
* creates: apps that expose interfaces delete their Brett application (the
|
|
@@ -205,7 +213,7 @@ declare interface DeployableWorkbenchApp extends ResolvedWorkbenchApp {
|
|
|
205
213
|
}
|
|
206
214
|
|
|
207
215
|
/** A view or service as the deploy report and `--json` output surface it. */
|
|
208
|
-
declare interface
|
|
216
|
+
declare interface DeployedInterface {
|
|
209
217
|
name: string;
|
|
210
218
|
src: string;
|
|
211
219
|
title: string;
|
|
@@ -295,16 +303,11 @@ declare type WorkbenchApp = DefineAppResult &
|
|
|
295
303
|
/** The workbench extension of the shared target; serializes into `--json` as-is. */
|
|
296
304
|
declare type WorkbenchUndeployTarget =
|
|
297
305
|
| (UndeployApplicationTarget & {
|
|
298
|
-
|
|
299
|
-
|
|
306
|
+
services: DeployedInterface[];
|
|
307
|
+
views: DeployedInterface[];
|
|
300
308
|
})
|
|
301
309
|
| (UndeployConfigTarget & {
|
|
302
|
-
|
|
303
|
-
configs: {
|
|
304
|
-
createdAt: string | null;
|
|
305
|
-
deployedBy: string | null;
|
|
306
|
-
id: string;
|
|
307
|
-
}[];
|
|
310
|
+
configs: ConfigSnapshot[];
|
|
308
311
|
});
|
|
309
312
|
|
|
310
313
|
export {};
|
|
@@ -5,7 +5,7 @@ import { subdebug } from '@sanity/cli-core';
|
|
|
5
5
|
import { pack } from 'tar-fs';
|
|
6
6
|
import { getWorkbenchUrl } from '../../services/applications.js';
|
|
7
7
|
import { createConfig, resolveSingletonInstallationId } from '../../services/installations.js';
|
|
8
|
-
import {
|
|
8
|
+
import { summarizeGroup } from './summarizeInterfaces.js';
|
|
9
9
|
const debug = subdebug('deploy');
|
|
10
10
|
/**
|
|
11
11
|
* The org's active installation for an app type, or `undefined` when none is
|
|
@@ -31,7 +31,7 @@ const debug = subdebug('deploy');
|
|
|
31
31
|
switch(config.appType){
|
|
32
32
|
case 'media-library':
|
|
33
33
|
{
|
|
34
|
-
return
|
|
34
|
+
return summarizeGroup('Media library fields', config.fields);
|
|
35
35
|
}
|
|
36
36
|
default:
|
|
37
37
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/deploy/deployConfig.ts"],"sourcesContent":["import {basename, dirname} from 'node:path'\nimport {styleText} from 'node:util'\nimport {createGzip} from 'node:zlib'\n\nimport {type Output, subdebug} from '@sanity/cli-core'\nimport {pack} from 'tar-fs'\n\nimport {getWorkbenchUrl} from '../../services/applications.js'\nimport {createConfig, resolveSingletonInstallationId} from '../../services/installations.js'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/deploy/deployConfig.ts"],"sourcesContent":["import {basename, dirname} from 'node:path'\nimport {styleText} from 'node:util'\nimport {createGzip} from 'node:zlib'\n\nimport {type Output, subdebug} from '@sanity/cli-core'\nimport {pack} from 'tar-fs'\n\nimport {getWorkbenchUrl} from '../../services/applications.js'\nimport {createConfig, resolveSingletonInstallationId} from '../../services/installations.js'\nimport {summarizeGroup} from './summarizeInterfaces.js'\n\nconst debug = subdebug('deploy')\n\n/**\n * The org's active installation for an app type, or `undefined` when none is\n * installed. Read-only, so `--dry-run` can report deployability.\n * @internal\n */\nexport async function resolveInstallationId(options: {\n appType: string\n organizationId: string\n}): Promise<string | undefined> {\n switch (options.appType) {\n case 'media-library': {\n return resolveSingletonInstallationId(options.organizationId, 'media-library')\n }\n default: {\n throw new Error(`Cannot create config for unknown app type: ${options.appType}`)\n }\n }\n}\n\n/**\n * A report heading and item list for a config; a media library's `fields` are\n * one of potentially many shapes.\n * @internal\n */\nexport function summarizeConfig(config: {\n appType: string\n fields: {name: string; src: string; title: string}[]\n}): string {\n switch (config.appType) {\n case 'media-library': {\n return summarizeGroup('Media library fields', config.fields)\n }\n default: {\n throw new Error(`Cannot create config for unknown app type: ${config.appType}`)\n }\n }\n}\n\n/**\n * Upload the built module-federation remote to the installation as its config\n * snapshot. `installationId` is resolved by the caller so `--dry-run` never\n * reaches this mutating step.\n * @internal\n */\nexport async function deployConfig(options: {\n appType: string\n installationId: string\n organizationId: string\n output: Output\n sourceDir: string\n version: string\n}): Promise<void> {\n const {appType, installationId, organizationId, output, sourceDir, version} = options\n const tarball = pack(dirname(sourceDir), {entries: [basename(sourceDir)]}).pipe(createGzip())\n await createConfig(installationId, {tarball, version})\n\n debug('Deployed config for app type: %s', appType)\n const url = getWorkbenchUrl(organizationId)\n output.log(`\\n🚀 ${styleText('bold', 'Success!')} Config deployed to ${styleText('cyan', url)}`)\n}\n"],"names":["basename","dirname","styleText","createGzip","subdebug","pack","getWorkbenchUrl","createConfig","resolveSingletonInstallationId","summarizeGroup","debug","resolveInstallationId","options","appType","organizationId","Error","summarizeConfig","config","fields","deployConfig","installationId","output","sourceDir","version","tarball","entries","pipe","url","log"],"mappings":"AAAA,SAAQA,QAAQ,EAAEC,OAAO,QAAO,YAAW;AAC3C,SAAQC,SAAS,QAAO,YAAW;AACnC,SAAQC,UAAU,QAAO,YAAW;AAEpC,SAAqBC,QAAQ,QAAO,mBAAkB;AACtD,SAAQC,IAAI,QAAO,SAAQ;AAE3B,SAAQC,eAAe,QAAO,iCAAgC;AAC9D,SAAQC,YAAY,EAAEC,8BAA8B,QAAO,kCAAiC;AAC5F,SAAQC,cAAc,QAAO,2BAA0B;AAEvD,MAAMC,QAAQN,SAAS;AAEvB;;;;CAIC,GACD,OAAO,eAAeO,sBAAsBC,OAG3C;IACC,OAAQA,QAAQC,OAAO;QACrB,KAAK;YAAiB;gBACpB,OAAOL,+BAA+BI,QAAQE,cAAc,EAAE;YAChE;QACA;YAAS;gBACP,MAAM,IAAIC,MAAM,CAAC,2CAA2C,EAAEH,QAAQC,OAAO,EAAE;YACjF;IACF;AACF;AAEA;;;;CAIC,GACD,OAAO,SAASG,gBAAgBC,MAG/B;IACC,OAAQA,OAAOJ,OAAO;QACpB,KAAK;YAAiB;gBACpB,OAAOJ,eAAe,wBAAwBQ,OAAOC,MAAM;YAC7D;QACA;YAAS;gBACP,MAAM,IAAIH,MAAM,CAAC,2CAA2C,EAAEE,OAAOJ,OAAO,EAAE;YAChF;IACF;AACF;AAEA;;;;;CAKC,GACD,OAAO,eAAeM,aAAaP,OAOlC;IACC,MAAM,EAACC,OAAO,EAAEO,cAAc,EAAEN,cAAc,EAAEO,MAAM,EAAEC,SAAS,EAAEC,OAAO,EAAC,GAAGX;IAC9E,MAAMY,UAAUnB,KAAKJ,QAAQqB,YAAY;QAACG,SAAS;YAACzB,SAASsB;SAAW;IAAA,GAAGI,IAAI,CAACvB;IAChF,MAAMI,aAAaa,gBAAgB;QAACI;QAASD;IAAO;IAEpDb,MAAM,oCAAoCG;IAC1C,MAAMc,MAAMrB,gBAAgBQ;IAC5BO,OAAOO,GAAG,CAAC,CAAC,KAAK,EAAE1B,UAAU,QAAQ,YAAY,oBAAoB,EAAEA,UAAU,QAAQyB,MAAM;AACjG"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gated once so a plain app can't pick up a stray key: without a workbench
|
|
3
|
+
* there is nothing to contribute. `views` and `services` travel together.
|
|
4
|
+
*/ export function toWorkbenchPayload(workbench, { config, interfaces, title }) {
|
|
5
|
+
if (!workbench) return {};
|
|
6
|
+
const { services, views } = interfaces ?? {
|
|
7
|
+
services: [],
|
|
8
|
+
views: []
|
|
9
|
+
};
|
|
10
|
+
return {
|
|
11
|
+
...config ? {
|
|
12
|
+
config
|
|
13
|
+
} : {},
|
|
14
|
+
...workbench.isSingleton === undefined ? {} : {
|
|
15
|
+
isSingleton: workbench.isSingleton
|
|
16
|
+
},
|
|
17
|
+
...services.length > 0 || views.length > 0 ? {
|
|
18
|
+
services,
|
|
19
|
+
views
|
|
20
|
+
} : {},
|
|
21
|
+
slug: workbench.slug,
|
|
22
|
+
title,
|
|
23
|
+
...workbench.visibility ? {
|
|
24
|
+
visibility: workbench.visibility
|
|
25
|
+
} : {}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=deployPayload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/deploy/deployPayload.ts"],"sourcesContent":["import {type DeployableWorkbenchApp} from './getWorkbench.js'\nimport {type DeployedInterface} from './summarizeInterfaces.js'\n\n/** What a workbench app contributes to a deploy payload. */\nexport interface WorkbenchDeployPayload {\n slug: string\n title: string\n\n /** Media-library config summary. */\n config?: string\n isSingleton?: boolean\n services?: DeployedInterface[]\n views?: DeployedInterface[]\n visibility?: string\n}\n\n/**\n * Gated once so a plain app can't pick up a stray key: without a workbench\n * there is nothing to contribute. `views` and `services` travel together.\n */\nexport function toWorkbenchPayload(\n workbench: DeployableWorkbenchApp | null,\n {\n config,\n interfaces,\n title,\n }: {\n config?: string\n interfaces: {services: DeployedInterface[]; views: DeployedInterface[]} | null\n title: string\n },\n): Partial<WorkbenchDeployPayload> {\n if (!workbench) return {}\n const {services, views} = interfaces ?? {services: [], views: []}\n return {\n ...(config ? {config} : {}),\n ...(workbench.isSingleton === undefined ? {} : {isSingleton: workbench.isSingleton}),\n ...(services.length > 0 || views.length > 0 ? {services, views} : {}),\n slug: workbench.slug,\n title,\n ...(workbench.visibility ? {visibility: workbench.visibility} : {}),\n }\n}\n"],"names":["toWorkbenchPayload","workbench","config","interfaces","title","services","views","isSingleton","undefined","length","slug","visibility"],"mappings":"AAgBA;;;CAGC,GACD,OAAO,SAASA,mBACdC,SAAwC,EACxC,EACEC,MAAM,EACNC,UAAU,EACVC,KAAK,EAKN;IAED,IAAI,CAACH,WAAW,OAAO,CAAC;IACxB,MAAM,EAACI,QAAQ,EAAEC,KAAK,EAAC,GAAGH,cAAc;QAACE,UAAU,EAAE;QAAEC,OAAO,EAAE;IAAA;IAChE,OAAO;QACL,GAAIJ,SAAS;YAACA;QAAM,IAAI,CAAC,CAAC;QAC1B,GAAID,UAAUM,WAAW,KAAKC,YAAY,CAAC,IAAI;YAACD,aAAaN,UAAUM,WAAW;QAAA,CAAC;QACnF,GAAIF,SAASI,MAAM,GAAG,KAAKH,MAAMG,MAAM,GAAG,IAAI;YAACJ;YAAUC;QAAK,IAAI,CAAC,CAAC;QACpEI,MAAMT,UAAUS,IAAI;QACpBN;QACA,GAAIH,UAAUU,UAAU,GAAG;YAACA,YAAYV,UAAUU,UAAU;QAAA,IAAI,CAAC,CAAC;IACpE;AACF"}
|
|
@@ -11,14 +11,14 @@ import { createApplication, createDeployment, deleteApplication, updateApplicati
|
|
|
11
11
|
*/ export async function createCoreApp(options) {
|
|
12
12
|
const spin = spinner('Creating application...').start();
|
|
13
13
|
try {
|
|
14
|
-
const
|
|
14
|
+
const application = await createApplication({
|
|
15
15
|
...options,
|
|
16
16
|
type: 'coreApp'
|
|
17
17
|
});
|
|
18
18
|
spin.succeed();
|
|
19
19
|
return {
|
|
20
|
-
|
|
21
|
-
rollback: ()=>deleteApplication(id)
|
|
20
|
+
application,
|
|
21
|
+
rollback: ()=>deleteApplication(application.id)
|
|
22
22
|
};
|
|
23
23
|
} catch (error) {
|
|
24
24
|
spin.fail();
|
|
@@ -31,14 +31,14 @@ import { createApplication, createDeployment, deleteApplication, updateApplicati
|
|
|
31
31
|
*/ export async function createStudio(options) {
|
|
32
32
|
const spin = spinner('Creating studio...').start();
|
|
33
33
|
try {
|
|
34
|
-
const
|
|
34
|
+
const application = await createApplication({
|
|
35
35
|
...options,
|
|
36
36
|
type: 'studio'
|
|
37
37
|
});
|
|
38
38
|
spin.succeed();
|
|
39
39
|
return {
|
|
40
|
-
|
|
41
|
-
rollback: ()=>deleteApplication(id)
|
|
40
|
+
application,
|
|
41
|
+
rollback: ()=>deleteApplication(application.id)
|
|
42
42
|
};
|
|
43
43
|
} catch (error) {
|
|
44
44
|
spin.fail();
|
|
@@ -56,7 +56,7 @@ import { createApplication, createDeployment, deleteApplication, updateApplicati
|
|
|
56
56
|
* application once it has an active deployment.
|
|
57
57
|
* @internal
|
|
58
58
|
*/ export async function deployWorkbenchApp(options) {
|
|
59
|
-
const { app, applicationId, icon, isApp, isAutoUpdating, label = 'Deploying...', onDeployed, sourceDir, title, version, visibility, workspaces } = options;
|
|
59
|
+
const { access, app, applicationId, icon, isApp, isAutoUpdating, label = 'Deploying...', onDeployed, sourceDir, title, version, visibility, workspaces } = options;
|
|
60
60
|
const tarball = pack(dirname(sourceDir), {
|
|
61
61
|
entries: [
|
|
62
62
|
basename(sourceDir)
|
|
@@ -65,6 +65,7 @@ import { createApplication, createDeployment, deleteApplication, updateApplicati
|
|
|
65
65
|
const spin = spinner(label).start();
|
|
66
66
|
try {
|
|
67
67
|
await createDeployment({
|
|
68
|
+
access,
|
|
68
69
|
applicationId,
|
|
69
70
|
// Brett assigns the id and resolves modules by `moduleId`, so neither travels.
|
|
70
71
|
interfaces: deriveInterfaces(app, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/deploy/deployWorkbenchApp.ts"],"sourcesContent":["import {basename, dirname} from 'node:path'\nimport {createGzip} from 'node:zlib'\n\nimport {type AppVisibility, type CliConfig} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {pack} from 'tar-fs'\n\nimport {deriveInterfaces} from '../../deriveInterfaces.js'\nimport {\n type BrettInterface,\n type BrettWorkspace,\n createApplication,\n createDeployment,\n deleteApplication,\n updateApplication,\n} from '../../services/applications.js'\n\n/**\n *
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/deploy/deployWorkbenchApp.ts"],"sourcesContent":["import {basename, dirname} from 'node:path'\nimport {createGzip} from 'node:zlib'\n\nimport {type AppVisibility, type CliConfig} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {pack} from 'tar-fs'\n\nimport {deriveInterfaces} from '../../deriveInterfaces.js'\nimport {\n type Application,\n type BrettAccess,\n type BrettInterface,\n type BrettWorkspace,\n createApplication,\n createDeployment,\n deleteApplication,\n updateApplication,\n} from '../../services/applications.js'\n\n/**\n * `rollback` undoes the creation, so a later failure leaves no record stranded at the slug.\n * @internal\n */\nexport interface CreatedApplication {\n application: Application\n rollback: () => Promise<void>\n}\n\n/**\n * Create a coreApp record (no deployment), so the CLI can build with its id\n * before shipping the first deployment. First deploy only.\n * @internal\n */\nexport async function createCoreApp(options: {\n isSingleton?: boolean\n organizationId: string\n slug: string\n title: string\n visibility?: AppVisibility\n}): Promise<CreatedApplication> {\n const spin = spinner('Creating application...').start()\n try {\n const application = await createApplication({...options, type: 'coreApp'})\n spin.succeed()\n return {application, rollback: () => deleteApplication(application.id)}\n } catch (error) {\n spin.fail()\n throw error\n }\n}\n\n/**\n * Create a studio record (no deployment).\n * @internal\n */\nexport async function createStudio(options: {\n organizationId: string\n projectId: string | undefined\n slug: string\n title: string\n visibility?: AppVisibility\n}): Promise<CreatedApplication> {\n const spin = spinner('Creating studio...').start()\n try {\n const application = await createApplication({...options, type: 'studio'})\n spin.succeed()\n return {application, rollback: () => deleteApplication(application.id)}\n } catch (error) {\n spin.fail()\n throw error\n }\n}\n\n/**\n * Ship a deployment to an already-created (or `deployment.appId`) application,\n * then sync its mutable metadata (`title`, and `icon`/`visibility` when set)\n * from config. The deploy endpoint ignores these, so a redeploy patches them\n * here alongside the new deployment.\n *\n * `onDeployed` fires the instant the deployment is live, before the metadata\n * sync — so a caller can disarm a create-time rollback that must not delete an\n * application once it has an active deployment.\n * @internal\n */\nexport async function deployWorkbenchApp(options: {\n access?: readonly BrettAccess[]\n app: CliConfig['app']\n applicationId: string\n icon?: string\n isApp: boolean\n isAutoUpdating: boolean\n label?: string\n onDeployed?: () => void\n sourceDir: string\n title: string\n version: string\n visibility?: AppVisibility\n workspaces?: readonly BrettWorkspace[]\n}): Promise<void> {\n const {\n access,\n app,\n applicationId,\n icon,\n isApp,\n isAutoUpdating,\n label = 'Deploying...',\n onDeployed,\n sourceDir,\n title,\n version,\n visibility,\n workspaces,\n } = options\n const tarball = pack(dirname(sourceDir), {entries: [basename(sourceDir)]}).pipe(createGzip())\n\n const spin = spinner(label).start()\n try {\n await createDeployment({\n access,\n applicationId,\n // Brett assigns the id and resolves modules by `moduleId`, so neither travels.\n interfaces: deriveInterfaces(app, {appTitle: title, isApp}).map(\n ({id: _id, src: _src, ...iface}): BrettInterface => ({...iface, version}),\n ),\n isAutoUpdating,\n tarball,\n version,\n workspaces,\n })\n onDeployed?.()\n await updateApplication(applicationId, {\n title,\n ...(icon ? {icon} : {}),\n ...(visibility ? {visibility} : {}),\n })\n spin.succeed()\n } catch (error) {\n spin.clear()\n throw error\n }\n}\n"],"names":["basename","dirname","createGzip","spinner","pack","deriveInterfaces","createApplication","createDeployment","deleteApplication","updateApplication","createCoreApp","options","spin","start","application","type","succeed","rollback","id","error","fail","createStudio","deployWorkbenchApp","access","app","applicationId","icon","isApp","isAutoUpdating","label","onDeployed","sourceDir","title","version","visibility","workspaces","tarball","entries","pipe","interfaces","appTitle","map","_id","src","_src","iface","clear"],"mappings":"AAAA,SAAQA,QAAQ,EAAEC,OAAO,QAAO,YAAW;AAC3C,SAAQC,UAAU,QAAO,YAAW;AAGpC,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,IAAI,QAAO,SAAQ;AAE3B,SAAQC,gBAAgB,QAAO,4BAA2B;AAC1D,SAKEC,iBAAiB,EACjBC,gBAAgB,EAChBC,iBAAiB,EACjBC,iBAAiB,QACZ,iCAAgC;AAWvC;;;;CAIC,GACD,OAAO,eAAeC,cAAcC,OAMnC;IACC,MAAMC,OAAOT,QAAQ,2BAA2BU,KAAK;IACrD,IAAI;QACF,MAAMC,cAAc,MAAMR,kBAAkB;YAAC,GAAGK,OAAO;YAAEI,MAAM;QAAS;QACxEH,KAAKI,OAAO;QACZ,OAAO;YAACF;YAAaG,UAAU,IAAMT,kBAAkBM,YAAYI,EAAE;QAAC;IACxE,EAAE,OAAOC,OAAO;QACdP,KAAKQ,IAAI;QACT,MAAMD;IACR;AACF;AAEA;;;CAGC,GACD,OAAO,eAAeE,aAAaV,OAMlC;IACC,MAAMC,OAAOT,QAAQ,sBAAsBU,KAAK;IAChD,IAAI;QACF,MAAMC,cAAc,MAAMR,kBAAkB;YAAC,GAAGK,OAAO;YAAEI,MAAM;QAAQ;QACvEH,KAAKI,OAAO;QACZ,OAAO;YAACF;YAAaG,UAAU,IAAMT,kBAAkBM,YAAYI,EAAE;QAAC;IACxE,EAAE,OAAOC,OAAO;QACdP,KAAKQ,IAAI;QACT,MAAMD;IACR;AACF;AAEA;;;;;;;;;;CAUC,GACD,OAAO,eAAeG,mBAAmBX,OAcxC;IACC,MAAM,EACJY,MAAM,EACNC,GAAG,EACHC,aAAa,EACbC,IAAI,EACJC,KAAK,EACLC,cAAc,EACdC,QAAQ,cAAc,EACtBC,UAAU,EACVC,SAAS,EACTC,KAAK,EACLC,OAAO,EACPC,UAAU,EACVC,UAAU,EACX,GAAGxB;IACJ,MAAMyB,UAAUhC,KAAKH,QAAQ8B,YAAY;QAACM,SAAS;YAACrC,SAAS+B;SAAW;IAAA,GAAGO,IAAI,CAACpC;IAEhF,MAAMU,OAAOT,QAAQ0B,OAAOhB,KAAK;IACjC,IAAI;QACF,MAAMN,iBAAiB;YACrBgB;YACAE;YACA,+EAA+E;YAC/Ec,YAAYlC,iBAAiBmB,KAAK;gBAACgB,UAAUR;gBAAOL;YAAK,GAAGc,GAAG,CAC7D,CAAC,EAACvB,IAAIwB,GAAG,EAAEC,KAAKC,IAAI,EAAE,GAAGC,OAAM,GAAsB,CAAA;oBAAC,GAAGA,KAAK;oBAAEZ;gBAAO,CAAA;YAEzEL;YACAQ;YACAH;YACAE;QACF;QACAL;QACA,MAAMrB,kBAAkBgB,eAAe;YACrCO;YACA,GAAIN,OAAO;gBAACA;YAAI,IAAI,CAAC,CAAC;YACtB,GAAIQ,aAAa;gBAACA;YAAU,IAAI,CAAC,CAAC;QACpC;QACAtB,KAAKI,OAAO;IACd,EAAE,OAAOG,OAAO;QACdP,KAAKkC,KAAK;QACV,MAAM3B;IACR;AACF"}
|
|
@@ -2,31 +2,28 @@ const label = (item)=>item.title === item.name ? item.name : `${item.title} (${i
|
|
|
2
2
|
/**
|
|
3
3
|
* One `Title (name): src` report line per declared entry point.
|
|
4
4
|
* @internal
|
|
5
|
-
*/ export function
|
|
5
|
+
*/ export function summarizeGroup(heading, items) {
|
|
6
6
|
return `${heading}:\n${items.map((item)=>` ${label(item)}: ${item.src}`).join('\n')}`;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
* and one report line per non-empty group (for the human report).
|
|
9
|
+
* One report line per non-empty group, alongside the records `--json` reports.
|
|
11
10
|
* @internal
|
|
12
11
|
*/ export function summarizeInterfaces({ services, views }) {
|
|
13
|
-
const
|
|
12
|
+
const toInterface = (decl)=>({
|
|
14
13
|
name: decl.name,
|
|
15
14
|
src: decl.src,
|
|
16
15
|
title: decl.title,
|
|
17
16
|
type: decl.type
|
|
18
17
|
});
|
|
19
|
-
const
|
|
20
|
-
const
|
|
18
|
+
const deployedViews = (views ?? []).map((view)=>toInterface(view));
|
|
19
|
+
const deployedServices = (services ?? []).map((service)=>toInterface(service));
|
|
21
20
|
const lines = [];
|
|
22
|
-
if (
|
|
23
|
-
if (
|
|
21
|
+
if (deployedViews.length > 0) lines.push(summarizeGroup('Views', deployedViews));
|
|
22
|
+
if (deployedServices.length > 0) lines.push(summarizeGroup('Services', deployedServices));
|
|
24
23
|
return {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
],
|
|
29
|
-
lines
|
|
24
|
+
lines,
|
|
25
|
+
services: deployedServices,
|
|
26
|
+
views: deployedViews
|
|
30
27
|
};
|
|
31
28
|
}
|
|
32
29
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/deploy/summarizeInterfaces.ts"],"sourcesContent":["import {type WorkbenchExposes} from '../../resolveWorkbenchApp.js'\n\n/** A view or service as the deploy report and `--json` output surface it. */\nexport interface
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/deploy/summarizeInterfaces.ts"],"sourcesContent":["import {type WorkbenchExposes} from '../../resolveWorkbenchApp.js'\n\n/** A view or service as the deploy report and `--json` output surface it. */\nexport interface DeployedInterface {\n name: string\n src: string\n title: string\n type: string\n}\n\nconst label = (item: {name: string; title: string}) =>\n item.title === item.name ? item.name : `${item.title} (${item.name})`\n\n/**\n * One `Title (name): src` report line per declared entry point.\n * @internal\n */\nexport function summarizeGroup(\n heading: string,\n items: readonly {name: string; src: string; title: string}[],\n): string {\n return `${heading}:\\n${items.map((item) => ` ${label(item)}: ${item.src}`).join('\\n')}`\n}\n\n/**\n * One report line per non-empty group, alongside the records `--json` reports.\n * @internal\n */\nexport function summarizeInterfaces({services, views}: WorkbenchExposes): {\n lines: string[]\n services: DeployedInterface[]\n views: DeployedInterface[]\n} {\n const toInterface = (decl: DeployedInterface): DeployedInterface => ({\n name: decl.name,\n src: decl.src,\n title: decl.title,\n type: decl.type,\n })\n const deployedViews = (views ?? []).map((view) => toInterface(view))\n const deployedServices = (services ?? []).map((service) => toInterface(service))\n\n const lines: string[] = []\n if (deployedViews.length > 0) lines.push(summarizeGroup('Views', deployedViews))\n if (deployedServices.length > 0) lines.push(summarizeGroup('Services', deployedServices))\n return {lines, services: deployedServices, views: deployedViews}\n}\n"],"names":["label","item","title","name","summarizeGroup","heading","items","map","src","join","summarizeInterfaces","services","views","toInterface","decl","type","deployedViews","view","deployedServices","service","lines","length","push"],"mappings":"AAUA,MAAMA,QAAQ,CAACC,OACbA,KAAKC,KAAK,KAAKD,KAAKE,IAAI,GAAGF,KAAKE,IAAI,GAAG,GAAGF,KAAKC,KAAK,CAAC,EAAE,EAAED,KAAKE,IAAI,CAAC,CAAC,CAAC;AAEvE;;;CAGC,GACD,OAAO,SAASC,eACdC,OAAe,EACfC,KAA4D;IAE5D,OAAO,GAAGD,QAAQ,GAAG,EAAEC,MAAMC,GAAG,CAAC,CAACN,OAAS,CAAC,EAAE,EAAED,MAAMC,MAAM,EAAE,EAAEA,KAAKO,GAAG,EAAE,EAAEC,IAAI,CAAC,OAAO;AAC1F;AAEA;;;CAGC,GACD,OAAO,SAASC,oBAAoB,EAACC,QAAQ,EAAEC,KAAK,EAAmB;IAKrE,MAAMC,cAAc,CAACC,OAAgD,CAAA;YACnEX,MAAMW,KAAKX,IAAI;YACfK,KAAKM,KAAKN,GAAG;YACbN,OAAOY,KAAKZ,KAAK;YACjBa,MAAMD,KAAKC,IAAI;QACjB,CAAA;IACA,MAAMC,gBAAgB,AAACJ,CAAAA,SAAS,EAAE,AAAD,EAAGL,GAAG,CAAC,CAACU,OAASJ,YAAYI;IAC9D,MAAMC,mBAAmB,AAACP,CAAAA,YAAY,EAAE,AAAD,EAAGJ,GAAG,CAAC,CAACY,UAAYN,YAAYM;IAEvE,MAAMC,QAAkB,EAAE;IAC1B,IAAIJ,cAAcK,MAAM,GAAG,GAAGD,MAAME,IAAI,CAAClB,eAAe,SAASY;IACjE,IAAIE,iBAAiBG,MAAM,GAAG,GAAGD,MAAME,IAAI,CAAClB,eAAe,YAAYc;IACvE,OAAO;QAACE;QAAOT,UAAUO;QAAkBN,OAAOI;IAAa;AACjE"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { getCliConfigUncached } from '@sanity/cli-core';
|
|
2
|
-
import {
|
|
2
|
+
import { isWorkbenchApp } from '../../defineApp.js';
|
|
3
3
|
import { deriveInterfaces } from '../../deriveInterfaces.js';
|
|
4
4
|
import { formatWorkbenchAppErrors, validateWorkbenchApp } from '../../validateWorkbenchApp.js';
|
|
5
5
|
import { deriveConfigs } from './deriveConfigs.js';
|
|
6
6
|
import { trackExposesSet } from './exposesSetId.js';
|
|
7
|
-
import { registerDevServer } from './registry.js';
|
|
7
|
+
import { getRegisteredServers, registerDevServer } from './registry.js';
|
|
8
8
|
import { startDevManifestWatcher } from './startDevManifestWatcher.js';
|
|
9
9
|
/**
|
|
10
10
|
* Log any config validation errors without aborting. Unlike build and deploy,
|
|
@@ -13,7 +13,6 @@ import { startDevManifestWatcher } from './startDevManifestWatcher.js';
|
|
|
13
13
|
*/ function reportConfigErrors(app, output) {
|
|
14
14
|
const errors = validateWorkbenchApp(app);
|
|
15
15
|
if (errors.length === 0) return;
|
|
16
|
-
// `output.error` exits the process; `warn` keeps the dev server alive.
|
|
17
16
|
output.warn(formatWorkbenchAppErrors(errors));
|
|
18
17
|
}
|
|
19
18
|
/** The address the server actually bound — the live socket, which can differ from the configured port under non-strict ports. */ function serverAddress(server) {
|
|
@@ -38,16 +37,20 @@ import { startDevManifestWatcher } from './startDevManifestWatcher.js';
|
|
|
38
37
|
isApp
|
|
39
38
|
});
|
|
40
39
|
const configs = await deriveConfigs(cliConfig.app);
|
|
40
|
+
const id = isWorkbenchApp(cliConfig.app) ? cliConfig.app.slug : undefined;
|
|
41
|
+
const devServer = id ? getRegisteredServers().find((server)=>server.id === id) : undefined;
|
|
42
|
+
if (id && devServer) {
|
|
43
|
+
output.error(`The app "${id}" is already served by another dev server running on port ${devServer.port}, ` + "so the workbench can't tell them apart and this one stays out of it. " + 'Stop that server, or give this app its own `slug` in sanity.cli.ts.', {
|
|
44
|
+
exit: false
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
close: async ()=>{}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
41
50
|
const registration = registerDevServer({
|
|
42
51
|
configs,
|
|
43
52
|
host: appHost,
|
|
44
|
-
|
|
45
|
-
// collide with its deployed twin — on the configured port, not the bound one,
|
|
46
|
-
// to match `__SANITY_APP_ID__`, compiled before any non-strict shift.
|
|
47
|
-
id: resolveAppId({
|
|
48
|
-
host: appHost,
|
|
49
|
-
port: server.config.server.port ?? appPort
|
|
50
|
-
}),
|
|
53
|
+
id,
|
|
51
54
|
interfaces,
|
|
52
55
|
port: appPort,
|
|
53
56
|
projectId: cliConfig?.api?.projectId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/dev/startDevServerRegistration.ts"],"sourcesContent":["import {type CliConfig, getCliConfigUncached, type Output} from '@sanity/cli-core'\nimport {type ViteDevServer} from 'vite'\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/dev/startDevServerRegistration.ts"],"sourcesContent":["import {type CliConfig, getCliConfigUncached, type Output} from '@sanity/cli-core'\nimport {type ViteDevServer} from 'vite'\n\nimport {isWorkbenchApp} from '../../defineApp.js'\nimport {deriveInterfaces} from '../../deriveInterfaces.js'\nimport {formatWorkbenchAppErrors, validateWorkbenchApp} from '../../validateWorkbenchApp.js'\nimport {deriveConfigs} from './deriveConfigs.js'\nimport {trackExposesSet} from './exposesSetId.js'\nimport {type DevServerManifest, getRegisteredServers, registerDevServer} from './registry.js'\nimport {startDevManifestWatcher} from './startDevManifestWatcher.js'\n\ninterface DevServerRegistrationOptions {\n cliConfig: CliConfig\n /**\n * Extract the project manifest to inline into the registry. The caller owns the\n * studio-vs-app split (manifest formats are CLI-domain); registration re-derives\n * the interface set alongside it.\n */\n extractManifest: (params: {\n configPath: string\n workDir: string\n }) => Promise<DevServerManifest['manifest']>\n isApp: boolean\n output: Output\n server: ViteDevServer\n workDir: string\n\n /**\n * Rebuild the app's federation remote when its interface set changes, awaited\n * *before* the registry patch — the patch reloads the workbench page, which must\n * re-fetch a remote that already exposes the new interface. Resolves with the\n * recreated server so the entry gets its actual address (non-strict ports may\n * shift it); must reject if the restart produces no server, so the set stays\n * uncommitted and the next save retries instead of advertising a dead port.\n */\n onInterfaceSetChange?: () => Promise<ViteDevServer>\n}\n\ninterface DevServerRegistrationHandle {\n close: () => Promise<void>\n}\n\n/**\n * Log any config validation errors without aborting. Unlike build and deploy,\n * dev stays up on an invalid config so the author sees the errors and fixes them\n * live on the next save.\n */\nfunction reportConfigErrors(app: CliConfig['app'], output: Output): void {\n const errors = validateWorkbenchApp(app)\n if (errors.length === 0) return\n output.warn(formatWorkbenchAppErrors(errors))\n}\n\n/** The address the server actually bound — the live socket, which can differ from the configured port under non-strict ports. */\nfunction serverAddress(server: ViteDevServer) {\n const resolvedHost = server.config.server.host\n const addr = server.httpServer?.address()\n return {\n host: typeof resolvedHost === 'string' ? resolvedHost : 'localhost',\n port: typeof addr === 'object' && addr ? addr.port : server.config.server.port,\n }\n}\n\n/**\n * Register the dev server in the registry and watch its config for manifest +\n * interface changes. The workbench reads the entry to locate and render the\n * server; the watcher keeps it current as `sanity.cli.ts` is edited.\n */\nexport async function startDevServerRegistration(\n options: DevServerRegistrationOptions,\n): Promise<DevServerRegistrationHandle> {\n const {cliConfig, extractManifest, isApp, onInterfaceSetChange, output, server, workDir} = options\n\n const {host: appHost, port: appPort} = serverAddress(server)\n\n reportConfigErrors(cliConfig.app, output)\n\n // Forwarded alongside (not inside) the manifest so the workbench renders local\n // panels/workers and reads the configs without a deploy.\n const interfaces = deriveInterfaces(cliConfig.app, {isApp})\n const configs = await deriveConfigs(cliConfig.app)\n\n const id = isWorkbenchApp(cliConfig.app) ? cliConfig.app.slug : undefined\n\n const devServer = id ? getRegisteredServers().find((server) => server.id === id) : undefined\n\n if (id && devServer) {\n output.error(\n `The app \"${id}\" is already served by another dev server running on port ${devServer.port}, ` +\n \"so the workbench can't tell them apart and this one stays out of it. \" +\n 'Stop that server, or give this app its own `slug` in sanity.cli.ts.',\n {exit: false},\n )\n return {close: async () => {}}\n }\n\n const registration = registerDevServer({\n configs,\n host: appHost,\n id,\n interfaces,\n port: appPort,\n projectId: cliConfig?.api?.projectId,\n type: isApp ? 'coreApp' : 'studio',\n workDir,\n })\n\n const exposesSet = trackExposesSet({configs, interfaces})\n\n const watcher = await startDevManifestWatcher({\n // Re-derive every pass (don't omit): the registry patch is a shallow merge,\n // so omitting would wipe the registered set.\n extract: async (params) => {\n const app = (await getCliConfigUncached(params.workDir)).app\n reportConfigErrors(app, output)\n return {\n configs: await deriveConfigs(app),\n interfaces: deriveInterfaces(app, {isApp}),\n manifest: await extractManifest(params),\n }\n },\n // A studio's root resolves to `sanity.config.*` but its interfaces live in\n // `sanity.cli.*` — watch that too. Apps already root at `sanity.cli.*`.\n extraWatchFilenames: isApp ? undefined : ['sanity.cli.js', 'sanity.cli.ts'],\n output,\n update: async (patch) => {\n if (\n !exposesSet.changed({\n configs: patch.configs,\n interfaces: patch.interfaces,\n })\n ) {\n registration.update(patch)\n return\n }\n // Rebuild the remote *before* patching the registry — the patch reloads the\n // page, which must re-fetch a remote that already exposes the new interface.\n const rebuiltServer = await onInterfaceSetChange?.()\n // Commit only after a successful rebuild, so a thrown one retries next pass.\n exposesSet.commit({\n configs: patch.configs,\n interfaces: patch.interfaces,\n })\n // The recreated server can bind a different port (non-strict ports).\n registration.update(rebuiltServer ? {...patch, ...serverAddress(rebuiltServer)} : patch)\n },\n workDir,\n })\n\n return {\n close: async () => {\n registration.release()\n await watcher.close()\n },\n }\n}\n"],"names":["getCliConfigUncached","isWorkbenchApp","deriveInterfaces","formatWorkbenchAppErrors","validateWorkbenchApp","deriveConfigs","trackExposesSet","getRegisteredServers","registerDevServer","startDevManifestWatcher","reportConfigErrors","app","output","errors","length","warn","serverAddress","server","resolvedHost","config","host","addr","httpServer","address","port","startDevServerRegistration","options","cliConfig","extractManifest","isApp","onInterfaceSetChange","workDir","appHost","appPort","interfaces","configs","id","slug","undefined","devServer","find","error","exit","close","registration","projectId","api","type","exposesSet","watcher","extract","params","manifest","extraWatchFilenames","update","patch","changed","rebuiltServer","commit","release"],"mappings":"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"}
|
|
@@ -52,13 +52,10 @@ import { serveBuiltApplication } from './serveBuiltApplication.js';
|
|
|
52
52
|
checkForDeprecatedAppId();
|
|
53
53
|
const configPath = (await findProjectRoot(workDir)).path;
|
|
54
54
|
const workbench = resolveWorkbenchApp(cliConfig);
|
|
55
|
-
|
|
56
|
-
// (which carries the API id, not the shape hash); fall back for older builds.
|
|
55
|
+
if (!workbench) throw new Error('`sanity start` was invoked in a non-workbench application');
|
|
57
56
|
const inlinedId = await readInlinedAppId(outDir);
|
|
58
57
|
const configs = await deriveConfigs(cliConfig.app);
|
|
59
|
-
|
|
60
|
-
// the bundle's `__SANITY_APP_ID__`), not the dev host-port.
|
|
61
|
-
const id = workbench ? inlinedId ?? await buildAppId(workbench) : `${remote.host}-${remote.port}`;
|
|
58
|
+
const id = inlinedId ?? await buildAppId(workbench);
|
|
62
59
|
const registration = registerDevServer({
|
|
63
60
|
configs,
|
|
64
61
|
host: remote.host,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/preview/startWorkbenchPreview.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {type CliConfig, findProjectRoot, type Output} from '@sanity/cli-core'\n\nimport {buildAppId, SANITY_APP_ID_FILE} from '../../appId.js'\nimport {deriveInterfaces} from '../../deriveInterfaces.js'\nimport {resolveWorkbenchApp} from '../../resolveWorkbenchApp.js'\nimport {createServerLifecycle, toDisplayHost} from '../../util/serverOrchestration.js'\nimport {deriveConfigs} from '../dev/deriveConfigs.js'\nimport {type DevServerManifest, registerDevServer} from '../dev/registry.js'\nimport {startWorkbenchDevServer} from '../dev/startWorkbenchDevServer.js'\nimport {serveBuiltApplication} from './serveBuiltApplication.js'\n\nexport interface StartWorkbenchPreviewOptions {\n /** Directory for the workbench Vite server's dependency cache. */\n cacheDir: string\n /** CLI-domain `app.id`/`deployment.appId` deprecation check, run before registering. */\n checkForDeprecatedAppId: () => void\n cliConfig: CliConfig\n /** Extract the project manifest to inline into the registry (studio-vs-app handled by the CLI). */\n extractManifest: (params: {\n configPath: string\n workDir: string\n }) => Promise<DevServerManifest['manifest']>\n httpHost: string\n httpPort: number\n isApp: boolean\n /** The built `dist` directory to serve as the federation remote. */\n outDir: string\n output: Output\n reactStrictMode: boolean\n workDir: string\n}\n\n/**\n * `sanity start` for a workbench app: serve a production build the way dev serves\n * a live one. The same singleton workbench shell renders it and the same registry\n * advertises it — only the remote differs, static files from the build output\n * instead of a live Vite dev server. There's no config watcher or rebuild: a\n * build is fixed, so nothing re-syncs.\n *\n * A running workbench claims the configured port, so the built remote binds the\n * next one. Without one the remote takes the configured port and announces its\n * own URL.\n */\nexport async function startWorkbenchPreview(\n options: StartWorkbenchPreviewOptions,\n): Promise<{close: () => Promise<void>}> {\n const {\n cacheDir,\n checkForDeprecatedAppId,\n cliConfig,\n extractManifest,\n httpHost,\n httpPort,\n isApp,\n outDir,\n output,\n reactStrictMode,\n workDir,\n } = options\n\n const {close, closers, installSignalHandlers} = createServerLifecycle()\n\n const workbench = await startWorkbenchDevServer({\n cacheDir,\n cliConfig,\n httpHost,\n httpPort,\n mode: 'preview',\n output,\n reactStrictMode,\n workDir,\n })\n closers.push(workbench.close)\n\n const remotePort = workbench.workbenchAvailable ? workbench.workbenchPort + 1 : httpPort\n\n const remote = await serveBuiltApplication({\n cacheDir,\n httpHost,\n httpPort: remotePort,\n outDir,\n workDir,\n }).catch(async (err) => {\n await close()\n throw err\n })\n closers.push(remote.close)\n\n try {\n // Callers provide CLI-only validation and manifest extraction to keep them\n // out of workbench-cli.\n checkForDeprecatedAppId()\n const configPath = (await findProjectRoot(workDir)).path\n const workbench = resolveWorkbenchApp(cliConfig)\n
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/preview/startWorkbenchPreview.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {type CliConfig, findProjectRoot, type Output} from '@sanity/cli-core'\n\nimport {buildAppId, SANITY_APP_ID_FILE} from '../../appId.js'\nimport {deriveInterfaces} from '../../deriveInterfaces.js'\nimport {resolveWorkbenchApp} from '../../resolveWorkbenchApp.js'\nimport {createServerLifecycle, toDisplayHost} from '../../util/serverOrchestration.js'\nimport {deriveConfigs} from '../dev/deriveConfigs.js'\nimport {type DevServerManifest, registerDevServer} from '../dev/registry.js'\nimport {startWorkbenchDevServer} from '../dev/startWorkbenchDevServer.js'\nimport {serveBuiltApplication} from './serveBuiltApplication.js'\n\nexport interface StartWorkbenchPreviewOptions {\n /** Directory for the workbench Vite server's dependency cache. */\n cacheDir: string\n /** CLI-domain `app.id`/`deployment.appId` deprecation check, run before registering. */\n checkForDeprecatedAppId: () => void\n cliConfig: CliConfig\n /** Extract the project manifest to inline into the registry (studio-vs-app handled by the CLI). */\n extractManifest: (params: {\n configPath: string\n workDir: string\n }) => Promise<DevServerManifest['manifest']>\n httpHost: string\n httpPort: number\n isApp: boolean\n /** The built `dist` directory to serve as the federation remote. */\n outDir: string\n output: Output\n reactStrictMode: boolean\n workDir: string\n}\n\n/**\n * `sanity start` for a workbench app: serve a production build the way dev serves\n * a live one. The same singleton workbench shell renders it and the same registry\n * advertises it — only the remote differs, static files from the build output\n * instead of a live Vite dev server. There's no config watcher or rebuild: a\n * build is fixed, so nothing re-syncs.\n *\n * A running workbench claims the configured port, so the built remote binds the\n * next one. Without one the remote takes the configured port and announces its\n * own URL.\n */\nexport async function startWorkbenchPreview(\n options: StartWorkbenchPreviewOptions,\n): Promise<{close: () => Promise<void>}> {\n const {\n cacheDir,\n checkForDeprecatedAppId,\n cliConfig,\n extractManifest,\n httpHost,\n httpPort,\n isApp,\n outDir,\n output,\n reactStrictMode,\n workDir,\n } = options\n\n const {close, closers, installSignalHandlers} = createServerLifecycle()\n\n const workbench = await startWorkbenchDevServer({\n cacheDir,\n cliConfig,\n httpHost,\n httpPort,\n mode: 'preview',\n output,\n reactStrictMode,\n workDir,\n })\n closers.push(workbench.close)\n\n const remotePort = workbench.workbenchAvailable ? workbench.workbenchPort + 1 : httpPort\n\n const remote = await serveBuiltApplication({\n cacheDir,\n httpHost,\n httpPort: remotePort,\n outDir,\n workDir,\n }).catch(async (err) => {\n await close()\n throw err\n })\n closers.push(remote.close)\n\n try {\n // Callers provide CLI-only validation and manifest extraction to keep them\n // out of workbench-cli.\n checkForDeprecatedAppId()\n const configPath = (await findProjectRoot(workDir)).path\n const workbench = resolveWorkbenchApp(cliConfig)\n\n if (!workbench) throw new Error('`sanity start` was invoked in a non-workbench application')\n const inlinedId = await readInlinedAppId(outDir)\n const configs = await deriveConfigs(cliConfig.app)\n const id = inlinedId ?? (await buildAppId(workbench))\n const registration = registerDevServer({\n configs,\n host: remote.host,\n id,\n interfaces: deriveInterfaces(cliConfig.app, {isApp}),\n manifest: await extractManifest({configPath, workDir}),\n manifestUpdatedAt: new Date().toISOString(),\n port: remote.port,\n projectId: cliConfig?.api?.projectId,\n type: isApp ? 'coreApp' : 'studio',\n workDir,\n })\n closers.push(async () => registration.release())\n } catch (err) {\n await close()\n throw err\n }\n\n if (workbench.workbenchAvailable) {\n const workbenchUrl = `http://${toDisplayHost(workbench.httpHost)}:${workbench.workbenchPort}`\n output.log(\n `Workbench preview server started at ${styleText(['blue', 'underline'], workbenchUrl)} (serving build on port ${remote.port})`,\n )\n } else {\n const remoteUrl = `http://${toDisplayHost(remote.host)}:${remote.port}`\n output.log(`Serving build at ${styleText(['blue', 'underline'], remoteUrl)}`)\n }\n\n installSignalHandlers()\n\n return {close}\n}\n\n/** The id the build inlined into its bundle, or undefined when absent. */\nasync function readInlinedAppId(outDir: string): Promise<string | undefined> {\n try {\n return (await readFile(path.join(outDir, SANITY_APP_ID_FILE), 'utf8')).trim() || undefined\n } catch {\n return undefined\n }\n}\n"],"names":["readFile","path","styleText","findProjectRoot","buildAppId","SANITY_APP_ID_FILE","deriveInterfaces","resolveWorkbenchApp","createServerLifecycle","toDisplayHost","deriveConfigs","registerDevServer","startWorkbenchDevServer","serveBuiltApplication","startWorkbenchPreview","options","cacheDir","checkForDeprecatedAppId","cliConfig","extractManifest","httpHost","httpPort","isApp","outDir","output","reactStrictMode","workDir","close","closers","installSignalHandlers","workbench","mode","push","remotePort","workbenchAvailable","workbenchPort","remote","catch","err","configPath","Error","inlinedId","readInlinedAppId","configs","app","id","registration","host","interfaces","manifest","manifestUpdatedAt","Date","toISOString","port","projectId","api","type","release","workbenchUrl","log","remoteUrl","join","trim","undefined"],"mappings":"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"}
|
|
@@ -58,17 +58,19 @@ async function resolveApplicationTarget({ appId, type, workbench }) {
|
|
|
58
58
|
type: 'none'
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
|
-
const {
|
|
61
|
+
const { lines, services, views } = summarizeInterfaces(workbench);
|
|
62
62
|
return {
|
|
63
63
|
target: {
|
|
64
|
-
|
|
65
|
-
appHost: application.slug,
|
|
66
|
-
createdAt: null,
|
|
64
|
+
application,
|
|
67
65
|
deletes: 'application',
|
|
68
66
|
id: application.id,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
payload: {
|
|
68
|
+
appId: application.id,
|
|
69
|
+
services,
|
|
70
|
+
type,
|
|
71
|
+
views
|
|
72
|
+
},
|
|
73
|
+
services,
|
|
72
74
|
summary: [
|
|
73
75
|
...lines,
|
|
74
76
|
...workbench.isSingleton === undefined ? [] : [
|
|
@@ -80,7 +82,8 @@ async function resolveApplicationTarget({ appId, type, workbench }) {
|
|
|
80
82
|
url: getApplicationUrl({
|
|
81
83
|
...application,
|
|
82
84
|
type
|
|
83
|
-
})
|
|
85
|
+
}),
|
|
86
|
+
views
|
|
84
87
|
},
|
|
85
88
|
type: 'found'
|
|
86
89
|
};
|
|
@@ -114,30 +117,23 @@ async function resolveConfigTarget({ organizationId, workbench }) {
|
|
|
114
117
|
}
|
|
115
118
|
};
|
|
116
119
|
}
|
|
117
|
-
// At most one snapshot is active (served); the rest are deactivated history.
|
|
118
|
-
const active = configs.find((snapshot)=>snapshot.isActive);
|
|
119
120
|
return {
|
|
120
121
|
installationId,
|
|
121
122
|
resolution: {
|
|
122
123
|
target: {
|
|
123
|
-
|
|
124
|
-
deployedAt: active.createdAt ?? '',
|
|
125
|
-
deployedBy: active.deployedBy ?? ''
|
|
126
|
-
} : null,
|
|
127
|
-
appHost: null,
|
|
128
|
-
configs: configs.map((snapshot)=>({
|
|
129
|
-
createdAt: snapshot.createdAt ?? null,
|
|
130
|
-
deployedBy: snapshot.deployedBy ?? null,
|
|
131
|
-
id: snapshot.id
|
|
132
|
-
})),
|
|
133
|
-
createdAt: configs.at(-1)?.createdAt ?? null,
|
|
124
|
+
configs,
|
|
134
125
|
deletes: 'config',
|
|
135
126
|
id: null,
|
|
136
|
-
|
|
137
|
-
|
|
127
|
+
payload: {
|
|
128
|
+
appId: null,
|
|
129
|
+
...config ? {
|
|
130
|
+
config: summarizeConfig(config)
|
|
131
|
+
} : {},
|
|
132
|
+
type: 'coreApp'
|
|
133
|
+
},
|
|
138
134
|
summary: config ? [
|
|
139
135
|
summarizeConfig(config)
|
|
140
|
-
] :
|
|
136
|
+
] : [],
|
|
141
137
|
title: workbench.slug,
|
|
142
138
|
type: 'coreApp',
|
|
143
139
|
url: getWorkbenchUrl(organizationId)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/undeploy/workbenchUndeployAdapter.ts"],"sourcesContent":["import {\n type UndeployAdapter,\n type UndeployApplicationTarget,\n type UndeployConfigTarget,\n type UndeployTargetResolution,\n} from '@sanity/cli-core/undeploy'\n\nimport {\n deleteApplication,\n getApplication,\n getApplicationUrl,\n getWorkbenchUrl,\n} from '../../services/applications.js'\nimport {deleteConfig, listConfigs} from '../../services/installations.js'\nimport {resolveInstallationId, summarizeConfig} from '../deploy/deployConfig.js'\nimport {type DeployableWorkbenchApp} from '../deploy/getWorkbench.js'\nimport {type
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/undeploy/workbenchUndeployAdapter.ts"],"sourcesContent":["import {\n type UndeployAdapter,\n type UndeployApplicationTarget,\n type UndeployConfigTarget,\n type UndeployTargetResolution,\n} from '@sanity/cli-core/undeploy'\n\nimport {\n deleteApplication,\n getApplication,\n getApplicationUrl,\n getWorkbenchUrl,\n} from '../../services/applications.js'\nimport {type ConfigSnapshot, deleteConfig, listConfigs} from '../../services/installations.js'\nimport {resolveInstallationId, summarizeConfig} from '../deploy/deployConfig.js'\nimport {type DeployableWorkbenchApp} from '../deploy/getWorkbench.js'\nimport {type DeployedInterface, summarizeInterfaces} from '../deploy/summarizeInterfaces.js'\n\n/** The workbench extension of the shared target; serializes into `--json` as-is. */\nexport type WorkbenchUndeployTarget =\n | (UndeployApplicationTarget & {\n services: DeployedInterface[]\n views: DeployedInterface[]\n })\n | (UndeployConfigTarget & {\n configs: ConfigSnapshot[]\n })\n\n/**\n * The undeploy adapter for workbench apps, mirroring what a workbench deploy\n * creates: apps that expose interfaces delete their Brett application (the\n * server soft-deletes its deployments and refuses singletons with active\n * installations); a singleton without interfaces — the media library — deletes\n * its installation's config snapshots instead.\n */\nexport function createWorkbenchUndeployAdapter(options: {\n appId: string | undefined\n organizationId: string | undefined\n type: 'coreApp' | 'studio'\n workbench: DeployableWorkbenchApp\n}): UndeployAdapter<WorkbenchUndeployTarget> {\n const {appId, organizationId, type, workbench} = options\n // Keyed on singleton-ness, not on a locally declared config, so an undeploy\n // still reaches the server's config snapshots after the fields are removed\n // from sanity.cli.ts.\n const configOnly = !!workbench.isSingleton && !workbench.hasInterfaces\n // Workbench-internal, so kept off the reported target; resolveTarget stashes it for the delete.\n let installationId: string | undefined\n\n return {\n resolveTarget: async () => {\n if (!configOnly) return resolveApplicationTarget({appId, type, workbench})\n const resolved = await resolveConfigTarget({organizationId, workbench})\n installationId = resolved.installationId\n return resolved.resolution\n },\n type,\n async undeploy(target) {\n if (target.deletes === 'config') {\n if (!installationId) throw new Error('No installation resolved for the config undeploy')\n for (const snapshot of target.configs) {\n await deleteConfig(installationId, snapshot.id)\n }\n return\n }\n await deleteApplication(target.id)\n },\n }\n}\n\nasync function resolveApplicationTarget({\n appId,\n type,\n workbench,\n}: {\n appId: string | undefined\n type: 'coreApp' | 'studio'\n workbench: DeployableWorkbenchApp\n}): Promise<UndeployTargetResolution<WorkbenchUndeployTarget>> {\n if (!appId) {\n return {\n message: 'No `deployment.appId` configured',\n solution: 'Add `deployment.appId` to sanity.cli.ts',\n type: 'none',\n }\n }\n\n const application = await getApplication(appId)\n if (!application) {\n return {message: 'Application with the given ID does not exist', type: 'none'}\n }\n\n const {lines, services, views} = summarizeInterfaces(workbench)\n return {\n target: {\n application,\n deletes: 'application',\n id: application.id,\n payload: {appId: application.id, services, type, views},\n services,\n summary: [\n ...lines,\n ...(workbench.isSingleton === undefined ? [] : [`Singleton: ${workbench.isSingleton}`]),\n ],\n title: application.title,\n type,\n url: getApplicationUrl({...application, type}),\n views,\n },\n type: 'found',\n }\n}\n\nasync function resolveConfigTarget({\n organizationId,\n workbench,\n}: {\n organizationId: string | undefined\n workbench: DeployableWorkbenchApp\n}): Promise<{\n installationId?: string\n resolution: UndeployTargetResolution<WorkbenchUndeployTarget>\n}> {\n const config = workbench.config\n const appType = config?.appType ?? workbench.applicationType\n if (!appType) throw new Error('The app declares no app type to resolve its installation')\n if (!organizationId) {\n throw new Error(\n 'sanity.cli.ts does not contain an organization identifier (\"app.organizationId\"), which is required to resolve the installation',\n )\n }\n\n const installationId = await resolveInstallationId({appType, organizationId})\n if (!installationId) {\n return {\n resolution: {\n message: `No active \"${appType}\" installation for organization \"${organizationId}\"`,\n type: 'none',\n },\n }\n }\n\n const configs = await listConfigs(installationId)\n if (configs.length === 0) {\n return {\n installationId,\n resolution: {\n message: `No deployed config for the \"${appType}\" installation`,\n type: 'none',\n },\n }\n }\n\n return {\n installationId,\n resolution: {\n target: {\n configs,\n deletes: 'config',\n id: null,\n payload: {\n appId: null,\n ...(config ? {config: summarizeConfig(config)} : {}),\n type: 'coreApp',\n },\n summary: config ? [summarizeConfig(config)] : [],\n title: workbench.slug,\n type: 'coreApp',\n url: getWorkbenchUrl(organizationId),\n },\n type: 'found',\n },\n }\n}\n"],"names":["deleteApplication","getApplication","getApplicationUrl","getWorkbenchUrl","deleteConfig","listConfigs","resolveInstallationId","summarizeConfig","summarizeInterfaces","createWorkbenchUndeployAdapter","options","appId","organizationId","type","workbench","configOnly","isSingleton","hasInterfaces","installationId","resolveTarget","resolveApplicationTarget","resolved","resolveConfigTarget","resolution","undeploy","target","deletes","Error","snapshot","configs","id","message","solution","application","lines","services","views","payload","summary","undefined","title","url","config","appType","applicationType","length","slug"],"mappings":"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"}
|
package/dist/appId.js
CHANGED
|
@@ -3,20 +3,11 @@
|
|
|
3
3
|
* bundle. `sanity start` serves a build without recompiling, so it reads this
|
|
4
4
|
* instead of recomputing — a deploy inlines the API id, not the shape hash.
|
|
5
5
|
*/ export const SANITY_APP_ID_FILE = 'sanity-app-id.txt';
|
|
6
|
-
/**
|
|
7
|
-
* The dev id for a workbench app — the address the server bound. `sanity dev`
|
|
8
|
-
* keys on where the app is served so a running app can't collide with its
|
|
9
|
-
* deployed twin. Sync and dependency-free: it's re-exported from the package's
|
|
10
|
-
* browser-facing entry, so it must not pull in `node:crypto`.
|
|
11
|
-
*/ export function resolveAppId(source) {
|
|
12
|
-
return `${source.host}-${source.port}`;
|
|
13
|
-
}
|
|
14
6
|
/**
|
|
15
7
|
* The `build`/`start` id — a hash of the app's declared shape (its identity, not
|
|
16
8
|
* its code), so the bundle inlined by `sanity build` and the registry entry
|
|
17
|
-
* advertised by `sanity start` resolve to the same id.
|
|
18
|
-
*
|
|
19
|
-
* home. `sanity deploy` resolves its own id from the applications API.
|
|
9
|
+
* advertised by `sanity start` resolve to the same id. `sanity deploy` resolves
|
|
10
|
+
* its own id from the applications API.
|
|
20
11
|
*/ export async function buildAppId(app) {
|
|
21
12
|
const canonical = (interfaces)=>(interfaces ?? []).map((i)=>[
|
|
22
13
|
i.type,
|
package/dist/appId.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/appId.ts"],"sourcesContent":["import {type ResolvedWorkbenchApp} from './resolveWorkbenchApp.js'\n\n/**\n * File the build writes into its output, carrying the id compiled into the\n * bundle. `sanity start` serves a build without recompiling, so it reads this\n * instead of recomputing — a deploy inlines the API id, not the shape hash.\n */\nexport const SANITY_APP_ID_FILE = 'sanity-app-id.txt'\n\n/**\n * The
|
|
1
|
+
{"version":3,"sources":["../src/appId.ts"],"sourcesContent":["import {type ResolvedWorkbenchApp} from './resolveWorkbenchApp.js'\n\n/**\n * File the build writes into its output, carrying the id compiled into the\n * bundle. `sanity start` serves a build without recompiling, so it reads this\n * instead of recomputing — a deploy inlines the API id, not the shape hash.\n */\nexport const SANITY_APP_ID_FILE = 'sanity-app-id.txt'\n\n/**\n * The `build`/`start` id — a hash of the app's declared shape (its identity, not\n * its code), so the bundle inlined by `sanity build` and the registry entry\n * advertised by `sanity start` resolve to the same id. `sanity deploy` resolves\n * its own id from the applications API.\n */\nexport async function buildAppId(app: ResolvedWorkbenchApp): Promise<string> {\n const canonical = (\n interfaces: ReadonlyArray<{name: string; src: string; type: string}> | undefined,\n ): Array<[string, string, string]> =>\n (interfaces ?? []).map((i): [string, string, string] => [i.type, i.name, i.src]).toSorted()\n const shape = JSON.stringify({\n config: app.config ?? null,\n entry: app.entry ?? null,\n organizationId: app.organizationId,\n services: canonical(app.services),\n slug: app.slug,\n views: canonical(app.views),\n })\n // eslint-disable-next-line n/no-unsupported-features/node-builtins -- the Web Crypto global is available on our Node target and in the browser\n const digest = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(shape))\n return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, '0')).join('')\n}\n"],"names":["SANITY_APP_ID_FILE","buildAppId","app","canonical","interfaces","map","i","type","name","src","toSorted","shape","JSON","stringify","config","entry","organizationId","services","slug","views","digest","globalThis","crypto","subtle","TextEncoder","encode","Array","from","Uint8Array","byte","toString","padStart","join"],"mappings":"AAEA;;;;CAIC,GACD,OAAO,MAAMA,qBAAqB,oBAAmB;AAErD;;;;;CAKC,GACD,OAAO,eAAeC,WAAWC,GAAyB;IACxD,MAAMC,YAAY,CAChBC,aAEA,AAACA,CAAAA,cAAc,EAAE,AAAD,EAAGC,GAAG,CAAC,CAACC,IAAgC;gBAACA,EAAEC,IAAI;gBAAED,EAAEE,IAAI;gBAAEF,EAAEG,GAAG;aAAC,EAAEC,QAAQ;IAC3F,MAAMC,QAAQC,KAAKC,SAAS,CAAC;QAC3BC,QAAQZ,IAAIY,MAAM,IAAI;QACtBC,OAAOb,IAAIa,KAAK,IAAI;QACpBC,gBAAgBd,IAAIc,cAAc;QAClCC,UAAUd,UAAUD,IAAIe,QAAQ;QAChCC,MAAMhB,IAAIgB,IAAI;QACdC,OAAOhB,UAAUD,IAAIiB,KAAK;IAC5B;IACA,+IAA+I;IAC/I,MAAMC,SAAS,MAAMC,WAAWC,MAAM,CAACC,MAAM,CAACH,MAAM,CAAC,WAAW,IAAII,cAAcC,MAAM,CAACd;IACzF,OAAOe,MAAMC,IAAI,CAAC,IAAIC,WAAWR,SAAS,CAACS,OAASA,KAAKC,QAAQ,CAAC,IAAIC,QAAQ,CAAC,GAAG,MAAMC,IAAI,CAAC;AAC/F"}
|
|
@@ -79,10 +79,11 @@ export async function updateApplication(applicationId, update) {
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
/** Deploy a new active version to an existing application. */ export async function createDeployment(options) {
|
|
82
|
-
const { applicationId, interfaces, isAutoUpdating, tarball, version, workspaces } = options;
|
|
82
|
+
const { access, applicationId, interfaces, isAutoUpdating, tarball, version, workspaces } = options;
|
|
83
83
|
const formData = new FormData();
|
|
84
84
|
formData.append('isAutoUpdating', isAutoUpdating.toString());
|
|
85
85
|
appendDeploymentParts(formData, {
|
|
86
|
+
access,
|
|
86
87
|
interfaces,
|
|
87
88
|
tarball,
|
|
88
89
|
version,
|
|
@@ -101,11 +102,13 @@ export async function updateApplication(applicationId, update) {
|
|
|
101
102
|
if (err?.statusCode !== 404) throw err;
|
|
102
103
|
}
|
|
103
104
|
}
|
|
104
|
-
function appendDeploymentParts(formData, { interfaces, tarball, version, workspaces }) {
|
|
105
|
+
function appendDeploymentParts(formData, { access, interfaces, tarball, version, workspaces }) {
|
|
105
106
|
formData.append('version', version);
|
|
106
107
|
appendJson(formData, 'interfaces', interfaces);
|
|
107
108
|
// Studio-only — the server rejects a workspaces part on non-studio types.
|
|
108
109
|
if (workspaces?.length) appendJson(formData, 'workspaces', workspaces);
|
|
110
|
+
// Per-deployment; forbidden for singletons, so callers omit it there.
|
|
111
|
+
if (access?.length) appendJson(formData, 'access', access);
|
|
109
112
|
formData.append('tarball', tarball, {
|
|
110
113
|
contentType: 'application/gzip',
|
|
111
114
|
filename: 'app.tar.gz'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/applications.ts"],"sourcesContent":["import {PassThrough} from 'node:stream'\nimport {type Gzip} from 'node:zlib'\n\nimport {type AppVisibility, getGlobalCliClient} from '@sanity/cli-core'\nimport {isStaging} from '@sanity/cli-core/util'\nimport FormData from 'form-data'\n\nimport {type AppInterfaceMetadata, type TileInterfaceMetadata} from '../contract.js'\nimport {APP_WORKBENCH_API_VERSION} from './apiVersion.js'\n\nexport type ApplicationType = 'coreApp' | 'studio'\n\nexport interface Application {\n id: string\n organizationId: string\n slug: string | null\n title: string\n type: ApplicationType\n}\n\ninterface BrettInterfaceBase {\n moduleId: string\n name: string\n title: string\n version: string\n}\n\n/**\n * An interface as Brett stores it, discriminated on `type`. `moduleId` is\n * remote-relative — the host prepends the app's id. Brett assigns the id.\n * @internal\n */\nexport type BrettInterface =\n | (BrettInterfaceBase & {metadata: AppInterfaceMetadata | null; type: 'app'})\n | (BrettInterfaceBase & {metadata: null; type: 'asset_source'})\n | (BrettInterfaceBase & {metadata: null; type: 'panel'})\n | (BrettInterfaceBase & {metadata: null; type: 'worker'})\n | (BrettInterfaceBase & {metadata: TileInterfaceMetadata; type: 'tile'})\n\n/** A studio workspace as Brett stores it. */\nexport interface BrettWorkspace {\n dataset: string\n projectId: string\n /** Lexicon schema descriptor id; Brett requires one per workspace. */\n schemaDescriptorId: string\n\n basePath?: string\n icon?: string\n name?: string\n subtitle?: string\n title?: string\n}\n\nexport function getWorkbenchUrl(organizationId: string): string {\n return `https://${organizationId}.${isStaging() ? 'run.sanity.work' : 'sanity.run'}`\n}\n\n/** Where a deployed application is served on its organization's workbench. */\nexport function getApplicationUrl(\n application: Pick<Application, 'id' | 'organizationId' | 'type'>,\n): string {\n const segment = application.type === 'studio' ? 'studio' : 'application'\n return `${getWorkbenchUrl(application.organizationId)}/${segment}/${application.id}`\n}\n\nasync function getClient() {\n return getGlobalCliClient({apiVersion: APP_WORKBENCH_API_VERSION, requireUser: true})\n}\n\nexport async function getApplication(applicationId: string): Promise<Application | null> {\n const client = await getClient()\n try {\n return await client.request({uri: `/applications/${applicationId}`})\n } catch (err) {\n if ((err as {statusCode?: number})?.statusCode === 404) return null\n throw err\n }\n}\n\n/** Every application in an organization, in one page (`limit=none`). */\nexport async function listApplications(organizationId: string): Promise<Application[]> {\n const client = await getClient()\n const {data}: {data: Application[]} = await client.request({\n query: {limit: 'none', organizationId},\n uri: '/applications',\n })\n return data\n}\n\n/**\n * Create an application record (no deployment), so the CLI can build with the\n * returned id, then ship it via {@link createDeployment}.\n */\nexport async function createApplication(options: {\n isSingleton?: boolean\n organizationId: string\n projectId?: string\n slug: string\n title: string\n type: ApplicationType\n visibility?: AppVisibility\n}): Promise<Application> {\n const {isSingleton, organizationId, projectId, slug, title, type, visibility} = options\n const client = await getClient()\n return client.request({\n body: {\n organizationId,\n slug,\n title,\n type,\n ...(isSingleton === undefined ? {} : {isSingleton}),\n ...(visibility ? {visibility} : {}),\n // Studio config is set once, at create — it's immutable on redeploy.\n ...(projectId ? {config: {studio: {projectId}}} : {}),\n },\n method: 'POST',\n uri: `/applications`,\n })\n}\n\n/** Mutable application fields the deploy flow patches after create. */\nexport interface ApplicationUpdate {\n icon?: string | null\n title?: string\n visibility?: AppVisibility\n}\n\n// Patch an application's mutable fields.\nexport async function updateApplication(\n applicationId: string,\n update: ApplicationUpdate,\n): Promise<void> {\n const client = await getClient()\n await client.request({body: update, method: 'PATCH', uri: `/applications/${applicationId}`})\n}\n\n/** Deploy a new active version to an existing application. */\nexport async function createDeployment(options: {\n applicationId: string\n interfaces: readonly BrettInterface[]\n isAutoUpdating: boolean\n tarball: Gzip\n version: string\n workspaces?: readonly BrettWorkspace[]\n}): Promise<{id: string}> {\n const {applicationId, interfaces, isAutoUpdating, tarball, version, workspaces} = options\n const formData = new FormData()\n formData.append('isAutoUpdating', isAutoUpdating.toString())\n appendDeploymentParts(formData, {interfaces, tarball, version, workspaces})\n return request(`/applications/${applicationId}/deployments`, formData)\n}\n\n/** Soft-deletes the application and all its deployments; already deleted counts as done. */\nexport async function deleteApplication(applicationId: string): Promise<void> {\n const client = await getClient()\n try {\n await client.request({method: 'DELETE', uri: `/applications/${applicationId}`})\n } catch (err) {\n if ((err as {statusCode?: number})?.statusCode !== 404) throw err\n }\n}\n\nfunction appendDeploymentParts(\n formData: FormData,\n {\n interfaces,\n tarball,\n version,\n workspaces,\n }: {\n interfaces: readonly BrettInterface[]\n tarball: Gzip\n version: string\n workspaces?: readonly BrettWorkspace[]\n },\n): void {\n formData.append('version', version)\n appendJson(formData, 'interfaces', interfaces)\n // Studio-only — the server rejects a workspaces part on non-studio types.\n if (workspaces?.length) appendJson(formData, 'workspaces', workspaces)\n formData.append('tarball', tarball, {contentType: 'application/gzip', filename: 'app.tar.gz'})\n}\n\n/** Structured parts must arrive as JSON so the server parses them. */\nfunction appendJson(formData: FormData, name: string, value: unknown): void {\n formData.append(name, JSON.stringify(value), {contentType: 'application/json'})\n}\n\nasync function request<T>(uri: string, formData: FormData): Promise<T> {\n const client = await getClient()\n return client.request({\n body: formData.pipe(new PassThrough()),\n headers: formData.getHeaders(),\n method: 'POST',\n uri,\n })\n}\n"],"names":["PassThrough","getGlobalCliClient","isStaging","FormData","APP_WORKBENCH_API_VERSION","getWorkbenchUrl","organizationId","getApplicationUrl","application","segment","type","id","getClient","apiVersion","requireUser","getApplication","applicationId","client","request","uri","err","statusCode","listApplications","data","query","limit","createApplication","options","isSingleton","projectId","slug","title","visibility","body","undefined","config","studio","method","updateApplication","update","createDeployment","interfaces","isAutoUpdating","tarball","version","workspaces","formData","append","toString","appendDeploymentParts","deleteApplication","appendJson","length","contentType","filename","name","value","JSON","stringify","pipe","headers","getHeaders"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/services/applications.ts"],"sourcesContent":["import {PassThrough} from 'node:stream'\nimport {type Gzip} from 'node:zlib'\n\nimport {type AppVisibility, getGlobalCliClient} from '@sanity/cli-core'\nimport {isStaging} from '@sanity/cli-core/util'\nimport FormData from 'form-data'\n\nimport {type AppInterfaceMetadata, type TileInterfaceMetadata} from '../contract.js'\nimport {APP_WORKBENCH_API_VERSION} from './apiVersion.js'\n\nexport type ApplicationType = 'coreApp' | 'studio'\n\nexport interface Application {\n id: string\n organizationId: string\n slug: string | null\n title: string\n type: ApplicationType\n}\n\ninterface BrettInterfaceBase {\n moduleId: string\n name: string\n title: string\n version: string\n}\n\n/**\n * An interface as Brett stores it, discriminated on `type`. `moduleId` is\n * remote-relative — the host prepends the app's id. Brett assigns the id.\n * @internal\n */\nexport type BrettInterface =\n | (BrettInterfaceBase & {metadata: AppInterfaceMetadata | null; type: 'app'})\n | (BrettInterfaceBase & {metadata: null; type: 'asset_source'})\n | (BrettInterfaceBase & {metadata: null; type: 'panel'})\n | (BrettInterfaceBase & {metadata: null; type: 'worker'})\n | (BrettInterfaceBase & {metadata: TileInterfaceMetadata; type: 'tile'})\n\n/**\n * A resource a deployment may interact with, as Brett stores it. Per-deployment\n * and forbidden for singletons (the server 400s).\n */\nexport interface BrettAccess {\n resourceId: string\n resourceType: 'canvas' | 'dashboard' | 'dataset' | 'media-library'\n}\n\n/** A studio workspace as Brett stores it. */\nexport interface BrettWorkspace {\n dataset: string\n projectId: string\n /** Lexicon schema descriptor id; Brett requires one per workspace. */\n schemaDescriptorId: string\n\n basePath?: string\n icon?: string\n name?: string\n subtitle?: string\n title?: string\n}\n\nexport function getWorkbenchUrl(organizationId: string): string {\n return `https://${organizationId}.${isStaging() ? 'run.sanity.work' : 'sanity.run'}`\n}\n\n/** Where a deployed application is served on its organization's workbench. */\nexport function getApplicationUrl(\n application: Pick<Application, 'id' | 'organizationId' | 'type'>,\n): string {\n const segment = application.type === 'studio' ? 'studio' : 'application'\n return `${getWorkbenchUrl(application.organizationId)}/${segment}/${application.id}`\n}\n\nasync function getClient() {\n return getGlobalCliClient({apiVersion: APP_WORKBENCH_API_VERSION, requireUser: true})\n}\n\nexport async function getApplication(applicationId: string): Promise<Application | null> {\n const client = await getClient()\n try {\n return await client.request({uri: `/applications/${applicationId}`})\n } catch (err) {\n if ((err as {statusCode?: number})?.statusCode === 404) return null\n throw err\n }\n}\n\n/** Every application in an organization, in one page (`limit=none`). */\nexport async function listApplications(organizationId: string): Promise<Application[]> {\n const client = await getClient()\n const {data}: {data: Application[]} = await client.request({\n query: {limit: 'none', organizationId},\n uri: '/applications',\n })\n return data\n}\n\n/**\n * Create an application record (no deployment), so the CLI can build with the\n * returned id, then ship it via {@link createDeployment}.\n */\nexport async function createApplication(options: {\n isSingleton?: boolean\n organizationId: string\n projectId?: string\n slug: string\n title: string\n type: ApplicationType\n visibility?: AppVisibility\n}): Promise<Application> {\n const {isSingleton, organizationId, projectId, slug, title, type, visibility} = options\n const client = await getClient()\n return client.request({\n body: {\n organizationId,\n slug,\n title,\n type,\n ...(isSingleton === undefined ? {} : {isSingleton}),\n ...(visibility ? {visibility} : {}),\n // Studio config is set once, at create — it's immutable on redeploy.\n ...(projectId ? {config: {studio: {projectId}}} : {}),\n },\n method: 'POST',\n uri: `/applications`,\n })\n}\n\n/** Mutable application fields the deploy flow patches after create. */\nexport interface ApplicationUpdate {\n icon?: string | null\n title?: string\n visibility?: AppVisibility\n}\n\n// Patch an application's mutable fields.\nexport async function updateApplication(\n applicationId: string,\n update: ApplicationUpdate,\n): Promise<void> {\n const client = await getClient()\n await client.request({body: update, method: 'PATCH', uri: `/applications/${applicationId}`})\n}\n\n/** Deploy a new active version to an existing application. */\nexport async function createDeployment(options: {\n access?: readonly BrettAccess[]\n applicationId: string\n interfaces: readonly BrettInterface[]\n isAutoUpdating: boolean\n tarball: Gzip\n version: string\n workspaces?: readonly BrettWorkspace[]\n}): Promise<{id: string}> {\n const {access, applicationId, interfaces, isAutoUpdating, tarball, version, workspaces} = options\n const formData = new FormData()\n formData.append('isAutoUpdating', isAutoUpdating.toString())\n appendDeploymentParts(formData, {access, interfaces, tarball, version, workspaces})\n return request(`/applications/${applicationId}/deployments`, formData)\n}\n\n/** Soft-deletes the application and all its deployments; already deleted counts as done. */\nexport async function deleteApplication(applicationId: string): Promise<void> {\n const client = await getClient()\n try {\n await client.request({method: 'DELETE', uri: `/applications/${applicationId}`})\n } catch (err) {\n if ((err as {statusCode?: number})?.statusCode !== 404) throw err\n }\n}\n\nfunction appendDeploymentParts(\n formData: FormData,\n {\n access,\n interfaces,\n tarball,\n version,\n workspaces,\n }: {\n access?: readonly BrettAccess[]\n interfaces: readonly BrettInterface[]\n tarball: Gzip\n version: string\n workspaces?: readonly BrettWorkspace[]\n },\n): void {\n formData.append('version', version)\n appendJson(formData, 'interfaces', interfaces)\n // Studio-only — the server rejects a workspaces part on non-studio types.\n if (workspaces?.length) appendJson(formData, 'workspaces', workspaces)\n // Per-deployment; forbidden for singletons, so callers omit it there.\n if (access?.length) appendJson(formData, 'access', access)\n formData.append('tarball', tarball, {contentType: 'application/gzip', filename: 'app.tar.gz'})\n}\n\n/** Structured parts must arrive as JSON so the server parses them. */\nfunction appendJson(formData: FormData, name: string, value: unknown): void {\n formData.append(name, JSON.stringify(value), {contentType: 'application/json'})\n}\n\nasync function request<T>(uri: string, formData: FormData): Promise<T> {\n const client = await getClient()\n return client.request({\n body: formData.pipe(new PassThrough()),\n headers: formData.getHeaders(),\n method: 'POST',\n uri,\n })\n}\n"],"names":["PassThrough","getGlobalCliClient","isStaging","FormData","APP_WORKBENCH_API_VERSION","getWorkbenchUrl","organizationId","getApplicationUrl","application","segment","type","id","getClient","apiVersion","requireUser","getApplication","applicationId","client","request","uri","err","statusCode","listApplications","data","query","limit","createApplication","options","isSingleton","projectId","slug","title","visibility","body","undefined","config","studio","method","updateApplication","update","createDeployment","access","interfaces","isAutoUpdating","tarball","version","workspaces","formData","append","toString","appendDeploymentParts","deleteApplication","appendJson","length","contentType","filename","name","value","JSON","stringify","pipe","headers","getHeaders"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/workbench-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Internal implementation detail of the Sanity CLI's unstable workbench support. Not intended for direct use.",
|
|
5
5
|
"homepage": "https://github.com/sanity-io/cli",
|
|
6
6
|
"bugs": "https://github.com/sanity-io/cli/issues",
|
|
@@ -53,14 +53,14 @@
|
|
|
53
53
|
"access": "public"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@module-federation/vite": "1.20.
|
|
56
|
+
"@module-federation/vite": "1.20.7",
|
|
57
57
|
"@sanity/types": "^6.7.0",
|
|
58
58
|
"@vitejs/plugin-react": "^6.0.5",
|
|
59
59
|
"form-data": "^4.0.5",
|
|
60
60
|
"tar-fs": "^3.1.2",
|
|
61
61
|
"vite": "^8.2.0",
|
|
62
62
|
"zod": "^4.4.3",
|
|
63
|
-
"@sanity/cli-core": "^
|
|
63
|
+
"@sanity/cli-core": "^3.0.0"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@eslint/compat": "^2.1.0",
|