@sanity/cli 7.7.1 → 7.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -2
- package/dist/actions/auth/ensureAuthenticated.js +1 -1
- package/dist/actions/auth/ensureAuthenticated.js.map +1 -1
- package/dist/actions/auth/login/validateToken.js +1 -1
- package/dist/actions/auth/login/validateToken.js.map +1 -1
- package/dist/actions/build/buildApp.js +2 -3
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStudio.js +1 -2
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/deploy/createUserApplication.js +8 -8
- package/dist/actions/deploy/createUserApplication.js.map +1 -1
- package/dist/actions/deploy/deployApp.js +128 -26
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployChecks.js +97 -72
- package/dist/actions/deploy/deployChecks.js.map +1 -1
- package/dist/actions/deploy/deployRunner.js +8 -8
- package/dist/actions/deploy/deployRunner.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +129 -23
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/deploymentPlan.js +29 -30
- package/dist/actions/deploy/deploymentPlan.js.map +1 -1
- package/dist/actions/deploy/findUserApplication.js +39 -14
- package/dist/actions/deploy/findUserApplication.js.map +1 -1
- package/dist/actions/deploy/resolveDeployTarget.js +44 -0
- package/dist/actions/deploy/resolveDeployTarget.js.map +1 -1
- package/dist/actions/deploy/urlUtils.js +0 -4
- package/dist/actions/deploy/urlUtils.js.map +1 -1
- package/dist/actions/dev/servers/getDevServerConfig.js +1 -1
- package/dist/actions/dev/servers/getDevServerConfig.js.map +1 -1
- package/dist/actions/dev/servers/startStudioDevServer.js +1 -2
- package/dist/actions/dev/servers/startStudioDevServer.js.map +1 -1
- package/dist/actions/documents/types.js.map +1 -1
- package/dist/actions/documents/validate.js +2 -1
- package/dist/actions/documents/validate.js.map +1 -1
- package/dist/actions/graphql/SchemaError.js.map +1 -1
- package/dist/actions/graphql/extractGraphQLAPIs.js +3 -1
- package/dist/actions/graphql/extractGraphQLAPIs.js.map +1 -1
- package/dist/actions/manifest/extractCoreAppManifest.js +1 -1
- package/dist/actions/manifest/extractCoreAppManifest.js.map +1 -1
- package/dist/actions/organizations/getOrganization.js +1 -1
- package/dist/actions/organizations/getOrganization.js.map +1 -1
- package/dist/actions/schema/validateAction.js +1 -1
- package/dist/actions/schema/validateAction.js.map +1 -1
- package/dist/actions/skills/setupSkills.js +1 -1
- package/dist/actions/skills/setupSkills.js.map +1 -1
- package/dist/actions/undeploy/adapters.js +101 -0
- package/dist/actions/undeploy/adapters.js.map +1 -0
- package/dist/actions/undeploy/runUndeploy.js +179 -0
- package/dist/actions/undeploy/runUndeploy.js.map +1 -0
- package/dist/actions/undeploy/undeployPlan.js +123 -0
- package/dist/actions/undeploy/undeployPlan.js.map +1 -0
- package/dist/commands/datasets/copy.js +2 -1
- package/dist/commands/datasets/copy.js.map +1 -1
- package/dist/commands/documents/validate.js +18 -17
- package/dist/commands/documents/validate.js.map +1 -1
- package/dist/commands/mcp/configure.js +1 -1
- package/dist/commands/mcp/configure.js.map +1 -1
- package/dist/commands/projects/create.js +18 -13
- package/dist/commands/projects/create.js.map +1 -1
- package/dist/commands/projects/list.js +2 -1
- package/dist/commands/projects/list.js.map +1 -1
- package/dist/commands/schemas/validate.js +3 -2
- package/dist/commands/schemas/validate.js.map +1 -1
- package/dist/commands/skills/install.js +1 -1
- package/dist/commands/skills/install.js.map +1 -1
- package/dist/commands/tokens/list.js +1 -1
- package/dist/commands/tokens/list.js.map +1 -1
- package/dist/commands/undeploy.js +47 -73
- package/dist/commands/undeploy.js.map +1 -1
- package/dist/server/devServer.js.map +1 -1
- package/dist/util/checks.js +83 -0
- package/dist/util/checks.js.map +1 -0
- package/dist/util/toStderrOutput.js +13 -0
- package/dist/util/toStderrOutput.js.map +1 -0
- package/oclif.manifest.json +28 -1
- package/package.json +7 -8
- package/dist/actions/undeploy/getStudioOrAppUserApplication.js +0 -36
- package/dist/actions/undeploy/getStudioOrAppUserApplication.js.map +0 -1
- package/dist/util/compareDependencyVersions.js +0 -110
- package/dist/util/compareDependencyVersions.js.map +0 -1
- package/dist/util/getErrorMessage.js +0 -28
- package/dist/util/getErrorMessage.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/tokens/list.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {Table} from 'console-table-printer'\n\nimport {type Token} from '../../actions/tokens/types.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {getTokens} from '../../services/tokens.js'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/tokens/list.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {Table} from 'console-table-printer'\n\nimport {type Token} from '../../actions/tokens/types.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {getTokens} from '../../services/tokens.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst listTokenDebug = subdebug('tokens:list')\n\nexport class TokensListCommand extends SanityCommand<typeof TokensListCommand> {\n static override description = 'List API tokens for the project'\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List tokens for the project',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --json',\n description: 'List tokens in JSON format',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --project-id abc123',\n description: 'List tokens for a specific project',\n },\n ]\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to list tokens for',\n semantics: 'override',\n }),\n json: Flags.boolean({\n default: false,\n description: 'Output tokens in JSON format',\n }),\n }\n\n static override hiddenAliases: string[] = ['token:list']\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(TokensListCommand)\n const {json} = flags\n const outputJson = json ?? false\n\n // Ensure we have project context\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [{grant: 'read', permission: 'sanity.project.tokens'}],\n }),\n })\n\n let tokens: Token[]\n try {\n tokens = await getTokens(projectId)\n } catch (error) {\n const message = getErrorMessage(error)\n listTokenDebug(`Error fetching tokens for project ${projectId}`, error)\n this.error(`Token list retrieval failed:\\n${message}`, {exit: 1})\n }\n\n if (outputJson) {\n this.log(JSON.stringify(tokens, null, 2))\n return\n }\n\n if (tokens.length === 0) {\n this.log('No API tokens found for this project.')\n return\n }\n\n const table = new Table({\n columns: [\n {alignment: 'left', maxLen: 40, name: 'label', title: 'Label'},\n {alignment: 'left', maxLen: 20, name: 'id', title: 'Token ID'},\n {alignment: 'left', maxLen: 30, name: 'roles', title: 'Roles'},\n ],\n title: `Found ${tokens.length} API tokens`,\n })\n\n for (const token of tokens) {\n const roles = token.roles?.map((role) => role.title).join(', ') || 'No roles'\n const truncatedLabel =\n token.label.length > 37 ? `${token.label.slice(0, 37)}...` : token.label\n const truncatedRoles = roles.length > 27 ? `${roles.slice(0, 27)}...` : roles\n\n table.addRow({\n id: token.id,\n label: truncatedLabel,\n roles: truncatedRoles,\n })\n }\n\n table.printTable()\n }\n}\n"],"names":["Flags","SanityCommand","subdebug","getErrorMessage","Table","promptForProject","getTokens","getProjectIdFlag","listTokenDebug","TokensListCommand","description","examples","command","flags","semantics","json","boolean","default","hiddenAliases","run","parse","outputJson","projectId","getProjectId","fallback","requiredPermissions","grant","permission","tokens","error","message","exit","log","JSON","stringify","length","table","columns","alignment","maxLen","name","title","token","roles","map","role","join","truncatedLabel","label","slice","truncatedRoles","addRow","id","printTable"],"mappings":"AAAA,SAAQA,KAAK,QAAO,cAAa;AACjC,SAAQC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACxD,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,KAAK,QAAO,wBAAuB;AAG3C,SAAQC,gBAAgB,QAAO,oCAAmC;AAClE,SAAQC,SAAS,QAAO,2BAA0B;AAClD,SAAQC,gBAAgB,QAAO,4BAA2B;AAE1D,MAAMC,iBAAiBN,SAAS;AAEhC,OAAO,MAAMO,0BAA0BR;IACrC,OAAgBS,cAAc,kCAAiC;IAC/D,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IACD,OAAgBG,QAAQ;QACtB,GAAGN,iBAAiB;YAClBG,aAAa;YACbI,WAAW;QACb,EAAE;QACFC,MAAMf,MAAMgB,OAAO,CAAC;YAClBC,SAAS;YACTP,aAAa;QACf;IACF,EAAC;IAED,OAAgBQ,gBAA0B;QAAC;KAAa,CAAA;IAExD,MAAaC,MAAqB;QAChC,MAAM,EAACN,KAAK,EAAC,GAAG,MAAM,IAAI,CAACO,KAAK,CAACX;QACjC,MAAM,EAACM,IAAI,EAAC,GAAGF;QACf,MAAMQ,aAAaN,QAAQ;QAE3B,iCAAiC;QACjC,MAAMO,YAAY,MAAM,IAAI,CAACC,YAAY,CAAC;YACxCC,UAAU,IACRnB,iBAAiB;oBACfoB,qBAAqB;wBAAC;4BAACC,OAAO;4BAAQC,YAAY;wBAAuB;qBAAE;gBAC7E;QACJ;QAEA,IAAIC;QACJ,IAAI;YACFA,SAAS,MAAMtB,UAAUgB;QAC3B,EAAE,OAAOO,OAAO;YACd,MAAMC,UAAU3B,gBAAgB0B;YAChCrB,eAAe,CAAC,kCAAkC,EAAEc,WAAW,EAAEO;YACjE,IAAI,CAACA,KAAK,CAAC,CAAC,8BAA8B,EAAEC,SAAS,EAAE;gBAACC,MAAM;YAAC;QACjE;QAEA,IAAIV,YAAY;YACd,IAAI,CAACW,GAAG,CAACC,KAAKC,SAAS,CAACN,QAAQ,MAAM;YACtC;QACF;QAEA,IAAIA,OAAOO,MAAM,KAAK,GAAG;YACvB,IAAI,CAACH,GAAG,CAAC;YACT;QACF;QAEA,MAAMI,QAAQ,IAAIhC,MAAM;YACtBiC,SAAS;gBACP;oBAACC,WAAW;oBAAQC,QAAQ;oBAAIC,MAAM;oBAASC,OAAO;gBAAO;gBAC7D;oBAACH,WAAW;oBAAQC,QAAQ;oBAAIC,MAAM;oBAAMC,OAAO;gBAAU;gBAC7D;oBAACH,WAAW;oBAAQC,QAAQ;oBAAIC,MAAM;oBAASC,OAAO;gBAAO;aAC9D;YACDA,OAAO,CAAC,MAAM,EAAEb,OAAOO,MAAM,CAAC,WAAW,CAAC;QAC5C;QAEA,KAAK,MAAMO,SAASd,OAAQ;YAC1B,MAAMe,QAAQD,MAAMC,KAAK,EAAEC,IAAI,CAACC,OAASA,KAAKJ,KAAK,EAAEK,KAAK,SAAS;YACnE,MAAMC,iBACJL,MAAMM,KAAK,CAACb,MAAM,GAAG,KAAK,GAAGO,MAAMM,KAAK,CAACC,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC,GAAGP,MAAMM,KAAK;YAC1E,MAAME,iBAAiBP,MAAMR,MAAM,GAAG,KAAK,GAAGQ,MAAMM,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC,GAAGN;YAExEP,MAAMe,MAAM,CAAC;gBACXC,IAAIV,MAAMU,EAAE;gBACZJ,OAAOD;gBACPJ,OAAOO;YACT;QACF;QAEAd,MAAMiB,UAAU;IAClB;AACF"}
|
|
@@ -1,13 +1,37 @@
|
|
|
1
|
-
import { styleText } from 'node:util';
|
|
2
1
|
import { Flags } from '@oclif/core';
|
|
3
2
|
import { SanityCommand } from '@sanity/cli-core';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { getWorkbench } from '@sanity/workbench-cli/deploy';
|
|
4
|
+
import { createWorkbenchUndeployAdapter } from '@sanity/workbench-cli/undeploy';
|
|
5
|
+
import { createAppUndeployAdapter, createStudioUndeployAdapter } from '../actions/undeploy/adapters.js';
|
|
6
|
+
import { runUndeploy } from '../actions/undeploy/runUndeploy.js';
|
|
7
|
+
import { getAppId } from '../util/appId.js';
|
|
7
8
|
import { determineIsApp } from '../util/determineIsApp.js';
|
|
8
9
|
export class UndeployCommand extends SanityCommand {
|
|
9
10
|
static description = 'Removes the deployed Sanity Studio/App from Sanity hosting';
|
|
11
|
+
static examples = [
|
|
12
|
+
{
|
|
13
|
+
command: '<%= config.bin %> <%= command.id %>',
|
|
14
|
+
description: 'Undeploy the studio or application after confirming'
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
command: '<%= config.bin %> <%= command.id %> --dry-run',
|
|
18
|
+
description: 'Report what would be undeployed without deleting anything'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
command: '<%= config.bin %> <%= command.id %> --json --yes',
|
|
22
|
+
description: 'Undeploy without prompting and report the result as JSON'
|
|
23
|
+
}
|
|
24
|
+
];
|
|
10
25
|
static flags = {
|
|
26
|
+
'dry-run': Flags.boolean({
|
|
27
|
+
default: false,
|
|
28
|
+
description: 'Report what would be undeployed without deleting anything'
|
|
29
|
+
}),
|
|
30
|
+
json: Flags.boolean({
|
|
31
|
+
char: 'j',
|
|
32
|
+
default: false,
|
|
33
|
+
description: 'Output the result as JSON'
|
|
34
|
+
}),
|
|
11
35
|
yes: Flags.boolean({
|
|
12
36
|
char: 'y',
|
|
13
37
|
default: false,
|
|
@@ -17,76 +41,26 @@ export class UndeployCommand extends SanityCommand {
|
|
|
17
41
|
async run() {
|
|
18
42
|
const { flags } = await this.parse(UndeployCommand);
|
|
19
43
|
const cliConfig = await this.getCliConfig();
|
|
20
|
-
const output = this.output;
|
|
21
44
|
const isApp = determineIsApp(cliConfig);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const url = `https://${styleText('yellow', userApplication.appHost)}.sanity.studio`;
|
|
42
|
-
if (!flags.yes) {
|
|
43
|
-
let message = `This will undeploy ${url} and make it unavailable for your users.\nThe hostname will be available for anyone to claim.\nAre you ${styleText('red', 'sure')} you want to undeploy?`;
|
|
44
|
-
if (isApp) {
|
|
45
|
-
message = `This will undeploy the following application:
|
|
46
|
-
|
|
47
|
-
Title: ${styleText('yellow', userApplication.title || '(untitled application)')}
|
|
48
|
-
ID: ${styleText('yellow', userApplication.id)}
|
|
49
|
-
|
|
50
|
-
The application will no longer be available for any of your users if you proceed.
|
|
51
|
-
|
|
52
|
-
Are you ${styleText('red', 'sure')} you want to undeploy?`;
|
|
53
|
-
}
|
|
54
|
-
const shouldUndeploy = await confirm({
|
|
55
|
-
default: false,
|
|
56
|
-
message
|
|
57
|
-
});
|
|
58
|
-
if (!shouldUndeploy) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
spin = spinner(`Undeploying ${isApp ? 'application' : 'studio'}`).start();
|
|
63
|
-
await deleteUserApplication({
|
|
64
|
-
applicationId: userApplication.id,
|
|
65
|
-
appType: isApp ? 'coreApp' : 'studio'
|
|
66
|
-
});
|
|
67
|
-
spin.succeed();
|
|
68
|
-
if (isApp) {
|
|
69
|
-
this.log(`\n${styleText('bold', '⏱️ Application undeploy scheduled.')} It might be a few minutes until ${userApplication.title ? styleText('italic', `'${userApplication.title}'`) : 'your application'} is unavailable.`);
|
|
70
|
-
this.log(`\n${styleText('bold', 'Remember to remove `deployment.appId` from your application configuration')} to avoid errors when redeploying.`);
|
|
71
|
-
} else {
|
|
72
|
-
this.log(`\nStudio undeploy scheduled. It might be a few minutes until ${url} is unavailable.`);
|
|
73
|
-
}
|
|
74
|
-
} catch (error) {
|
|
75
|
-
spin.fail();
|
|
76
|
-
if (error.message === NO_APP_ID) {
|
|
77
|
-
this.log('No application ID provided.');
|
|
78
|
-
this.log('Please set id in `deployment.appId` in sanity.cli.js or sanity.cli.ts.');
|
|
79
|
-
this.log('Nothing to undeploy.');
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
if (error.message === NO_APP_ID_OR_STUDIO_HOST) {
|
|
83
|
-
this.log('No application ID or studio host provided.');
|
|
84
|
-
this.log('Please set id in `deployment.appId` in sanity.cli.js or sanity.cli.ts.');
|
|
85
|
-
this.log('Nothing to undeploy.');
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
this.error(error);
|
|
89
|
-
}
|
|
45
|
+
// Workbench apps deploy through Brett, so they undeploy through it too;
|
|
46
|
+
// plain projects keep the user-applications backend.
|
|
47
|
+
const workbench = getWorkbench(cliConfig);
|
|
48
|
+
const adapter = workbench ? createWorkbenchUndeployAdapter({
|
|
49
|
+
appId: getAppId(cliConfig),
|
|
50
|
+
organizationId: cliConfig.app?.organizationId,
|
|
51
|
+
type: isApp ? 'coreApp' : 'studio',
|
|
52
|
+
workbench
|
|
53
|
+
}) : isApp ? createAppUndeployAdapter(cliConfig) : createStudioUndeployAdapter(cliConfig);
|
|
54
|
+
// An unattended run (--yes, --json, non-TTY) can't answer the confirmation
|
|
55
|
+
// prompt, so it consents up front; machine callers preview with --dry-run.
|
|
56
|
+
const undeployFlags = this.isUnattended() ? {
|
|
57
|
+
...flags,
|
|
58
|
+
yes: true
|
|
59
|
+
} : flags;
|
|
60
|
+
await runUndeploy({
|
|
61
|
+
flags: undeployFlags,
|
|
62
|
+
output: this.output
|
|
63
|
+
}, adapter);
|
|
90
64
|
}
|
|
91
65
|
}
|
|
92
66
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/undeploy.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/commands/undeploy.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\nimport {type UndeployAdapter} from '@sanity/cli-core/undeploy'\nimport {getWorkbench} from '@sanity/workbench-cli/deploy'\nimport {createWorkbenchUndeployAdapter} from '@sanity/workbench-cli/undeploy'\n\nimport {\n createAppUndeployAdapter,\n createStudioUndeployAdapter,\n} from '../actions/undeploy/adapters.js'\nimport {runUndeploy} from '../actions/undeploy/runUndeploy.js'\nimport {getAppId} from '../util/appId.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\n\nexport class UndeployCommand extends SanityCommand<typeof UndeployCommand> {\n static override description = 'Removes the deployed Sanity Studio/App from Sanity hosting'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Undeploy the studio or application after confirming',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --dry-run',\n description: 'Report what would be undeployed without deleting anything',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --json --yes',\n description: 'Undeploy without prompting and report the result as JSON',\n },\n ]\n\n static override flags = {\n 'dry-run': Flags.boolean({\n default: false,\n description: 'Report what would be undeployed without deleting anything',\n }),\n json: Flags.boolean({\n char: 'j',\n default: false,\n description: 'Output the result as JSON',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(UndeployCommand)\n\n const cliConfig = await this.getCliConfig()\n const isApp = determineIsApp(cliConfig)\n\n // Workbench apps deploy through Brett, so they undeploy through it too;\n // plain projects keep the user-applications backend.\n const workbench = getWorkbench(cliConfig)\n const adapter: UndeployAdapter = workbench\n ? createWorkbenchUndeployAdapter({\n appId: getAppId(cliConfig),\n organizationId: cliConfig.app?.organizationId,\n type: isApp ? 'coreApp' : 'studio',\n workbench,\n })\n : isApp\n ? createAppUndeployAdapter(cliConfig)\n : createStudioUndeployAdapter(cliConfig)\n\n // An unattended run (--yes, --json, non-TTY) can't answer the confirmation\n // prompt, so it consents up front; machine callers preview with --dry-run.\n const undeployFlags = this.isUnattended() ? {...flags, yes: true} : flags\n await runUndeploy({flags: undeployFlags, output: this.output}, adapter)\n }\n}\n"],"names":["Flags","SanityCommand","getWorkbench","createWorkbenchUndeployAdapter","createAppUndeployAdapter","createStudioUndeployAdapter","runUndeploy","getAppId","determineIsApp","UndeployCommand","description","examples","command","flags","boolean","default","json","char","yes","run","parse","cliConfig","getCliConfig","isApp","workbench","adapter","appId","organizationId","app","type","undeployFlags","isUnattended","output"],"mappings":"AAAA,SAAQA,KAAK,QAAO,cAAa;AACjC,SAAQC,aAAa,QAAO,mBAAkB;AAE9C,SAAQC,YAAY,QAAO,+BAA8B;AACzD,SAAQC,8BAA8B,QAAO,iCAAgC;AAE7E,SACEC,wBAAwB,EACxBC,2BAA2B,QACtB,kCAAiC;AACxC,SAAQC,WAAW,QAAO,qCAAoC;AAC9D,SAAQC,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,cAAc,QAAO,4BAA2B;AAExD,OAAO,MAAMC,wBAAwBR;IACnC,OAAgBS,cAAc,6DAA4D;IAE1F,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ;QACtB,WAAWb,MAAMc,OAAO,CAAC;YACvBC,SAAS;YACTL,aAAa;QACf;QACAM,MAAMhB,MAAMc,OAAO,CAAC;YAClBG,MAAM;YACNF,SAAS;YACTL,aAAa;QACf;QACAQ,KAAKlB,MAAMc,OAAO,CAAC;YACjBG,MAAM;YACNF,SAAS;YACTL,aACE;QACJ;IACF,EAAC;IAED,MAAaS,MAAqB;QAChC,MAAM,EAACN,KAAK,EAAC,GAAG,MAAM,IAAI,CAACO,KAAK,CAACX;QAEjC,MAAMY,YAAY,MAAM,IAAI,CAACC,YAAY;QACzC,MAAMC,QAAQf,eAAea;QAE7B,wEAAwE;QACxE,qDAAqD;QACrD,MAAMG,YAAYtB,aAAamB;QAC/B,MAAMI,UAA2BD,YAC7BrB,+BAA+B;YAC7BuB,OAAOnB,SAASc;YAChBM,gBAAgBN,UAAUO,GAAG,EAAED;YAC/BE,MAAMN,QAAQ,YAAY;YAC1BC;QACF,KACAD,QACEnB,yBAAyBiB,aACzBhB,4BAA4BgB;QAElC,2EAA2E;QAC3E,2EAA2E;QAC3E,MAAMS,gBAAgB,IAAI,CAACC,YAAY,KAAK;YAAC,GAAGlB,KAAK;YAAEK,KAAK;QAAI,IAAIL;QACpE,MAAMP,YAAY;YAACO,OAAOiB;YAAeE,QAAQ,IAAI,CAACA,MAAM;QAAA,GAAGP;IACjE;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/devServer.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {\n extendViteConfigWithUserConfig,\n getViteConfig,\n writeSanityRuntime,\n} from '@sanity/cli-build/_internal/build'\nimport {\n getAppEnvironmentVariables,\n getStudioEnvironmentVariables,\n} from '@sanity/cli-build/_internal/env'\nimport {CliConfig, getCliTelemetry, type UserViteConfig} from '@sanity/cli-core'\nimport {type WorkbenchExposes} from '@sanity/workbench-cli/build'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport {type FSWatcher} from 'chokidar'\nimport {createServer, type InlineConfig, type ViteDevServer} from 'vite'\n\nimport {serverDebug} from './serverDebug.js'\nimport {sanityTypegenPlugin} from './vite/plugin-typegen.js'\n\nconst debug = serverDebug.extend('dev')\n\nexport interface DevServerOptions {\n basePath: string\n cwd: string\n httpPort: number\n\n reactCompiler: ReactCompilerConfig | undefined\n reactStrictMode: boolean | undefined\n\n staticPath: string\n\n appTitle?: string\n /** Enable Vite's experimental bundled dev mode (`experimental.bundledDev`). */\n bundledDev?: boolean\n entry?: string\n exposes?: WorkbenchExposes\n httpHost?: string\n isApp?: boolean\n isWorkbenchApp?: boolean\n projectName?: string\n schemaExtraction?: CliConfig['schemaExtraction']\n typegen?: CliConfig['typegen']\n vite?: UserViteConfig\n /** The workbench app's bus identity (`__SANITY_APP_ID__`). */\n workbenchAppId?: string\n}\n\ninterface DevServer {\n close(): Promise<void>\n server: ViteDevServer\n\n watcher?: FSWatcher\n}\n\nexport async function startDevServer(options: DevServerOptions): Promise<DevServer> {\n const {\n appTitle,\n basePath,\n bundledDev,\n cwd,\n entry,\n exposes,\n httpHost,\n httpPort,\n isApp,\n isWorkbenchApp,\n reactCompiler,\n reactStrictMode,\n schemaExtraction,\n typegen,\n vite: extendViteConfig,\n workbenchAppId,\n } = options\n\n debug('Writing Sanity runtime files')\n const {entries, watcher} = await writeSanityRuntime({\n appTitle,\n basePath,\n cwd,\n entry,\n isApp,\n isWorkbenchApp,\n reactStrictMode,\n watch: true,\n })\n\n debug('Resolving vite config')\n const mode = 'development'\n\n function getEnvironmentVariables() {\n return isApp\n ? getAppEnvironmentVariables({jsonEncode: true, prefix: 'process.env.'})\n : getStudioEnvironmentVariables({jsonEncode: true, prefix: 'process.env.'})\n }\n\n let viteConfig: InlineConfig = await getViteConfig({\n additionalPlugins: [\n // Add typegen when enabled\n ...(typegen?.enabled\n ? [\n sanityTypegenPlugin({\n config: typegen,\n telemetryLogger: getCliTelemetry(),\n workDir: cwd,\n }),\n ]\n : []),\n ],\n basePath,\n cwd,\n entries,\n exposes,\n getEnvironmentVariables,\n isApp,\n isWorkbenchApp,\n mode: 'development',\n reactCompiler,\n schemaExtraction,\n server: {host: httpHost, port: httpPort},\n workbenchAppId,\n })\n\n // Opt into Vite's experimental bundled dev mode. Set before the user-config\n // extension below so a `vite` override in sanity.cli.ts still has final say.\n //\n // Bundled mode bundles the app up front from an HTML entry, defaulting to\n // `<root>/index.html`. Sanity has no such file — it serves a virtual document\n // rewritten to `.sanity/runtime/index.html` — so point the bundler at the real\n // runtime HTML, otherwise the build fails with UNRESOLVED_ENTRY.\n if (bundledDev) {\n viteConfig = {\n ...viteConfig,\n build: {\n ...viteConfig.build,\n rolldownOptions: {\n ...viteConfig.build?.rolldownOptions,\n input: path.join(cwd, '.sanity', 'runtime', 'index.html'),\n },\n },\n experimental: {...viteConfig.experimental, bundledDev: true},\n }\n }\n\n // Extend Vite configuration with user-provided config\n if (extendViteConfig) {\n viteConfig = await extendViteConfigWithUserConfig(\n {command: 'serve', mode},\n viteConfig,\n extendViteConfig,\n )\n }\n\n debug('Creating vite server')\n const server = await createServer(viteConfig)\n\n debug('Listening on specified port')\n await server.listen()\n\n return {\n close: async () => {\n if (watcher) {\n await watcher.close()\n }\n await server.close()\n },\n server,\n watcher,\n }\n}\n"],"names":["path","extendViteConfigWithUserConfig","getViteConfig","writeSanityRuntime","getAppEnvironmentVariables","getStudioEnvironmentVariables","getCliTelemetry","createServer","serverDebug","sanityTypegenPlugin","debug","extend","startDevServer","options","appTitle","basePath","bundledDev","cwd","entry","exposes","httpHost","httpPort","isApp","isWorkbenchApp","reactCompiler","reactStrictMode","schemaExtraction","typegen","vite","extendViteConfig","workbenchAppId","entries","watcher","watch","mode","getEnvironmentVariables","jsonEncode","prefix","viteConfig","additionalPlugins","enabled","config","telemetryLogger","workDir","server","host","port","build","rolldownOptions","input","join","experimental","command","listen","close"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,SACEC,8BAA8B,EAC9BC,aAAa,EACbC,kBAAkB,QACb,oCAAmC;AAC1C,SACEC,0BAA0B,EAC1BC,6BAA6B,QACxB,kCAAiC;AACxC,SAAmBC,eAAe,QAA4B,mBAAkB;AAIhF,SAAQC,YAAY,QAA8C,OAAM;AAExE,SAAQC,WAAW,QAAO,mBAAkB;AAC5C,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,MAAMC,QAAQF,YAAYG,MAAM,CAAC;AAmCjC,OAAO,eAAeC,eAAeC,OAAyB;IAC5D,MAAM,EACJC,QAAQ,EACRC,QAAQ,EACRC,UAAU,EACVC,GAAG,EACHC,KAAK,EACLC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,cAAc,EACdC,aAAa,EACbC,eAAe,EACfC,gBAAgB,EAChBC,OAAO,EACPC,MAAMC,gBAAgB,EACtBC,cAAc,EACf,GAAGjB;IAEJH,MAAM;IACN,MAAM,EAACqB,OAAO,EAAEC,OAAO,EAAC,GAAG,MAAM7B,mBAAmB;QAClDW;QACAC;QACAE;QACAC;QACAI;QACAC;QACAE;QACAQ,OAAO;IACT;IAEAvB,MAAM;IACN,MAAMwB,OAAO;IAEb,SAASC;QACP,OAAOb,QACHlB,2BAA2B;YAACgC,YAAY;YAAMC,QAAQ;QAAc,KACpEhC,8BAA8B;YAAC+B,YAAY;YAAMC,QAAQ;QAAc;IAC7E;IAEA,IAAIC,aAA2B,MAAMpC,cAAc;QACjDqC,mBAAmB;YACjB,2BAA2B;eACvBZ,SAASa,UACT;gBACE/B,oBAAoB;oBAClBgC,QAAQd;oBACRe,iBAAiBpC;oBACjBqC,SAAS1B;gBACX;aACD,GACD,EAAE;SACP;QACDF;QACAE;QACAc;QACAZ;QACAgB;QACAb;QACAC;QACAW,MAAM;QACNV;QACAE;QACAkB,QAAQ;YAACC,MAAMzB;YAAU0B,MAAMzB;QAAQ;QACvCS;IACF;IAEA,4EAA4E;IAC5E,6EAA6E;IAC7E,EAAE;IACF,0EAA0E;IAC1E,8EAA8E;IAC9E,+EAA+E;IAC/E,iEAAiE;IACjE,IAAId,YAAY;QACdsB,aAAa;YACX,GAAGA,UAAU;YACbS,OAAO;gBACL,GAAGT,WAAWS,KAAK;gBACnBC,iBAAiB;oBACf,GAAGV,WAAWS,KAAK,EAAEC,eAAe;oBACpCC,OAAOjD,KAAKkD,IAAI,CAACjC,KAAK,WAAW,WAAW;gBAC9C;YACF;YACAkC,cAAc;gBAAC,GAAGb,WAAWa,YAAY;gBAAEnC,YAAY;YAAI;QAC7D;IACF;IAEA,sDAAsD;IACtD,IAAIa,kBAAkB;QACpBS,aAAa,MAAMrC,+BACjB;YAACmD,SAAS;YAASlB;QAAI,GACvBI,YACAT;IAEJ;IAEAnB,MAAM;IACN,MAAMkC,SAAS,MAAMrC,aAAa+B;IAElC5B,MAAM;IACN,MAAMkC,OAAOS,MAAM;IAEnB,OAAO;QACLC,OAAO;YACL,IAAItB,SAAS;gBACX,MAAMA,QAAQsB,KAAK;YACrB;YACA,MAAMV,OAAOU,KAAK;QACpB;QACAV;QACAZ;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../src/server/devServer.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {\n extendViteConfigWithUserConfig,\n getViteConfig,\n writeSanityRuntime,\n} from '@sanity/cli-build/_internal/build'\nimport {\n getAppEnvironmentVariables,\n getStudioEnvironmentVariables,\n} from '@sanity/cli-build/_internal/env'\nimport {CliConfig, getCliTelemetry, type UserViteConfig} from '@sanity/cli-core'\nimport {type WorkbenchExposes} from '@sanity/workbench-cli/build'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport {type FSWatcher} from 'chokidar'\nimport {createServer, type InlineConfig, type ViteDevServer} from 'vite'\n\nimport {serverDebug} from './serverDebug.js'\nimport {sanityTypegenPlugin} from './vite/plugin-typegen.js'\n\nconst debug = serverDebug.extend('dev')\n\nexport interface DevServerOptions {\n basePath: string\n cwd: string\n httpPort: number\n\n reactCompiler: boolean | ReactCompilerConfig | undefined\n reactStrictMode: boolean | undefined\n\n staticPath: string\n\n appTitle?: string\n /** Enable Vite's experimental bundled dev mode (`experimental.bundledDev`). */\n bundledDev?: boolean\n entry?: string\n exposes?: WorkbenchExposes\n httpHost?: string\n isApp?: boolean\n isWorkbenchApp?: boolean\n projectName?: string\n schemaExtraction?: CliConfig['schemaExtraction']\n typegen?: CliConfig['typegen']\n vite?: UserViteConfig\n /** The workbench app's bus identity (`__SANITY_APP_ID__`). */\n workbenchAppId?: string\n}\n\ninterface DevServer {\n close(): Promise<void>\n server: ViteDevServer\n\n watcher?: FSWatcher\n}\n\nexport async function startDevServer(options: DevServerOptions): Promise<DevServer> {\n const {\n appTitle,\n basePath,\n bundledDev,\n cwd,\n entry,\n exposes,\n httpHost,\n httpPort,\n isApp,\n isWorkbenchApp,\n reactCompiler,\n reactStrictMode,\n schemaExtraction,\n typegen,\n vite: extendViteConfig,\n workbenchAppId,\n } = options\n\n debug('Writing Sanity runtime files')\n const {entries, watcher} = await writeSanityRuntime({\n appTitle,\n basePath,\n cwd,\n entry,\n isApp,\n isWorkbenchApp,\n reactStrictMode,\n watch: true,\n })\n\n debug('Resolving vite config')\n const mode = 'development'\n\n function getEnvironmentVariables() {\n return isApp\n ? getAppEnvironmentVariables({jsonEncode: true, prefix: 'process.env.'})\n : getStudioEnvironmentVariables({jsonEncode: true, prefix: 'process.env.'})\n }\n\n let viteConfig: InlineConfig = await getViteConfig({\n additionalPlugins: [\n // Add typegen when enabled\n ...(typegen?.enabled\n ? [\n sanityTypegenPlugin({\n config: typegen,\n telemetryLogger: getCliTelemetry(),\n workDir: cwd,\n }),\n ]\n : []),\n ],\n basePath,\n cwd,\n entries,\n exposes,\n getEnvironmentVariables,\n isApp,\n isWorkbenchApp,\n mode: 'development',\n reactCompiler,\n schemaExtraction,\n server: {host: httpHost, port: httpPort},\n workbenchAppId,\n })\n\n // Opt into Vite's experimental bundled dev mode. Set before the user-config\n // extension below so a `vite` override in sanity.cli.ts still has final say.\n //\n // Bundled mode bundles the app up front from an HTML entry, defaulting to\n // `<root>/index.html`. Sanity has no such file — it serves a virtual document\n // rewritten to `.sanity/runtime/index.html` — so point the bundler at the real\n // runtime HTML, otherwise the build fails with UNRESOLVED_ENTRY.\n if (bundledDev) {\n viteConfig = {\n ...viteConfig,\n build: {\n ...viteConfig.build,\n rolldownOptions: {\n ...viteConfig.build?.rolldownOptions,\n input: path.join(cwd, '.sanity', 'runtime', 'index.html'),\n },\n },\n experimental: {...viteConfig.experimental, bundledDev: true},\n }\n }\n\n // Extend Vite configuration with user-provided config\n if (extendViteConfig) {\n viteConfig = await extendViteConfigWithUserConfig(\n {command: 'serve', mode},\n viteConfig,\n extendViteConfig,\n )\n }\n\n debug('Creating vite server')\n const server = await createServer(viteConfig)\n\n debug('Listening on specified port')\n await server.listen()\n\n return {\n close: async () => {\n if (watcher) {\n await watcher.close()\n }\n await server.close()\n },\n server,\n watcher,\n }\n}\n"],"names":["path","extendViteConfigWithUserConfig","getViteConfig","writeSanityRuntime","getAppEnvironmentVariables","getStudioEnvironmentVariables","getCliTelemetry","createServer","serverDebug","sanityTypegenPlugin","debug","extend","startDevServer","options","appTitle","basePath","bundledDev","cwd","entry","exposes","httpHost","httpPort","isApp","isWorkbenchApp","reactCompiler","reactStrictMode","schemaExtraction","typegen","vite","extendViteConfig","workbenchAppId","entries","watcher","watch","mode","getEnvironmentVariables","jsonEncode","prefix","viteConfig","additionalPlugins","enabled","config","telemetryLogger","workDir","server","host","port","build","rolldownOptions","input","join","experimental","command","listen","close"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,SACEC,8BAA8B,EAC9BC,aAAa,EACbC,kBAAkB,QACb,oCAAmC;AAC1C,SACEC,0BAA0B,EAC1BC,6BAA6B,QACxB,kCAAiC;AACxC,SAAmBC,eAAe,QAA4B,mBAAkB;AAIhF,SAAQC,YAAY,QAA8C,OAAM;AAExE,SAAQC,WAAW,QAAO,mBAAkB;AAC5C,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,MAAMC,QAAQF,YAAYG,MAAM,CAAC;AAmCjC,OAAO,eAAeC,eAAeC,OAAyB;IAC5D,MAAM,EACJC,QAAQ,EACRC,QAAQ,EACRC,UAAU,EACVC,GAAG,EACHC,KAAK,EACLC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,cAAc,EACdC,aAAa,EACbC,eAAe,EACfC,gBAAgB,EAChBC,OAAO,EACPC,MAAMC,gBAAgB,EACtBC,cAAc,EACf,GAAGjB;IAEJH,MAAM;IACN,MAAM,EAACqB,OAAO,EAAEC,OAAO,EAAC,GAAG,MAAM7B,mBAAmB;QAClDW;QACAC;QACAE;QACAC;QACAI;QACAC;QACAE;QACAQ,OAAO;IACT;IAEAvB,MAAM;IACN,MAAMwB,OAAO;IAEb,SAASC;QACP,OAAOb,QACHlB,2BAA2B;YAACgC,YAAY;YAAMC,QAAQ;QAAc,KACpEhC,8BAA8B;YAAC+B,YAAY;YAAMC,QAAQ;QAAc;IAC7E;IAEA,IAAIC,aAA2B,MAAMpC,cAAc;QACjDqC,mBAAmB;YACjB,2BAA2B;eACvBZ,SAASa,UACT;gBACE/B,oBAAoB;oBAClBgC,QAAQd;oBACRe,iBAAiBpC;oBACjBqC,SAAS1B;gBACX;aACD,GACD,EAAE;SACP;QACDF;QACAE;QACAc;QACAZ;QACAgB;QACAb;QACAC;QACAW,MAAM;QACNV;QACAE;QACAkB,QAAQ;YAACC,MAAMzB;YAAU0B,MAAMzB;QAAQ;QACvCS;IACF;IAEA,4EAA4E;IAC5E,6EAA6E;IAC7E,EAAE;IACF,0EAA0E;IAC1E,8EAA8E;IAC9E,+EAA+E;IAC/E,iEAAiE;IACjE,IAAId,YAAY;QACdsB,aAAa;YACX,GAAGA,UAAU;YACbS,OAAO;gBACL,GAAGT,WAAWS,KAAK;gBACnBC,iBAAiB;oBACf,GAAGV,WAAWS,KAAK,EAAEC,eAAe;oBACpCC,OAAOjD,KAAKkD,IAAI,CAACjC,KAAK,WAAW,WAAW;gBAC9C;YACF;YACAkC,cAAc;gBAAC,GAAGb,WAAWa,YAAY;gBAAEnC,YAAY;YAAI;QAC7D;IACF;IAEA,sDAAsD;IACtD,IAAIa,kBAAkB;QACpBS,aAAa,MAAMrC,+BACjB;YAACmD,SAAS;YAASlB;QAAI,GACvBI,YACAT;IAEJ;IAEAnB,MAAM;IACN,MAAMkC,SAAS,MAAMrC,aAAa+B;IAElC5B,MAAM;IACN,MAAMkC,OAAOS,MAAM;IAEnB,OAAO;QACLC,OAAO;YACL,IAAItB,SAAS;gBACX,MAAMA,QAAQsB,KAAK;YACrB;YACA,MAAMV,OAAOU,KAAK;QACpB;QACAV;QACAZ;IACF;AACF"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { debug as cliDebug } from '@sanity/cli-core';
|
|
2
|
+
import { getErrorMessage } from '@sanity/cli-core/errors';
|
|
3
|
+
import { logSymbols } from '@sanity/cli-core/ux';
|
|
4
|
+
export function createFailFastReporter(output) {
|
|
5
|
+
return {
|
|
6
|
+
report (check) {
|
|
7
|
+
// Fixes surface in both modes: appended after the message here, and in the
|
|
8
|
+
// dry-run report, so the problem and its fix never drift apart.
|
|
9
|
+
const text = check.solution ? `${check.message}: ${check.solution}` : check.message;
|
|
10
|
+
if (check.status === 'fail') {
|
|
11
|
+
output.error(text, {
|
|
12
|
+
exit: check.exitCode ?? 1
|
|
13
|
+
});
|
|
14
|
+
} else if (check.status === 'warn') {
|
|
15
|
+
output.warn(text);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function createCollectingReporter() {
|
|
21
|
+
const results = [];
|
|
22
|
+
return {
|
|
23
|
+
report (check) {
|
|
24
|
+
results.push(check);
|
|
25
|
+
},
|
|
26
|
+
results
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Runs a fallible step and turns a throw into a `fail` check. In a real run
|
|
31
|
+
* that fail exits (aborting the sequence); in a dry run it's recorded and
|
|
32
|
+
* `null` comes back so the caller can skip the rest of the step. `name` labels
|
|
33
|
+
* the step in debug logs.
|
|
34
|
+
*/ export async function runStep(reporter, step) {
|
|
35
|
+
const { debug = cliDebug, formatError = getErrorMessage, name, solution, work } = step;
|
|
36
|
+
try {
|
|
37
|
+
return await work();
|
|
38
|
+
} catch (err) {
|
|
39
|
+
debug(`${name} step failed`, err);
|
|
40
|
+
reporter.report({
|
|
41
|
+
message: formatError(err),
|
|
42
|
+
solution,
|
|
43
|
+
status: 'fail'
|
|
44
|
+
});
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function checkStatusIcon(status) {
|
|
49
|
+
switch(status){
|
|
50
|
+
case 'fail':
|
|
51
|
+
{
|
|
52
|
+
return logSymbols.error;
|
|
53
|
+
}
|
|
54
|
+
case 'skip':
|
|
55
|
+
{
|
|
56
|
+
return logSymbols.info;
|
|
57
|
+
}
|
|
58
|
+
case 'warn':
|
|
59
|
+
{
|
|
60
|
+
return logSymbols.warning;
|
|
61
|
+
}
|
|
62
|
+
default:
|
|
63
|
+
{
|
|
64
|
+
return logSymbols.success;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Indents continuation lines of a multi-line check message past the status
|
|
70
|
+
* icon so its items nest under the heading.
|
|
71
|
+
*/ export function nestLines(text) {
|
|
72
|
+
return text.replaceAll('\n', '\n ');
|
|
73
|
+
}
|
|
74
|
+
/** Renders problem/warning checks under a title, each with its fix appended. */ export function renderIssues(output, title, checks) {
|
|
75
|
+
if (checks.length === 0) return;
|
|
76
|
+
output.log(`\n${title}`);
|
|
77
|
+
for (const check of checks){
|
|
78
|
+
const fix = check.solution ? `: ${check.solution}` : '';
|
|
79
|
+
output.log(nestLines(` ${checkStatusIcon(check.status)} ${check.message}${fix}`));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=checks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/checks.ts"],"sourcesContent":["import {debug as cliDebug, type Output} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {logSymbols} from '@sanity/cli-core/ux'\n\nexport type CheckStatus = 'fail' | 'pass' | 'skip' | 'warn'\n\nexport interface Check {\n message: string\n status: CheckStatus\n\n /** Exit code a real run uses when this check fails; defaults to 1 */\n exitCode?: number\n /** Actionable fix, shown under a failing or warning check */\n solution?: string\n}\n\n/**\n * Where a command's steps send their check outcomes — and the only place the\n * run mode lives. A real run fails fast: a `fail` prints and exits immediately,\n * which aborts the sequence. A dry run collects every outcome and never exits.\n * Steps just call `report`; they never know which mode is running.\n */\nexport interface CheckReporter<TCheck extends Check = Check> {\n report(check: TCheck): void\n}\n\nexport function createFailFastReporter(output: Output): CheckReporter {\n return {\n report(check) {\n // Fixes surface in both modes: appended after the message here, and in the\n // dry-run report, so the problem and its fix never drift apart.\n const text = check.solution ? `${check.message}: ${check.solution}` : check.message\n if (check.status === 'fail') {\n output.error(text, {exit: check.exitCode ?? 1})\n } else if (check.status === 'warn') {\n output.warn(text)\n }\n },\n }\n}\n\nexport function createCollectingReporter<TCheck extends Check = Check>(): CheckReporter<TCheck> & {\n results: TCheck[]\n} {\n const results: TCheck[] = []\n return {\n report(check) {\n results.push(check)\n },\n results,\n }\n}\n\n/**\n * Runs a fallible step and turns a throw into a `fail` check. In a real run\n * that fail exits (aborting the sequence); in a dry run it's recorded and\n * `null` comes back so the caller can skip the rest of the step. `name` labels\n * the step in debug logs.\n */\nexport async function runStep<T>(\n reporter: CheckReporter,\n step: {\n debug?: (message: string, error: unknown) => void\n formatError?: (error: unknown) => string\n\n name: string\n solution?: string\n work: () => Promise<T>\n },\n): Promise<T | null> {\n const {debug = cliDebug, formatError = getErrorMessage, name, solution, work} = step\n try {\n return await work()\n } catch (err) {\n debug(`${name} step failed`, err)\n reporter.report({message: formatError(err), solution, status: 'fail'})\n return null\n }\n}\n\nexport function checkStatusIcon(status: CheckStatus): string {\n switch (status) {\n case 'fail': {\n return logSymbols.error\n }\n case 'skip': {\n return logSymbols.info\n }\n case 'warn': {\n return logSymbols.warning\n }\n default: {\n return logSymbols.success\n }\n }\n}\n\n/**\n * Indents continuation lines of a multi-line check message past the status\n * icon so its items nest under the heading.\n */\nexport function nestLines(text: string): string {\n return text.replaceAll('\\n', '\\n ')\n}\n\n/** Renders problem/warning checks under a title, each with its fix appended. */\nexport function renderIssues(output: Output, title: string, checks: Check[]): void {\n if (checks.length === 0) return\n\n output.log(`\\n${title}`)\n for (const check of checks) {\n const fix = check.solution ? `: ${check.solution}` : ''\n output.log(nestLines(` ${checkStatusIcon(check.status)} ${check.message}${fix}`))\n }\n}\n"],"names":["debug","cliDebug","getErrorMessage","logSymbols","createFailFastReporter","output","report","check","text","solution","message","status","error","exit","exitCode","warn","createCollectingReporter","results","push","runStep","reporter","step","formatError","name","work","err","checkStatusIcon","info","warning","success","nestLines","replaceAll","renderIssues","title","checks","length","log","fix"],"mappings":"AAAA,SAAQA,SAASC,QAAQ,QAAoB,mBAAkB;AAC/D,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,UAAU,QAAO,sBAAqB;AAwB9C,OAAO,SAASC,uBAAuBC,MAAc;IACnD,OAAO;QACLC,QAAOC,KAAK;YACV,2EAA2E;YAC3E,gEAAgE;YAChE,MAAMC,OAAOD,MAAME,QAAQ,GAAG,GAAGF,MAAMG,OAAO,CAAC,EAAE,EAAEH,MAAME,QAAQ,EAAE,GAAGF,MAAMG,OAAO;YACnF,IAAIH,MAAMI,MAAM,KAAK,QAAQ;gBAC3BN,OAAOO,KAAK,CAACJ,MAAM;oBAACK,MAAMN,MAAMO,QAAQ,IAAI;gBAAC;YAC/C,OAAO,IAAIP,MAAMI,MAAM,KAAK,QAAQ;gBAClCN,OAAOU,IAAI,CAACP;YACd;QACF;IACF;AACF;AAEA,OAAO,SAASQ;IAGd,MAAMC,UAAoB,EAAE;IAC5B,OAAO;QACLX,QAAOC,KAAK;YACVU,QAAQC,IAAI,CAACX;QACf;QACAU;IACF;AACF;AAEA;;;;;CAKC,GACD,OAAO,eAAeE,QACpBC,QAAuB,EACvBC,IAOC;IAED,MAAM,EAACrB,QAAQC,QAAQ,EAAEqB,cAAcpB,eAAe,EAAEqB,IAAI,EAAEd,QAAQ,EAAEe,IAAI,EAAC,GAAGH;IAChF,IAAI;QACF,OAAO,MAAMG;IACf,EAAE,OAAOC,KAAK;QACZzB,MAAM,GAAGuB,KAAK,YAAY,CAAC,EAAEE;QAC7BL,SAASd,MAAM,CAAC;YAACI,SAASY,YAAYG;YAAMhB;YAAUE,QAAQ;QAAM;QACpE,OAAO;IACT;AACF;AAEA,OAAO,SAASe,gBAAgBf,MAAmB;IACjD,OAAQA;QACN,KAAK;YAAQ;gBACX,OAAOR,WAAWS,KAAK;YACzB;QACA,KAAK;YAAQ;gBACX,OAAOT,WAAWwB,IAAI;YACxB;QACA,KAAK;YAAQ;gBACX,OAAOxB,WAAWyB,OAAO;YAC3B;QACA;YAAS;gBACP,OAAOzB,WAAW0B,OAAO;YAC3B;IACF;AACF;AAEA;;;CAGC,GACD,OAAO,SAASC,UAAUtB,IAAY;IACpC,OAAOA,KAAKuB,UAAU,CAAC,MAAM;AAC/B;AAEA,8EAA8E,GAC9E,OAAO,SAASC,aAAa3B,MAAc,EAAE4B,KAAa,EAAEC,MAAe;IACzE,IAAIA,OAAOC,MAAM,KAAK,GAAG;IAEzB9B,OAAO+B,GAAG,CAAC,CAAC,EAAE,EAAEH,OAAO;IACvB,KAAK,MAAM1B,SAAS2B,OAAQ;QAC1B,MAAMG,MAAM9B,MAAME,QAAQ,GAAG,CAAC,EAAE,EAAEF,MAAME,QAAQ,EAAE,GAAG;QACrDJ,OAAO+B,GAAG,CAACN,UAAU,CAAC,EAAE,EAAEJ,gBAAgBnB,MAAMI,MAAM,EAAE,CAAC,EAAEJ,MAAMG,OAAO,GAAG2B,KAAK;IAClF;AACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { format } from 'node:util';
|
|
2
|
+
/**
|
|
3
|
+
* An `Output` whose `log` writes to stderr, for `--json` runs where the payload
|
|
4
|
+
* owns stdout and progress logs must not corrupt it. Spinners are already on
|
|
5
|
+
* stderr.
|
|
6
|
+
*/ export function toStderrOutput(output) {
|
|
7
|
+
return {
|
|
8
|
+
...output,
|
|
9
|
+
log: (message = '', ...args)=>void process.stderr.write(`${format(message, ...args)}\n`)
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=toStderrOutput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/toStderrOutput.ts"],"sourcesContent":["import {format} from 'node:util'\n\nimport {type Output} from '@sanity/cli-core'\n\n/**\n * An `Output` whose `log` writes to stderr, for `--json` runs where the payload\n * owns stdout and progress logs must not corrupt it. Spinners are already on\n * stderr.\n */\nexport function toStderrOutput(output: Output): Output {\n return {\n ...output,\n log: (message = '', ...args: unknown[]) =>\n void process.stderr.write(`${format(message, ...args)}\\n`),\n }\n}\n"],"names":["format","toStderrOutput","output","log","message","args","process","stderr","write"],"mappings":"AAAA,SAAQA,MAAM,QAAO,YAAW;AAIhC;;;;CAIC,GACD,OAAO,SAASC,eAAeC,MAAc;IAC3C,OAAO;QACL,GAAGA,MAAM;QACTC,KAAK,CAACC,UAAU,EAAE,EAAE,GAAGC,OACrB,KAAKC,QAAQC,MAAM,CAACC,KAAK,CAAC,GAAGR,OAAOI,YAAYC,MAAM,EAAE,CAAC;IAC7D;AACF"}
|
package/oclif.manifest.json
CHANGED
|
@@ -1011,7 +1011,34 @@
|
|
|
1011
1011
|
"aliases": [],
|
|
1012
1012
|
"args": {},
|
|
1013
1013
|
"description": "Removes the deployed Sanity Studio/App from Sanity hosting",
|
|
1014
|
+
"examples": [
|
|
1015
|
+
{
|
|
1016
|
+
"command": "<%= config.bin %> <%= command.id %>",
|
|
1017
|
+
"description": "Undeploy the studio or application after confirming"
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
"command": "<%= config.bin %> <%= command.id %> --dry-run",
|
|
1021
|
+
"description": "Report what would be undeployed without deleting anything"
|
|
1022
|
+
},
|
|
1023
|
+
{
|
|
1024
|
+
"command": "<%= config.bin %> <%= command.id %> --json --yes",
|
|
1025
|
+
"description": "Undeploy without prompting and report the result as JSON"
|
|
1026
|
+
}
|
|
1027
|
+
],
|
|
1014
1028
|
"flags": {
|
|
1029
|
+
"dry-run": {
|
|
1030
|
+
"description": "Report what would be undeployed without deleting anything",
|
|
1031
|
+
"name": "dry-run",
|
|
1032
|
+
"allowNo": false,
|
|
1033
|
+
"type": "boolean"
|
|
1034
|
+
},
|
|
1035
|
+
"json": {
|
|
1036
|
+
"char": "j",
|
|
1037
|
+
"description": "Output the result as JSON",
|
|
1038
|
+
"name": "json",
|
|
1039
|
+
"allowNo": false,
|
|
1040
|
+
"type": "boolean"
|
|
1041
|
+
},
|
|
1015
1042
|
"yes": {
|
|
1016
1043
|
"char": "y",
|
|
1017
1044
|
"description": "Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults",
|
|
@@ -5169,5 +5196,5 @@
|
|
|
5169
5196
|
]
|
|
5170
5197
|
}
|
|
5171
5198
|
},
|
|
5172
|
-
"version": "7.
|
|
5199
|
+
"version": "7.9.0"
|
|
5173
5200
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/cli",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.9.0",
|
|
4
4
|
"description": "Sanity CLI tool for managing Sanity projects and organizations",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -118,9 +118,9 @@
|
|
|
118
118
|
"which": "^6.0.1",
|
|
119
119
|
"yaml": "^2.9.0",
|
|
120
120
|
"zod": "^4.4.3",
|
|
121
|
-
"@sanity/
|
|
122
|
-
"@sanity/cli-
|
|
123
|
-
"@sanity/cli
|
|
121
|
+
"@sanity/cli-build": "^4.1.0",
|
|
122
|
+
"@sanity/cli-core": "^2.4.0",
|
|
123
|
+
"@sanity/workbench-cli": "^1.4.0"
|
|
124
124
|
},
|
|
125
125
|
"devDependencies": {
|
|
126
126
|
"@eslint/compat": "^2.1.0",
|
|
@@ -144,7 +144,6 @@
|
|
|
144
144
|
"@types/which": "^3.0.4",
|
|
145
145
|
"@vitest/coverage-istanbul": "^4.1.9",
|
|
146
146
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
147
|
-
"es-module-lexer": "^2.1.0",
|
|
148
147
|
"eslint": "^10.4.1",
|
|
149
148
|
"jsdom": "^29.1.1",
|
|
150
149
|
"nock": "^14.0.15",
|
|
@@ -155,9 +154,9 @@
|
|
|
155
154
|
"typescript": "^5.9.3",
|
|
156
155
|
"vitest": "^4.1.9",
|
|
157
156
|
"@repo/package.config": "0.0.1",
|
|
158
|
-
"@
|
|
159
|
-
"@sanity/cli
|
|
160
|
-
"@
|
|
157
|
+
"@sanity/cli-test": "5.0.0",
|
|
158
|
+
"@sanity/eslint-config-cli": "1.1.2",
|
|
159
|
+
"@repo/tsconfig": "3.70.0"
|
|
161
160
|
},
|
|
162
161
|
"peerDependencies": {
|
|
163
162
|
"babel-plugin-react-compiler": "*"
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { getUserApplication } from '../../services/userApplications.js';
|
|
2
|
-
import { getAppId } from '../../util/appId.js';
|
|
3
|
-
import { determineIsApp } from '../../util/determineIsApp.js';
|
|
4
|
-
import { NO_PROJECT_ID } from '../../util/errorMessages.js';
|
|
5
|
-
export const NO_APP_ID = 'NO_APP_ID';
|
|
6
|
-
export const NO_APP_ID_OR_STUDIO_HOST = 'NO_APP_ID_OR_STUDIO_HOST';
|
|
7
|
-
// Used only in undeploy flow
|
|
8
|
-
export async function getStudioOrAppUserApplication(options) {
|
|
9
|
-
const { cliConfig } = options;
|
|
10
|
-
const projectId = cliConfig.api?.projectId;
|
|
11
|
-
const isApp = determineIsApp(cliConfig);
|
|
12
|
-
if (isApp) {
|
|
13
|
-
const appId = getAppId(cliConfig);
|
|
14
|
-
if (!appId) {
|
|
15
|
-
throw new Error(NO_APP_ID);
|
|
16
|
-
}
|
|
17
|
-
return getUserApplication({
|
|
18
|
-
appId,
|
|
19
|
-
isSdkApp: true
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
if (!cliConfig.studioHost && !cliConfig.deployment?.appId) {
|
|
23
|
-
throw new Error(NO_APP_ID_OR_STUDIO_HOST);
|
|
24
|
-
}
|
|
25
|
-
if (!projectId) {
|
|
26
|
-
throw new Error(NO_PROJECT_ID);
|
|
27
|
-
}
|
|
28
|
-
return getUserApplication({
|
|
29
|
-
appHost: cliConfig.studioHost,
|
|
30
|
-
appId: cliConfig.deployment?.appId,
|
|
31
|
-
isSdkApp: false,
|
|
32
|
-
projectId
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
//# sourceMappingURL=getStudioOrAppUserApplication.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/undeploy/getStudioOrAppUserApplication.ts"],"sourcesContent":["import {type CliConfig, type Output} from '@sanity/cli-core'\n\nimport {getUserApplication} from '../../services/userApplications.js'\nimport {getAppId} from '../../util/appId.js'\nimport {determineIsApp} from '../../util/determineIsApp.js'\nimport {NO_PROJECT_ID} from '../../util/errorMessages.js'\n\ninterface GetStudioOrAppUserApplicationOptions {\n cliConfig: CliConfig\n output: Output\n}\n\nexport const NO_APP_ID = 'NO_APP_ID'\nexport const NO_APP_ID_OR_STUDIO_HOST = 'NO_APP_ID_OR_STUDIO_HOST'\n\n// Used only in undeploy flow\nexport async function getStudioOrAppUserApplication(options: GetStudioOrAppUserApplicationOptions) {\n const {cliConfig} = options\n const projectId = cliConfig.api?.projectId\n const isApp = determineIsApp(cliConfig)\n\n if (isApp) {\n const appId = getAppId(cliConfig)\n if (!appId) {\n throw new Error(NO_APP_ID)\n }\n\n return getUserApplication({appId, isSdkApp: true})\n }\n\n if (!cliConfig.studioHost && !cliConfig.deployment?.appId) {\n throw new Error(NO_APP_ID_OR_STUDIO_HOST)\n }\n\n if (!projectId) {\n throw new Error(NO_PROJECT_ID)\n }\n\n return getUserApplication({\n appHost: cliConfig.studioHost,\n appId: cliConfig.deployment?.appId,\n isSdkApp: false,\n projectId,\n })\n}\n"],"names":["getUserApplication","getAppId","determineIsApp","NO_PROJECT_ID","NO_APP_ID","NO_APP_ID_OR_STUDIO_HOST","getStudioOrAppUserApplication","options","cliConfig","projectId","api","isApp","appId","Error","isSdkApp","studioHost","deployment","appHost"],"mappings":"AAEA,SAAQA,kBAAkB,QAAO,qCAAoC;AACrE,SAAQC,QAAQ,QAAO,sBAAqB;AAC5C,SAAQC,cAAc,QAAO,+BAA8B;AAC3D,SAAQC,aAAa,QAAO,8BAA6B;AAOzD,OAAO,MAAMC,YAAY,YAAW;AACpC,OAAO,MAAMC,2BAA2B,2BAA0B;AAElE,6BAA6B;AAC7B,OAAO,eAAeC,8BAA8BC,OAA6C;IAC/F,MAAM,EAACC,SAAS,EAAC,GAAGD;IACpB,MAAME,YAAYD,UAAUE,GAAG,EAAED;IACjC,MAAME,QAAQT,eAAeM;IAE7B,IAAIG,OAAO;QACT,MAAMC,QAAQX,SAASO;QACvB,IAAI,CAACI,OAAO;YACV,MAAM,IAAIC,MAAMT;QAClB;QAEA,OAAOJ,mBAAmB;YAACY;YAAOE,UAAU;QAAI;IAClD;IAEA,IAAI,CAACN,UAAUO,UAAU,IAAI,CAACP,UAAUQ,UAAU,EAAEJ,OAAO;QACzD,MAAM,IAAIC,MAAMR;IAClB;IAEA,IAAI,CAACI,WAAW;QACd,MAAM,IAAII,MAAMV;IAClB;IAEA,OAAOH,mBAAmB;QACxBiB,SAAST,UAAUO,UAAU;QAC7BH,OAAOJ,UAAUQ,UAAU,EAAEJ;QAC7BE,UAAU;QACVL;IACF;AACF"}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { getModuleUrl } from '@sanity/cli-build/_internal/build';
|
|
3
|
-
import { getLocalPackageVersion, readPackageJson } from '@sanity/cli-core';
|
|
4
|
-
import { createRequester } from '@sanity/cli-core/request';
|
|
5
|
-
import { coerce, eq, prerelease, parse as semverParse } from 'semver';
|
|
6
|
-
const defaultRequester = createRequester({
|
|
7
|
-
middleware: {
|
|
8
|
-
httpErrors: false,
|
|
9
|
-
promise: {
|
|
10
|
-
onlyBody: false
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
/**
|
|
15
|
-
* @internal
|
|
16
|
-
*
|
|
17
|
-
* Compares the versions of dependencies in the studio or app with their remote versions.
|
|
18
|
-
*
|
|
19
|
-
* This function reads the package.json file in the provided working directory, and compares the versions of the dependencies
|
|
20
|
-
* specified in the `autoUpdatesImports` parameter with their remote versions. If the versions do not match, the dependency is
|
|
21
|
-
* added to a list of failed dependencies, which is returned by the function.
|
|
22
|
-
*
|
|
23
|
-
* The failed dependencies are anything that does not strictly match the remote version.
|
|
24
|
-
* This means that if a version is lower or greater by even a patch it will be marked as failed.
|
|
25
|
-
*
|
|
26
|
-
* @param packages - An array of packages with their name and version to compare against remote.
|
|
27
|
-
* @param workDir - The path to the working directory containing the package.json file.
|
|
28
|
-
* @param options - Optional configuration for version comparison.
|
|
29
|
-
*
|
|
30
|
-
* @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ)
|
|
31
|
-
* and `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely).
|
|
32
|
-
*
|
|
33
|
-
* @throws Throws an error if the remote version of a non-prerelease package cannot be fetched, or if the local version
|
|
34
|
-
* of a package cannot be parsed.
|
|
35
|
-
*/ export async function compareDependencyVersions(packages, workDir, { appId, requester = defaultRequester } = {}) {
|
|
36
|
-
const manifest = await readPackageJson(path.join(workDir, 'package.json'), {
|
|
37
|
-
skipSchemaValidation: true
|
|
38
|
-
});
|
|
39
|
-
const dependencies = {
|
|
40
|
-
...manifest?.dependencies,
|
|
41
|
-
...manifest?.devDependencies
|
|
42
|
-
};
|
|
43
|
-
const mismatched = [];
|
|
44
|
-
const unresolvedPrerelease = [];
|
|
45
|
-
for (const pkg of packages){
|
|
46
|
-
// Skip packages that are not declared in the local package.json
|
|
47
|
-
if (!dependencies[pkg.name]) {
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
const resolvedVersion = await getRemoteResolvedVersion(getModuleUrl(pkg, {
|
|
51
|
-
appId
|
|
52
|
-
}), requester);
|
|
53
|
-
if (resolvedVersion === null) {
|
|
54
|
-
if (prerelease(pkg.version)) {
|
|
55
|
-
unresolvedPrerelease.push({
|
|
56
|
-
pkg: pkg.name,
|
|
57
|
-
version: pkg.version
|
|
58
|
-
});
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
throw new Error(`Failed to resolve remote version for ${pkg.name}@${pkg.version}: package not found`);
|
|
62
|
-
}
|
|
63
|
-
const packageVersion = await getLocalPackageVersion(pkg.name, workDir);
|
|
64
|
-
const manifestVersion = dependencies[pkg.name];
|
|
65
|
-
const installed = coerce(packageVersion ? semverParse(packageVersion) : coerce(manifestVersion));
|
|
66
|
-
if (!installed) {
|
|
67
|
-
throw new Error(`Failed to parse installed version for ${pkg.name}`);
|
|
68
|
-
}
|
|
69
|
-
if (!eq(resolvedVersion, installed.version)) {
|
|
70
|
-
mismatched.push({
|
|
71
|
-
installed: installed.version,
|
|
72
|
-
pkg: pkg.name,
|
|
73
|
-
remote: resolvedVersion
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return {
|
|
78
|
-
mismatched,
|
|
79
|
-
unresolvedPrerelease
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
async function getRemoteResolvedVersion(url, request) {
|
|
83
|
-
let response;
|
|
84
|
-
try {
|
|
85
|
-
response = await request({
|
|
86
|
-
maxRedirects: 0,
|
|
87
|
-
method: 'HEAD',
|
|
88
|
-
url
|
|
89
|
-
});
|
|
90
|
-
} catch (err) {
|
|
91
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
92
|
-
throw new Error(`Failed to fetch remote version for ${url}: ${message}`, {
|
|
93
|
-
cause: err
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
// 302 is expected, but lets also handle 2xx
|
|
97
|
-
if (response.statusCode < 400) {
|
|
98
|
-
const resolved = response.headers['x-resolved-version'];
|
|
99
|
-
if (!resolved) {
|
|
100
|
-
throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`);
|
|
101
|
-
}
|
|
102
|
-
return resolved;
|
|
103
|
-
}
|
|
104
|
-
if (response.statusCode === 404) {
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
throw new Error(`Unexpected HTTP response: ${response.statusCode} ${response.statusMessage}`);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
//# sourceMappingURL=compareDependencyVersions.js.map
|