@sanity/cli 8.20.0 → 8.22.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 +106 -47
- package/codemods/dashboard.js +111 -0
- package/dist/actions/build/buildApp.js +1 -1
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStudio.js +1 -1
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/codemods/dashboard.js +113 -0
- package/dist/actions/codemods/dashboard.js.map +1 -0
- package/dist/actions/codemods/index.js +2 -0
- package/dist/actions/codemods/index.js.map +1 -1
- package/dist/actions/codemods/types.js.map +1 -1
- package/dist/actions/deploy/deployApp.js +13 -6
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployChecks.js +12 -7
- package/dist/actions/deploy/deployChecks.js.map +1 -1
- package/dist/actions/deploy/deployRunner.js +14 -8
- package/dist/actions/deploy/deployRunner.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +39 -4
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/resolveDeployTarget.js +7 -6
- package/dist/actions/deploy/resolveDeployTarget.js.map +1 -1
- package/dist/actions/init/project/promptForAppTemplateSetup.js +22 -0
- package/dist/actions/init/project/promptForAppTemplateSetup.js.map +1 -1
- package/dist/actions/schema/listSchemas.js +2 -3
- package/dist/actions/schema/listSchemas.js.map +1 -1
- package/dist/actions/tokens/formatTokenAccess.js +18 -0
- package/dist/actions/tokens/formatTokenAccess.js.map +1 -0
- package/dist/actions/tokens/grants.js +12 -0
- package/dist/actions/tokens/grants.js.map +1 -1
- package/dist/actions/tokens/types.js.map +1 -1
- package/dist/actions/typegen/generateResourceTypes.js +11 -8
- package/dist/actions/typegen/generateResourceTypes.js.map +1 -1
- package/dist/actions/typegen/watchResourceTypes.js +208 -0
- package/dist/actions/typegen/watchResourceTypes.js.map +1 -0
- package/dist/actions/undeploy/runUndeploy.js +14 -8
- package/dist/actions/undeploy/runUndeploy.js.map +1 -1
- package/dist/commands/codemod.js +15 -4
- package/dist/commands/codemod.js.map +1 -1
- package/dist/commands/context/get.js +3 -8
- package/dist/commands/context/get.js.map +1 -1
- package/dist/commands/context/imports/download.js +3 -8
- package/dist/commands/context/imports/download.js.map +1 -1
- package/dist/commands/context/imports/get.js +3 -8
- package/dist/commands/context/imports/get.js.map +1 -1
- package/dist/commands/context/imports/list.js +3 -8
- package/dist/commands/context/imports/list.js.map +1 -1
- package/dist/commands/context/jobs/get.js +8 -8
- package/dist/commands/context/jobs/get.js.map +1 -1
- package/dist/commands/context/list.js +2 -6
- package/dist/commands/context/list.js.map +1 -1
- package/dist/commands/deploy.js +1 -0
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/doctor.js +2 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/openapi/list.js +2 -4
- package/dist/commands/openapi/list.js.map +1 -1
- package/dist/commands/projects/create.js +3 -6
- package/dist/commands/projects/create.js.map +1 -1
- package/dist/commands/schemas/list.js +1 -3
- package/dist/commands/schemas/list.js.map +1 -1
- package/dist/commands/tokens/create.js +2 -5
- package/dist/commands/tokens/create.js.map +1 -1
- package/dist/commands/tokens/delete.js +38 -30
- package/dist/commands/tokens/delete.js.map +1 -1
- package/dist/commands/tokens/list.js +27 -25
- package/dist/commands/tokens/list.js.map +1 -1
- package/dist/commands/tokens/rotate.js +2 -5
- package/dist/commands/tokens/rotate.js.map +1 -1
- package/dist/commands/typegen/generate.js +83 -45
- package/dist/commands/typegen/generate.js.map +1 -1
- package/dist/commands/undeploy.js +1 -0
- package/dist/commands/undeploy.js.map +1 -1
- package/dist/commands/whoami.js +5 -11
- package/dist/commands/whoami.js.map +1 -1
- package/dist/exports/invokeSanityCli/index.js +26 -6
- package/dist/exports/invokeSanityCli/index.js.map +1 -1
- package/dist/generated/apiRoutes.js +11 -26
- package/dist/generated/apiRoutes.js.map +1 -1
- package/dist/services/tokens.js +32 -22
- package/dist/services/tokens.js.map +1 -1
- package/dist/telemetry/init.telemetry.js.map +1 -1
- package/dist/util/resolveTokenScope.js +24 -0
- package/dist/util/resolveTokenScope.js.map +1 -0
- package/oclif.manifest.json +2027 -1964
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/tokens/delete.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {requiredWhenUnattended} from '@sanity/cli-core/flags'\nimport {confirm, select} from '@sanity/cli-core/ux'\nimport {ClientError} from '@sanity/client'\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/tokens/delete.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {requiredWhenUnattended} from '@sanity/cli-core/flags'\nimport {confirm, select} from '@sanity/cli-core/ux'\nimport {ClientError} from '@sanity/client'\n\nimport {formatTokenAccess} from '../../actions/tokens/formatTokenAccess.js'\nimport {type TokenScope} from '../../actions/tokens/types.js'\nimport {deleteToken, getTokens} from '../../services/tokens.js'\nimport {formatCliErrorMessages} from '../../util/formatCliErrorMessages.js'\nimport {resolveTokenScope} from '../../util/resolveTokenScope.js'\nimport {getOrganizationFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst deleteTokenDebug = subdebug('tokens:delete')\n\nexport class DeleteTokensCommand extends SanityCommand<typeof DeleteTokensCommand> {\n static override args = {\n tokenId: Args.string({\n description: 'Token ID to delete (will prompt if not provided)',\n required: false,\n }),\n }\n\n static override description = 'Delete an API token from a project or organization'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> --organization org123',\n description: 'Interactively select and delete an organization token',\n },\n {\n command: '<%= config.bin %> <%= command.id %> silJ2lFmK6dONB --organization org123 --yes',\n description: 'Delete an organization token without confirmation',\n },\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Interactively select and delete a token',\n },\n {\n command: '<%= config.bin %> <%= command.id %> silJ2lFmK6dONB',\n description: 'Delete a specific token by ID',\n },\n {\n command: '<%= config.bin %> <%= command.id %> silJ2lFmK6dONB --yes',\n description: 'Delete a specific token without confirmation prompt',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --project-id abc123',\n description: 'Delete a token from a specific project',\n },\n ]\n\n static override flags = {\n ...getOrganizationFlag({\n description: 'Delete a token managed by this organization',\n exclusive: ['project-id'],\n semantics: 'specify',\n }),\n ...getProjectIdFlag({\n description: 'Project ID to delete token from',\n semantics: 'override',\n }),\n yes: requiredWhenUnattended(\n Flags.boolean({\n char: 'y',\n description: 'Skip confirmation prompt (unattended mode)',\n }),\n ),\n }\n\n static override hiddenAliases: string[] = ['token:delete']\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(DeleteTokensCommand)\n\n const skipConfirmation = flags.yes\n const unattended = this.isUnattended()\n const {tokenId: givenTokenId} = args\n\n if (unattended) {\n const errors: string[] = []\n\n if (!givenTokenId) {\n errors.push('Token ID is required. Pass it as the `<tokenId>` argument.')\n }\n if (errors.length > 0) {\n this.error(formatCliErrorMessages(errors), {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n }\n\n const scope = await resolveTokenScope({\n getProjectId: this.getProjectId.bind(this),\n grant: 'delete',\n organization: flags.organization,\n })\n\n const tokenId = givenTokenId || (await this.getTokenIdFromList(scope))\n\n if (!skipConfirmation) {\n const confirmed = await confirm({\n default: false,\n message:\n scope.resourceType === 'organization'\n ? `Delete API token \"${tokenId}\" from organization \"${scope.resourceId}\"? This revokes all of its organization and project access.`\n : `Delete API token \"${tokenId}\"?`,\n })\n\n if (!confirmed) {\n this.log('API token not deleted')\n this.exit(exitCodes.USER_ABORT)\n }\n }\n\n try {\n await deleteToken(scope, tokenId)\n\n this.log('API token deleted')\n } catch (error) {\n if (error instanceof ClientError && error.response.statusCode === 404) {\n this.error(`Token with ID \"${tokenId}\" not found`, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n const err = error as Error\n deleteTokenDebug(`Error deleting token`, err)\n this.error(`Token deletion failed:\\n${err.message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n private async getTokenIdFromList(scope: TokenScope) {\n let tokens: Awaited<ReturnType<typeof getTokens>>\n try {\n tokens = await getTokens(scope)\n } catch (error) {\n const err = error as Error\n deleteTokenDebug(`Error fetching tokens for ${scope.resourceType} ${scope.resourceId}`, err)\n this.error(\n `Could not list API tokens:\\n${err.message}\\nCheck the ${scope.resourceType} ID and your access permissions, then try again.`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n\n if (tokens.length === 0) {\n this.error(`No API tokens found for this ${scope.resourceType}.`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n const choices = tokens.map((token) => {\n const access = formatTokenAccess(token, scope)\n return {name: `${token.label} [${token.id}] (${access})`, value: token.id}\n })\n\n return select({\n choices,\n message: 'Select token to delete:',\n })\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","requiredWhenUnattended","confirm","select","ClientError","formatTokenAccess","deleteToken","getTokens","formatCliErrorMessages","resolveTokenScope","getOrganizationFlag","getProjectIdFlag","deleteTokenDebug","DeleteTokensCommand","args","tokenId","string","description","required","examples","command","flags","exclusive","semantics","yes","boolean","char","hiddenAliases","run","parse","skipConfirmation","unattended","isUnattended","givenTokenId","errors","push","length","error","exit","USAGE_ERROR","scope","getProjectId","bind","grant","organization","getTokenIdFromList","confirmed","default","message","resourceType","resourceId","log","USER_ABORT","response","statusCode","RUNTIME_ERROR","err","tokens","choices","map","token","access","name","label","id","value"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,sBAAsB,QAAO,yBAAwB;AAC7D,SAAQC,OAAO,EAAEC,MAAM,QAAO,sBAAqB;AACnD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,iBAAiB,QAAO,4CAA2C;AAE3E,SAAQC,WAAW,EAAEC,SAAS,QAAO,2BAA0B;AAC/D,SAAQC,sBAAsB,QAAO,uCAAsC;AAC3E,SAAQC,iBAAiB,QAAO,kCAAiC;AACjE,SAAQC,mBAAmB,EAAEC,gBAAgB,QAAO,4BAA2B;AAE/E,MAAMC,mBAAmBZ,SAAS;AAElC,OAAO,MAAMa,4BAA4Bd;IACvC,OAAgBe,OAAO;QACrBC,SAASnB,KAAKoB,MAAM,CAAC;YACnBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,qDAAoD;IAElF,OAAgBE,WAAW;QACzB;YACEC,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IAED,OAAgBI,QAAQ;QACtB,GAAGX,oBAAoB;YACrBO,aAAa;YACbK,WAAW;gBAAC;aAAa;YACzBC,WAAW;QACb,EAAE;QACF,GAAGZ,iBAAiB;YAClBM,aAAa;YACbM,WAAW;QACb,EAAE;QACFC,KAAKvB,uBACHJ,MAAM4B,OAAO,CAAC;YACZC,MAAM;YACNT,aAAa;QACf;IAEJ,EAAC;IAED,OAAgBU,gBAA0B;QAAC;KAAe,CAAA;IAE1D,MAAaC,MAAqB;QAChC,MAAM,EAACd,IAAI,EAAEO,KAAK,EAAC,GAAG,MAAM,IAAI,CAACQ,KAAK,CAAChB;QAEvC,MAAMiB,mBAAmBT,MAAMG,GAAG;QAClC,MAAMO,aAAa,IAAI,CAACC,YAAY;QACpC,MAAM,EAACjB,SAASkB,YAAY,EAAC,GAAGnB;QAEhC,IAAIiB,YAAY;YACd,MAAMG,SAAmB,EAAE;YAE3B,IAAI,CAACD,cAAc;gBACjBC,OAAOC,IAAI,CAAC;YACd;YACA,IAAID,OAAOE,MAAM,GAAG,GAAG;gBACrB,IAAI,CAACC,KAAK,CAAC7B,uBAAuB0B,SAAS;oBACzCI,MAAMxC,UAAUyC,WAAW;gBAC7B;YACF;QACF;QAEA,MAAMC,QAAQ,MAAM/B,kBAAkB;YACpCgC,cAAc,IAAI,CAACA,YAAY,CAACC,IAAI,CAAC,IAAI;YACzCC,OAAO;YACPC,cAAcvB,MAAMuB,YAAY;QAClC;QAEA,MAAM7B,UAAUkB,gBAAiB,MAAM,IAAI,CAACY,kBAAkB,CAACL;QAE/D,IAAI,CAACV,kBAAkB;YACrB,MAAMgB,YAAY,MAAM5C,QAAQ;gBAC9B6C,SAAS;gBACTC,SACER,MAAMS,YAAY,KAAK,iBACnB,CAAC,kBAAkB,EAAElC,QAAQ,qBAAqB,EAAEyB,MAAMU,UAAU,CAAC,2DAA2D,CAAC,GACjI,CAAC,kBAAkB,EAAEnC,QAAQ,EAAE,CAAC;YACxC;YAEA,IAAI,CAAC+B,WAAW;gBACd,IAAI,CAACK,GAAG,CAAC;gBACT,IAAI,CAACb,IAAI,CAACxC,UAAUsD,UAAU;YAChC;QACF;QAEA,IAAI;YACF,MAAM9C,YAAYkC,OAAOzB;YAEzB,IAAI,CAACoC,GAAG,CAAC;QACX,EAAE,OAAOd,OAAO;YACd,IAAIA,iBAAiBjC,eAAeiC,MAAMgB,QAAQ,CAACC,UAAU,KAAK,KAAK;gBACrE,IAAI,CAACjB,KAAK,CAAC,CAAC,eAAe,EAAEtB,QAAQ,WAAW,CAAC,EAAE;oBAACuB,MAAMxC,UAAUyD,aAAa;gBAAA;YACnF;YAEA,MAAMC,MAAMnB;YACZzB,iBAAiB,CAAC,oBAAoB,CAAC,EAAE4C;YACzC,IAAI,CAACnB,KAAK,CAAC,CAAC,wBAAwB,EAAEmB,IAAIR,OAAO,EAAE,EAAE;gBAACV,MAAMxC,UAAUyD,aAAa;YAAA;QACrF;IACF;IAEA,MAAcV,mBAAmBL,KAAiB,EAAE;QAClD,IAAIiB;QACJ,IAAI;YACFA,SAAS,MAAMlD,UAAUiC;QAC3B,EAAE,OAAOH,OAAO;YACd,MAAMmB,MAAMnB;YACZzB,iBAAiB,CAAC,0BAA0B,EAAE4B,MAAMS,YAAY,CAAC,CAAC,EAAET,MAAMU,UAAU,EAAE,EAAEM;YACxF,IAAI,CAACnB,KAAK,CACR,CAAC,4BAA4B,EAAEmB,IAAIR,OAAO,CAAC,YAAY,EAAER,MAAMS,YAAY,CAAC,gDAAgD,CAAC,EAC7H;gBAACX,MAAMxC,UAAUyD,aAAa;YAAA;QAElC;QAEA,IAAIE,OAAOrB,MAAM,KAAK,GAAG;YACvB,IAAI,CAACC,KAAK,CAAC,CAAC,6BAA6B,EAAEG,MAAMS,YAAY,CAAC,CAAC,CAAC,EAAE;gBAChEX,MAAMxC,UAAUyD,aAAa;YAC/B;QACF;QAEA,MAAMG,UAAUD,OAAOE,GAAG,CAAC,CAACC;YAC1B,MAAMC,SAASxD,kBAAkBuD,OAAOpB;YACxC,OAAO;gBAACsB,MAAM,GAAGF,MAAMG,KAAK,CAAC,EAAE,EAAEH,MAAMI,EAAE,CAAC,GAAG,EAAEH,OAAO,CAAC,CAAC;gBAAEI,OAAOL,MAAMI,EAAE;YAAA;QAC3E;QAEA,OAAO7D,OAAO;YACZuD;YACAV,SAAS;QACX;IACF;AACF"}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import { Flags } from '@oclif/core';
|
|
2
1
|
import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
|
|
3
2
|
import { getErrorMessage } from '@sanity/cli-core/errors';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { formatTokenAccess } from '../../actions/tokens/formatTokenAccess.js';
|
|
4
|
+
import { getTokens } from '../../services/tokens.js';
|
|
5
|
+
import { resolveTokenScope } from '../../util/resolveTokenScope.js';
|
|
6
6
|
import { Table } from '../../util/responsiveTable.js';
|
|
7
|
-
import { getProjectIdFlag } from '../../util/sharedFlags.js';
|
|
7
|
+
import { getOrganizationFlag, getProjectIdFlag } from '../../util/sharedFlags.js';
|
|
8
8
|
const listTokenDebug = subdebug('tokens:list');
|
|
9
9
|
export class TokensListCommand extends SanityCommand {
|
|
10
|
-
static description = 'List API tokens for
|
|
10
|
+
static description = 'List API tokens for a project or organization';
|
|
11
|
+
static enableJsonFlag = true;
|
|
11
12
|
static examples = [
|
|
13
|
+
{
|
|
14
|
+
command: '<%= config.bin %> <%= command.id %> --organization org123',
|
|
15
|
+
description: 'List tokens managed by an organization'
|
|
16
|
+
},
|
|
12
17
|
{
|
|
13
18
|
command: '<%= config.bin %> <%= command.id %>',
|
|
14
19
|
description: 'List tokens for the project'
|
|
@@ -23,13 +28,16 @@ export class TokensListCommand extends SanityCommand {
|
|
|
23
28
|
}
|
|
24
29
|
];
|
|
25
30
|
static flags = {
|
|
31
|
+
...getOrganizationFlag({
|
|
32
|
+
description: 'List tokens managed by this organization',
|
|
33
|
+
exclusive: [
|
|
34
|
+
'project-id'
|
|
35
|
+
],
|
|
36
|
+
semantics: 'specify'
|
|
37
|
+
}),
|
|
26
38
|
...getProjectIdFlag({
|
|
27
39
|
description: 'Project ID to list tokens for',
|
|
28
40
|
semantics: 'override'
|
|
29
|
-
}),
|
|
30
|
-
json: Flags.boolean({
|
|
31
|
-
default: false,
|
|
32
|
-
description: 'Output tokens in JSON format'
|
|
33
41
|
})
|
|
34
42
|
};
|
|
35
43
|
static hiddenAliases = [
|
|
@@ -39,33 +47,27 @@ export class TokensListCommand extends SanityCommand {
|
|
|
39
47
|
const { flags } = await this.parse(TokensListCommand);
|
|
40
48
|
const { json } = flags;
|
|
41
49
|
const outputJson = json ?? false;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
{
|
|
47
|
-
grant: 'read',
|
|
48
|
-
permission: 'sanity.project.tokens'
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
})
|
|
50
|
+
const scope = await resolveTokenScope({
|
|
51
|
+
getProjectId: this.getProjectId.bind(this),
|
|
52
|
+
grant: 'read',
|
|
53
|
+
organization: flags.organization
|
|
52
54
|
});
|
|
53
55
|
let tokens;
|
|
54
56
|
try {
|
|
55
|
-
tokens = await getTokens(
|
|
57
|
+
tokens = await getTokens(scope);
|
|
56
58
|
} catch (error) {
|
|
57
59
|
const message = getErrorMessage(error);
|
|
58
|
-
listTokenDebug(`Error fetching tokens for
|
|
60
|
+
listTokenDebug(`Error fetching tokens for ${scope.resourceType} ${scope.resourceId}`, error);
|
|
59
61
|
this.error(`Token list retrieval failed:\n${message}`, {
|
|
60
62
|
exit: exitCodes.RUNTIME_ERROR
|
|
61
63
|
});
|
|
62
64
|
}
|
|
63
65
|
if (outputJson) {
|
|
64
|
-
this.
|
|
66
|
+
this.logJson(tokens);
|
|
65
67
|
return;
|
|
66
68
|
}
|
|
67
69
|
if (tokens.length === 0) {
|
|
68
|
-
this.log(
|
|
70
|
+
this.log(`No API tokens found for this ${scope.resourceType}.`);
|
|
69
71
|
return;
|
|
70
72
|
}
|
|
71
73
|
const table = new Table({
|
|
@@ -83,7 +85,7 @@ export class TokensListCommand extends SanityCommand {
|
|
|
83
85
|
{
|
|
84
86
|
alignment: 'left',
|
|
85
87
|
name: 'roles',
|
|
86
|
-
title: 'Roles'
|
|
88
|
+
title: scope.resourceType === 'organization' ? 'Access' : 'Roles'
|
|
87
89
|
},
|
|
88
90
|
{
|
|
89
91
|
alignment: 'left',
|
|
@@ -94,7 +96,7 @@ export class TokensListCommand extends SanityCommand {
|
|
|
94
96
|
title: `Found ${tokens.length} API tokens`
|
|
95
97
|
});
|
|
96
98
|
for (const token of tokens){
|
|
97
|
-
const roles =
|
|
99
|
+
const roles = formatTokenAccess(token, scope);
|
|
98
100
|
table.addRow({
|
|
99
101
|
expires: token.expiresAt ? token.expiresAt.slice(0, 10) : 'Never',
|
|
100
102
|
id: token.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/tokens/list.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/tokens/list.ts"],"sourcesContent":["import {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\n\nimport {formatTokenAccess} from '../../actions/tokens/formatTokenAccess.js'\nimport {type Robot} from '../../actions/tokens/types.js'\nimport {getTokens} from '../../services/tokens.js'\nimport {resolveTokenScope} from '../../util/resolveTokenScope.js'\nimport {Table} from '../../util/responsiveTable.js'\nimport {getOrganizationFlag, 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 a project or organization'\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> --organization org123',\n description: 'List tokens managed by an organization',\n },\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 ...getOrganizationFlag({\n description: 'List tokens managed by this organization',\n exclusive: ['project-id'],\n semantics: 'specify',\n }),\n ...getProjectIdFlag({\n description: 'Project ID to list tokens for',\n semantics: 'override',\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 const scope = await resolveTokenScope({\n getProjectId: this.getProjectId.bind(this),\n grant: 'read',\n organization: flags.organization,\n })\n\n let tokens: Robot[]\n try {\n tokens = await getTokens(scope)\n } catch (error) {\n const message = getErrorMessage(error)\n listTokenDebug(`Error fetching tokens for ${scope.resourceType} ${scope.resourceId}`, error)\n this.error(`Token list retrieval failed:\\n${message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n if (outputJson) {\n this.logJson(tokens)\n return\n }\n\n if (tokens.length === 0) {\n this.log(`No API tokens found for this ${scope.resourceType}.`)\n return\n }\n\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'label', title: 'Label'},\n {alignment: 'left', name: 'id', title: 'ID'},\n {\n alignment: 'left',\n name: 'roles',\n title: scope.resourceType === 'organization' ? 'Access' : 'Roles',\n },\n {alignment: 'left', name: 'expires', title: 'Expires'},\n ],\n title: `Found ${tokens.length} API tokens`,\n })\n\n for (const token of tokens) {\n const roles = formatTokenAccess(token, scope)\n\n table.addRow({\n expires: token.expiresAt ? token.expiresAt.slice(0, 10) : 'Never',\n id: token.id,\n label: token.label,\n roles,\n })\n }\n\n this.log(table.render())\n }\n}\n"],"names":["exitCodes","SanityCommand","subdebug","getErrorMessage","formatTokenAccess","getTokens","resolveTokenScope","Table","getOrganizationFlag","getProjectIdFlag","listTokenDebug","TokensListCommand","description","enableJsonFlag","examples","command","flags","exclusive","semantics","hiddenAliases","run","parse","json","outputJson","scope","getProjectId","bind","grant","organization","tokens","error","message","resourceType","resourceId","exit","RUNTIME_ERROR","logJson","length","log","table","columns","alignment","name","title","token","roles","addRow","expires","expiresAt","slice","id","label","render"],"mappings":"AAAA,SAAQA,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AAEvD,SAAQC,iBAAiB,QAAO,4CAA2C;AAE3E,SAAQC,SAAS,QAAO,2BAA0B;AAClD,SAAQC,iBAAiB,QAAO,kCAAiC;AACjE,SAAQC,KAAK,QAAO,gCAA+B;AACnD,SAAQC,mBAAmB,EAAEC,gBAAgB,QAAO,4BAA2B;AAE/E,MAAMC,iBAAiBR,SAAS;AAEhC,OAAO,MAAMS,0BAA0BV;IACrC,OAAgBW,cAAc,gDAA+C;IAC7E,OAAgBC,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IACD,OAAgBI,QAAQ;QACtB,GAAGR,oBAAoB;YACrBI,aAAa;YACbK,WAAW;gBAAC;aAAa;YACzBC,WAAW;QACb,EAAE;QACF,GAAGT,iBAAiB;YAClBG,aAAa;YACbM,WAAW;QACb,EAAE;IACJ,EAAC;IAED,OAAgBC,gBAA0B;QAAC;KAAa,CAAA;IAExD,MAAaC,MAAqB;QAChC,MAAM,EAACJ,KAAK,EAAC,GAAG,MAAM,IAAI,CAACK,KAAK,CAACV;QACjC,MAAM,EAACW,IAAI,EAAC,GAAGN;QACf,MAAMO,aAAaD,QAAQ;QAE3B,MAAME,QAAQ,MAAMlB,kBAAkB;YACpCmB,cAAc,IAAI,CAACA,YAAY,CAACC,IAAI,CAAC,IAAI;YACzCC,OAAO;YACPC,cAAcZ,MAAMY,YAAY;QAClC;QAEA,IAAIC;QACJ,IAAI;YACFA,SAAS,MAAMxB,UAAUmB;QAC3B,EAAE,OAAOM,OAAO;YACd,MAAMC,UAAU5B,gBAAgB2B;YAChCpB,eAAe,CAAC,0BAA0B,EAAEc,MAAMQ,YAAY,CAAC,CAAC,EAAER,MAAMS,UAAU,EAAE,EAAEH;YACtF,IAAI,CAACA,KAAK,CAAC,CAAC,8BAA8B,EAAEC,SAAS,EAAE;gBAACG,MAAMlC,UAAUmC,aAAa;YAAA;QACvF;QAEA,IAAIZ,YAAY;YACd,IAAI,CAACa,OAAO,CAACP;YACb;QACF;QAEA,IAAIA,OAAOQ,MAAM,KAAK,GAAG;YACvB,IAAI,CAACC,GAAG,CAAC,CAAC,6BAA6B,EAAEd,MAAMQ,YAAY,CAAC,CAAC,CAAC;YAC9D;QACF;QAEA,MAAMO,QAAQ,IAAIhC,MAAM;YACtBiC,SAAS;gBACP;oBAACC,WAAW;oBAAQC,MAAM;oBAASC,OAAO;gBAAO;gBACjD;oBAACF,WAAW;oBAAQC,MAAM;oBAAMC,OAAO;gBAAI;gBAC3C;oBACEF,WAAW;oBACXC,MAAM;oBACNC,OAAOnB,MAAMQ,YAAY,KAAK,iBAAiB,WAAW;gBAC5D;gBACA;oBAACS,WAAW;oBAAQC,MAAM;oBAAWC,OAAO;gBAAS;aACtD;YACDA,OAAO,CAAC,MAAM,EAAEd,OAAOQ,MAAM,CAAC,WAAW,CAAC;QAC5C;QAEA,KAAK,MAAMO,SAASf,OAAQ;YAC1B,MAAMgB,QAAQzC,kBAAkBwC,OAAOpB;YAEvCe,MAAMO,MAAM,CAAC;gBACXC,SAASH,MAAMI,SAAS,GAAGJ,MAAMI,SAAS,CAACC,KAAK,CAAC,GAAG,MAAM;gBAC1DC,IAAIN,MAAMM,EAAE;gBACZC,OAAOP,MAAMO,KAAK;gBAClBN;YACF;QACF;QAEA,IAAI,CAACP,GAAG,CAACC,MAAMa,MAAM;IACvB;AACF"}
|
|
@@ -8,6 +8,7 @@ const tokensRotateDebug = subdebug('tokens:rotate');
|
|
|
8
8
|
const TOKEN_USAGE_HINT = 'Token is required. Pipe it on standard input (`echo "$SANITY_TOKEN" | sanity tokens rotate`) to keep it out of shell history, or pass it with `--token`.';
|
|
9
9
|
export class RotateTokenCommand extends SanityCommand {
|
|
10
10
|
static description = 'Rotate an API token, replacing its secret with a new one';
|
|
11
|
+
static enableJsonFlag = true;
|
|
11
12
|
static examples = [
|
|
12
13
|
{
|
|
13
14
|
command: 'echo "$SANITY_TOKEN" | <%= config.bin %> <%= command.id %>',
|
|
@@ -23,10 +24,6 @@ export class RotateTokenCommand extends SanityCommand {
|
|
|
23
24
|
}
|
|
24
25
|
];
|
|
25
26
|
static flags = {
|
|
26
|
-
json: Flags.boolean({
|
|
27
|
-
default: false,
|
|
28
|
-
description: 'Output as JSON'
|
|
29
|
-
}),
|
|
30
27
|
token: Flags.string({
|
|
31
28
|
char: 't',
|
|
32
29
|
description: 'Token to rotate (prefer standard input to keep it out of shell history)',
|
|
@@ -44,7 +41,7 @@ export class RotateTokenCommand extends SanityCommand {
|
|
|
44
41
|
tokensRotateDebug('Rotating API token');
|
|
45
42
|
const robot = await rotateToken(token);
|
|
46
43
|
if (json) {
|
|
47
|
-
this.
|
|
44
|
+
this.logJson(robot);
|
|
48
45
|
return;
|
|
49
46
|
}
|
|
50
47
|
this.log('API token rotated');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/tokens/rotate.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {rotateToken} from '../../services/tokens.js'\nimport {readTokenFromStdin} from '../../util/readTokenFromStdin.js'\n\nconst tokensRotateDebug = subdebug('tokens:rotate')\n\nconst TOKEN_USAGE_HINT =\n 'Token is required. Pipe it on standard input (`echo \"$SANITY_TOKEN\" | sanity tokens rotate`) to keep it out of shell history, or pass it with `--token`.'\n\nexport class RotateTokenCommand extends SanityCommand<typeof RotateTokenCommand> {\n static override description = 'Rotate an API token, replacing its secret with a new one'\n\n static override examples = [\n {\n command: 'echo \"$SANITY_TOKEN\" | <%= config.bin %> <%= command.id %>',\n description: 'Rotate the token piped on standard input',\n },\n {\n command: '<%= config.bin %> <%= command.id %> < token.txt',\n description: 'Rotate a token read from a file',\n },\n {\n command: 'echo \"$SANITY_TOKEN\" | <%= config.bin %> <%= command.id %> --json',\n description: 'Output the rotated token as JSON',\n },\n ]\n\n static override flags = {\n
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/tokens/rotate.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {rotateToken} from '../../services/tokens.js'\nimport {readTokenFromStdin} from '../../util/readTokenFromStdin.js'\n\nconst tokensRotateDebug = subdebug('tokens:rotate')\n\nconst TOKEN_USAGE_HINT =\n 'Token is required. Pipe it on standard input (`echo \"$SANITY_TOKEN\" | sanity tokens rotate`) to keep it out of shell history, or pass it with `--token`.'\n\nexport class RotateTokenCommand extends SanityCommand<typeof RotateTokenCommand> {\n static override description = 'Rotate an API token, replacing its secret with a new one'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: 'echo \"$SANITY_TOKEN\" | <%= config.bin %> <%= command.id %>',\n description: 'Rotate the token piped on standard input',\n },\n {\n command: '<%= config.bin %> <%= command.id %> < token.txt',\n description: 'Rotate a token read from a file',\n },\n {\n command: 'echo \"$SANITY_TOKEN\" | <%= config.bin %> <%= command.id %> --json',\n description: 'Output the rotated token as JSON',\n },\n ]\n\n static override flags = {\n token: Flags.string({\n char: 't',\n description: 'Token to rotate (prefer standard input to keep it out of shell history)',\n helpValue: '<token>',\n }),\n }\n\n static override hiddenAliases: string[] = ['token:rotate']\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(RotateTokenCommand)\n const {json} = flags\n\n const token = flags.token?.trim() || (await this.readTokenArg())\n\n try {\n tokensRotateDebug('Rotating API token')\n const robot = await rotateToken(token)\n\n if (json) {\n this.logJson(robot)\n return\n }\n\n this.log('API token rotated')\n this.log(`Label: ${robot.label}`)\n this.log(`ID: ${robot.id}`)\n if (robot.expiresAt) {\n this.log(`Expires: ${robot.expiresAt}`)\n }\n this.log(`Token: ${robot.token}`)\n this.log('')\n this.log(\"Copy the token now. It won't be shown again.\")\n this.log('The previous token was revoked and no longer works.')\n } catch (error) {\n tokensRotateDebug('Error rotating token', error)\n\n if (isHttpError(error) && error.statusCode === 401) {\n this.error(\n 'Token is invalid, expired, or was already rotated or revoked. Check that you are passing the current token.',\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n if (isHttpError(error) && error.statusCode === 403) {\n this.error(\n 'The token is not an API token and cannot be rotated. Personal tokens are renewed by logging in again.',\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n\n this.error(`Token rotation failed:\\n${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async readTokenArg(): Promise<string> {\n let token: string\n try {\n token = await readTokenFromStdin(TOKEN_USAGE_HINT)\n } catch (error) {\n return this.error(getErrorMessage(error), {exit: exitCodes.USAGE_ERROR})\n }\n\n if (!token) {\n this.error(TOKEN_USAGE_HINT, {exit: exitCodes.USAGE_ERROR})\n }\n\n return token\n }\n}\n"],"names":["Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","rotateToken","readTokenFromStdin","tokensRotateDebug","TOKEN_USAGE_HINT","RotateTokenCommand","description","enableJsonFlag","examples","command","flags","token","string","char","helpValue","hiddenAliases","run","parse","json","trim","readTokenArg","robot","logJson","log","label","id","expiresAt","error","statusCode","exit","RUNTIME_ERROR","USAGE_ERROR"],"mappings":"AAAA,SAAQA,KAAK,QAAO,cAAa;AACjC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,WAAW,QAAO,2BAA0B;AACpD,SAAQC,kBAAkB,QAAO,mCAAkC;AAEnE,MAAMC,oBAAoBL,SAAS;AAEnC,MAAMM,mBACJ;AAEF,OAAO,MAAMC,2BAA2BR;IACtC,OAAgBS,cAAc,2DAA0D;IAExF,OAAgBC,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IAED,OAAgBI,QAAQ;QACtBC,OAAOhB,MAAMiB,MAAM,CAAC;YAClBC,MAAM;YACNP,aAAa;YACbQ,WAAW;QACb;IACF,EAAC;IAED,OAAgBC,gBAA0B;QAAC;KAAe,CAAA;IAE1D,MAAaC,MAAqB;QAChC,MAAM,EAACN,KAAK,EAAC,GAAG,MAAM,IAAI,CAACO,KAAK,CAACZ;QACjC,MAAM,EAACa,IAAI,EAAC,GAAGR;QAEf,MAAMC,QAAQD,MAAMC,KAAK,EAAEQ,UAAW,MAAM,IAAI,CAACC,YAAY;QAE7D,IAAI;YACFjB,kBAAkB;YAClB,MAAMkB,QAAQ,MAAMpB,YAAYU;YAEhC,IAAIO,MAAM;gBACR,IAAI,CAACI,OAAO,CAACD;gBACb;YACF;YAEA,IAAI,CAACE,GAAG,CAAC;YACT,IAAI,CAACA,GAAG,CAAC,CAAC,OAAO,EAAEF,MAAMG,KAAK,EAAE;YAChC,IAAI,CAACD,GAAG,CAAC,CAAC,IAAI,EAAEF,MAAMI,EAAE,EAAE;YAC1B,IAAIJ,MAAMK,SAAS,EAAE;gBACnB,IAAI,CAACH,GAAG,CAAC,CAAC,SAAS,EAAEF,MAAMK,SAAS,EAAE;YACxC;YACA,IAAI,CAACH,GAAG,CAAC,CAAC,OAAO,EAAEF,MAAMV,KAAK,EAAE;YAChC,IAAI,CAACY,GAAG,CAAC;YACT,IAAI,CAACA,GAAG,CAAC;YACT,IAAI,CAACA,GAAG,CAAC;QACX,EAAE,OAAOI,OAAO;YACdxB,kBAAkB,wBAAwBwB;YAE1C,IAAI3B,YAAY2B,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CACR,+GACA;oBAACE,MAAMjC,UAAUkC,aAAa;gBAAA;YAElC;YACA,IAAI9B,YAAY2B,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CACR,yGACA;oBAACE,MAAMjC,UAAUkC,aAAa;gBAAA;YAElC;YAEA,IAAI,CAACH,KAAK,CAAC,CAAC,wBAAwB,EAAE5B,gBAAgB4B,QAAQ,EAAE;gBAC9DE,MAAMjC,UAAUkC,aAAa;YAC/B;QACF;IACF;IAEA,MAAcV,eAAgC;QAC5C,IAAIT;QACJ,IAAI;YACFA,QAAQ,MAAMT,mBAAmBE;QACnC,EAAE,OAAOuB,OAAO;YACd,OAAO,IAAI,CAACA,KAAK,CAAC5B,gBAAgB4B,QAAQ;gBAACE,MAAMjC,UAAUmC,WAAW;YAAA;QACxE;QAEA,IAAI,CAACpB,OAAO;YACV,IAAI,CAACgB,KAAK,CAACvB,kBAAkB;gBAACyB,MAAMjC,UAAUmC,WAAW;YAAA;QAC3D;QAEA,OAAOpB;IACT;AACF"}
|
|
@@ -12,6 +12,7 @@ import { generateResourceTypes, resolveResourceSchemas } from '../../actions/typ
|
|
|
12
12
|
import { parseTypegenConfig } from '../../actions/typegen/parseTypegenConfig.js';
|
|
13
13
|
import { parseTypegenResources } from '../../actions/typegen/parseTypegenResources.js';
|
|
14
14
|
import { createTypegenProgressRenderer } from '../../actions/typegen/renderTypegenProgress.js';
|
|
15
|
+
import { watchResourceTypes } from '../../actions/typegen/watchResourceTypes.js';
|
|
15
16
|
const description = `Sanity TypeGen
|
|
16
17
|
|
|
17
18
|
${styleText('bold', 'Configuration:')}
|
|
@@ -30,7 +31,7 @@ The default configuration values listed above are used if not overridden in your
|
|
|
30
31
|
|
|
31
32
|
${styleText('bold', 'Note:')}
|
|
32
33
|
- The \`sanity schema extract\` command is a prerequisite for extracting your Sanity Studio schema into a \`schema.json\` file, which is then used by the \`sanity typegen generate\` command to generate type definitions.
|
|
33
|
-
- To generate types for several datasets, list them in \`typegen.resources\` in \`sanity.cli.ts\` (beta). Each resource uses its own \`schema\` file, or the schema bound to its dataset when \`schema\` is omitted.`.trim();
|
|
34
|
+
- To generate types for several datasets, list them in \`typegen.resources\` in \`sanity.cli.ts\` (beta). Each resource uses its own \`schema\` file, or the schema bound to its dataset when \`schema\` is omitted. With \`--watch\`, a schema bound to a dataset is fetched once, when the watcher starts. Restart it after deploying a schema.`.trim();
|
|
34
35
|
export class TypegenGenerateCommand extends SanityCommand {
|
|
35
36
|
static description = description;
|
|
36
37
|
static examples = [
|
|
@@ -131,6 +132,25 @@ export class TypegenGenerateCommand extends SanityCommand {
|
|
|
131
132
|
});
|
|
132
133
|
}
|
|
133
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Prints the resources' configuration warnings, then locates every resource's schema, reporting
|
|
137
|
+
* each one on the spinner.
|
|
138
|
+
*/ async resolveResources(resources, spin, workDir, { checkSchemaFiles }) {
|
|
139
|
+
for (const warning of resources.warnings){
|
|
140
|
+
this.output.warn(warning);
|
|
141
|
+
}
|
|
142
|
+
return resolveResourceSchemas({
|
|
143
|
+
checkSchemaFiles,
|
|
144
|
+
onResolved: (entry)=>{
|
|
145
|
+
spin.succeed('schemaPath' in entry ? `Using ${formatPath(entry.schemaPath)} for ${entry.key}` : `Fetched the schema bound to ${entry.key} (${entry.schemaVersion})`);
|
|
146
|
+
},
|
|
147
|
+
onResolving: (resource, key)=>{
|
|
148
|
+
spin.start(resource.schema === undefined ? `Fetching the schema bound to ${key}…` : `Checking the schema file for ${key}…`);
|
|
149
|
+
},
|
|
150
|
+
resources: resources.resources,
|
|
151
|
+
workDir
|
|
152
|
+
});
|
|
153
|
+
}
|
|
134
154
|
async runSingle() {
|
|
135
155
|
const trace = this.telemetry.trace(TypesGeneratedTrace);
|
|
136
156
|
let spin;
|
|
@@ -138,31 +158,14 @@ export class TypegenGenerateCommand extends SanityCommand {
|
|
|
138
158
|
const { config: typegenConfig, resources, type: typegenConfigMethod, workDir } = await this.getConfig();
|
|
139
159
|
trace.start();
|
|
140
160
|
if (resources) {
|
|
141
|
-
for (const warning of resources.warnings){
|
|
142
|
-
this.output.warn(warning);
|
|
143
|
-
}
|
|
144
161
|
const resourceSpin = spinner({});
|
|
145
162
|
spin = resourceSpin;
|
|
146
|
-
const resolved = await
|
|
147
|
-
|
|
148
|
-
resourceSpin.succeed('schemaPath' in entry ? `Using ${formatPath(entry.schemaPath)} for ${entry.key}` : `Fetched the schema bound to ${entry.key} (${entry.schemaVersion})`);
|
|
149
|
-
},
|
|
150
|
-
onResolving: (resource, key)=>{
|
|
151
|
-
resourceSpin.start(resource.schema === undefined ? `Fetching the schema bound to ${key}…` : `Checking the schema file for ${key}…`);
|
|
152
|
-
},
|
|
153
|
-
resources: resources.resources,
|
|
154
|
-
workDir
|
|
163
|
+
const resolved = await this.resolveResources(resources, resourceSpin, workDir, {
|
|
164
|
+
checkSchemaFiles: true
|
|
155
165
|
});
|
|
156
166
|
const results = await generateResourceTypes({
|
|
157
167
|
config: typegenConfig,
|
|
158
|
-
onProgress: (
|
|
159
|
-
resourceSpin.start(`Generating types for ${entry.key}…`);
|
|
160
|
-
return createTypegenProgressRenderer(resourceSpin, {
|
|
161
|
-
formatGeneratedCode: typegenConfig.formatGeneratedCode,
|
|
162
|
-
generates: entry.resource.generates,
|
|
163
|
-
schema: 'schemaPath' in entry ? entry.schemaPath : entry.key
|
|
164
|
-
});
|
|
165
|
-
},
|
|
168
|
+
onProgress: createResourceProgressHandler(resourceSpin, typegenConfig),
|
|
166
169
|
resolved,
|
|
167
170
|
workDir
|
|
168
171
|
});
|
|
@@ -208,36 +211,14 @@ export class TypegenGenerateCommand extends SanityCommand {
|
|
|
208
211
|
let spin;
|
|
209
212
|
try {
|
|
210
213
|
const { config: typegenConfig, resources, workDir } = await this.getConfig();
|
|
211
|
-
if (resources) {
|
|
212
|
-
this.error('Watch mode does not support typegen.resources yet. Run "sanity typegen generate" without --watch.', {
|
|
213
|
-
exit: exitCodes.USAGE_ERROR
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
214
|
trace.start();
|
|
217
215
|
let resolve = ()=>{};
|
|
218
216
|
const promise = new Promise((res)=>{
|
|
219
217
|
resolve = res;
|
|
220
218
|
});
|
|
221
|
-
const watchSpin = spinner({})
|
|
219
|
+
const watchSpin = spinner({});
|
|
222
220
|
spin = watchSpin;
|
|
223
|
-
const
|
|
224
|
-
formatGeneratedCode: typegenConfig.formatGeneratedCode,
|
|
225
|
-
generates: typegenConfig.generates,
|
|
226
|
-
schema: typegenConfig.schema
|
|
227
|
-
};
|
|
228
|
-
let renderProgress = createTypegenProgressRenderer(watchSpin, rendererContext);
|
|
229
|
-
const typegenWatcher = runTypegenWatcher({
|
|
230
|
-
config: typegenConfig,
|
|
231
|
-
onProgress: (event)=>{
|
|
232
|
-
// 'schemaLoaded' is the first event of every generation cycle; the
|
|
233
|
-
// renderer accumulates per-run state, so start each cycle fresh.
|
|
234
|
-
if (event.type === 'schemaLoaded') {
|
|
235
|
-
renderProgress = createTypegenProgressRenderer(watchSpin, rendererContext);
|
|
236
|
-
}
|
|
237
|
-
renderProgress(event);
|
|
238
|
-
},
|
|
239
|
-
workDir
|
|
240
|
-
});
|
|
221
|
+
const typegenWatcher = resources ? await this.startResourceWatcher(typegenConfig, resources, watchSpin, workDir) : this.startSchemaWatcher(typegenConfig, watchSpin, workDir);
|
|
241
222
|
const stop = once(async ()=>{
|
|
242
223
|
process.off('SIGINT', stop);
|
|
243
224
|
process.off('SIGTERM', stop);
|
|
@@ -272,6 +253,63 @@ export class TypegenGenerateCommand extends SanityCommand {
|
|
|
272
253
|
});
|
|
273
254
|
}
|
|
274
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* Locates every resource's schema once, then generates on each query or local schema change.
|
|
258
|
+
* A schema bound to a dataset is fetched only here, so a schema deployed while the watcher runs
|
|
259
|
+
* is used after a restart.
|
|
260
|
+
*/ async startResourceWatcher(config, resources, spin, workDir) {
|
|
261
|
+
// A missing local schema file fails that resource's generation until the file appears,
|
|
262
|
+
// instead of ending the watcher.
|
|
263
|
+
const resolved = await this.resolveResources(resources, spin, workDir, {
|
|
264
|
+
checkSchemaFiles: false
|
|
265
|
+
});
|
|
266
|
+
return watchResourceTypes({
|
|
267
|
+
config,
|
|
268
|
+
onChange: (event, relativePath)=>{
|
|
269
|
+
this.output.log(`[${new Date().toLocaleTimeString()}] ${event}: ${relativePath}`);
|
|
270
|
+
},
|
|
271
|
+
onError: (error)=>{
|
|
272
|
+
spin.fail(error instanceof Error ? error.message : String(error));
|
|
273
|
+
},
|
|
274
|
+
onProgress: createResourceProgressHandler(spin, config),
|
|
275
|
+
resolved,
|
|
276
|
+
workDir
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
startSchemaWatcher(config, spin, workDir) {
|
|
280
|
+
spin.start('Loading schema…');
|
|
281
|
+
const rendererContext = {
|
|
282
|
+
formatGeneratedCode: config.formatGeneratedCode,
|
|
283
|
+
generates: config.generates,
|
|
284
|
+
schema: config.schema
|
|
285
|
+
};
|
|
286
|
+
let renderProgress = createTypegenProgressRenderer(spin, rendererContext);
|
|
287
|
+
return runTypegenWatcher({
|
|
288
|
+
config,
|
|
289
|
+
onProgress: (event)=>{
|
|
290
|
+
// 'schemaLoaded' is the first event of every generation cycle; the
|
|
291
|
+
// renderer accumulates per-run state, so start each cycle fresh.
|
|
292
|
+
if (event.type === 'schemaLoaded') {
|
|
293
|
+
renderProgress = createTypegenProgressRenderer(spin, rendererContext);
|
|
294
|
+
}
|
|
295
|
+
renderProgress(event);
|
|
296
|
+
},
|
|
297
|
+
workDir
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Returns the progress handler for one resource's generation, which starts with a line naming
|
|
303
|
+
* the resource. The renderer keeps per-run state, so each generation gets a new one.
|
|
304
|
+
*/ function createResourceProgressHandler(spin, config) {
|
|
305
|
+
return (entry)=>{
|
|
306
|
+
spin.start(`Generating types for ${entry.key}…`);
|
|
307
|
+
return createTypegenProgressRenderer(spin, {
|
|
308
|
+
formatGeneratedCode: config.formatGeneratedCode,
|
|
309
|
+
generates: entry.resource.generates,
|
|
310
|
+
schema: 'schemaPath' in entry ? entry.schemaPath : entry.key
|
|
311
|
+
});
|
|
312
|
+
};
|
|
275
313
|
}
|
|
276
314
|
|
|
277
315
|
//# sourceMappingURL=generate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/typegen/generate.ts"],"sourcesContent":["import {stat} from 'node:fs/promises'\nimport {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {exitCodes, SanityCommand} from '@sanity/cli-core'\nimport {spinner, type SpinnerInstance} from '@sanity/cli-core/ux'\nimport {\n readConfig,\n runTypegenGenerate,\n runTypegenWatcher,\n type TypeGenConfig,\n TypegenWatchModeTrace,\n TypesGeneratedTrace,\n} from '@sanity/codegen'\nimport omit from 'lodash-es/omit.js'\nimport once from 'lodash-es/once.js'\n\nimport {formatPath} from '../../actions/typegen/formatPath.js'\nimport {\n generateResourceTypes,\n resolveResourceSchemas,\n} from '../../actions/typegen/generateResourceTypes.js'\nimport {parseTypegenConfig} from '../../actions/typegen/parseTypegenConfig.js'\nimport {\n parseTypegenResources,\n type TypegenResourcesConfig,\n} from '../../actions/typegen/parseTypegenResources.js'\nimport {createTypegenProgressRenderer} from '../../actions/typegen/renderTypegenProgress.js'\n\nconst description = `Sanity TypeGen\n\n${styleText('bold', 'Configuration:')}\nThis command can utilize configuration settings defined in a \\`sanity-typegen.json\\` file. These settings include:\n\n- \"path\": Specifies a glob pattern to locate your TypeScript or JavaScript files.\n Default: \"./src/**/*.{ts,tsx,js,jsx}\"\n\n- \"schema\": Defines the path to your Sanity schema file. This file should be generated using the \\`sanity schema extract\\` command.\n Default: \"schema.json\"\n\n- \"generates\": Indicates the path where the generated TypeScript type definitions will be saved.\n Default: \"./sanity.types.ts\"\n\nThe default configuration values listed above are used if not overridden in your \\`sanity-typegen.json\\` configuration file. To customize the behavior of the type generation, adjust these properties in the configuration file according to your project's needs.\n\n${styleText('bold', 'Note:')}\n- The \\`sanity schema extract\\` command is a prerequisite for extracting your Sanity Studio schema into a \\`schema.json\\` file, which is then used by the \\`sanity typegen generate\\` command to generate type definitions.\n- To generate types for several datasets, list them in \\`typegen.resources\\` in \\`sanity.cli.ts\\` (beta). Each resource uses its own \\`schema\\` file, or the schema bound to its dataset when \\`schema\\` is omitted.`.trim()\n\nexport class TypegenGenerateCommand extends SanityCommand<typeof TypegenGenerateCommand> {\n static override description = description\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: `Generate TypeScript type definitions from a Sanity Studio schema extracted using the \\`sanity schema extract\\` command.`,\n },\n ]\n\n static override flags = {\n 'config-path': Flags.string({\n description:\n '[Default: sanity-typegen.json] Specifies the path to the typegen configuration file. This file should be a JSON file that contains settings for the type generation process.',\n }),\n watch: Flags.boolean({\n default: false,\n description: '[Default: false] Run the typegen in watch mode',\n }),\n }\n\n static override hiddenAliases: string[] = ['typegen:generate']\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(TypegenGenerateCommand)\n\n if (flags.watch) {\n await this.runWatcher()\n return\n }\n\n await this.runSingle()\n }\n\n private async getConfig(): Promise<{\n config: TypeGenConfig\n path?: string\n resources?: TypegenResourcesConfig\n type: 'cli' | 'legacy'\n workDir: string\n }> {\n const spin = spinner({}).start('Loading config…')\n\n try {\n const {flags} = await this.parse(TypegenGenerateCommand)\n const rootDir = await this.getProjectRoot()\n const config = await this.getCliConfig()\n\n const configPath = flags['config-path']\n const workDir = rootDir.directory\n\n const legacyConfigPath = configPath || 'sanity-typegen.json'\n let hasLegacyConfig = false\n\n try {\n const file = await stat(legacyConfigPath)\n hasLegacyConfig = file.isFile()\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT' && configPath) {\n spin.fail()\n this.error(`Typegen config file not found: ${configPath}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (err instanceof Error && 'code' in err && err.code !== 'ENOENT') {\n spin.fail()\n this.error(`Error when checking if typegen config file exists: ${legacyConfigPath}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n if (config?.typegen && hasLegacyConfig) {\n spin.warn(\n styleText(\n 'yellow',\n `You've specified typegen in your Sanity CLI config, but also have a typegen config.\n\n The config from the Sanity CLI config is used.\n `,\n ),\n )\n\n const resources = parseTypegenResources(config.typegen, workDir)\n return {\n config: resources?.config ?? parseTypegenConfig(config.typegen || {}),\n path: rootDir.path,\n resources,\n type: 'cli',\n workDir,\n }\n }\n\n if (hasLegacyConfig) {\n spin.warn(\n styleText(\n 'yellow',\n `The separate typegen config has been deprecated. Use \\`typegen\\` in the sanity CLI config instead.\n\n See: https://www.sanity.io/docs/help/configuring-typegen-in-sanity-cli-config`,\n ),\n )\n return {\n config: await readConfig(legacyConfigPath),\n path: legacyConfigPath,\n type: 'legacy',\n workDir,\n }\n }\n\n const resources = parseTypegenResources(config.typegen, workDir)\n spin.succeed(`Config loaded from sanity.cli.ts`)\n\n return {\n config: resources?.config ?? parseTypegenConfig(config.typegen || {}),\n path: rootDir.path,\n resources,\n type: 'cli',\n workDir,\n }\n } catch (err) {\n // The config-file checks above already reported a user-facing error via\n // `this.error()` (an oclif CLIError). Re-throw those as-is instead of\n // wrapping them a second time and failing the spinner twice.\n if (err instanceof CLIError) throw err\n spin.fail()\n this.error(`An error occurred during config loading: ${err}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async runSingle(): Promise<void> {\n const trace = this.telemetry.trace(TypesGeneratedTrace)\n let spin: SpinnerInstance | undefined\n\n try {\n const {\n config: typegenConfig,\n resources,\n type: typegenConfigMethod,\n workDir,\n } = await this.getConfig()\n trace.start()\n\n if (resources) {\n for (const warning of resources.warnings) {\n this.output.warn(warning)\n }\n\n const resourceSpin = spinner({})\n spin = resourceSpin\n const resolved = await resolveResourceSchemas({\n onResolved: (entry) => {\n resourceSpin.succeed(\n 'schemaPath' in entry\n ? `Using ${formatPath(entry.schemaPath)} for ${entry.key}`\n : `Fetched the schema bound to ${entry.key} (${entry.schemaVersion})`,\n )\n },\n onResolving: (resource, key) => {\n resourceSpin.start(\n resource.schema === undefined\n ? `Fetching the schema bound to ${key}…`\n : `Checking the schema file for ${key}…`,\n )\n },\n resources: resources.resources,\n workDir,\n })\n\n const results = await generateResourceTypes({\n config: typegenConfig,\n onProgress: (entry) => {\n resourceSpin.start(`Generating types for ${entry.key}…`)\n return createTypegenProgressRenderer(resourceSpin, {\n formatGeneratedCode: typegenConfig.formatGeneratedCode,\n generates: entry.resource.generates,\n schema: 'schemaPath' in entry ? entry.schemaPath : entry.key,\n })\n },\n resolved,\n workDir,\n })\n\n for (const {result} of results) {\n trace.log({\n configMethod: typegenConfigMethod,\n configOverloadClientMethods: typegenConfig.overloadClientMethods,\n ...omit(result, 'code', 'duration'),\n })\n }\n trace.complete()\n return\n }\n\n spin = spinner({}).start('Loading schema…')\n const result = await runTypegenGenerate({\n config: typegenConfig,\n onProgress: createTypegenProgressRenderer(spin, {\n formatGeneratedCode: typegenConfig.formatGeneratedCode,\n generates: typegenConfig.generates,\n schema: typegenConfig.schema,\n }),\n workDir,\n })\n\n const traceStats = omit(result, 'code', 'duration')\n\n trace.log({\n configMethod: typegenConfigMethod,\n configOverloadClientMethods: typegenConfig.overloadClientMethods,\n ...traceStats,\n })\n trace.complete()\n } catch (error) {\n if (spin?.isSpinning) {\n spin.fail()\n }\n trace.error(error instanceof Error ? error : new Error(String(error)))\n this.error(`${error instanceof Error ? error.message : 'Unknown error'}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async runWatcher(): Promise<void> {\n const trace = this.telemetry.trace(TypegenWatchModeTrace)\n let spin: SpinnerInstance | undefined\n\n try {\n const {config: typegenConfig, resources, workDir} = await this.getConfig()\n if (resources) {\n this.error(\n 'Watch mode does not support typegen.resources yet. Run \"sanity typegen generate\" without --watch.',\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n trace.start()\n\n let resolve: () => void = () => {}\n const promise = new Promise<void>((res) => {\n resolve = res\n })\n\n const watchSpin = spinner({}).start('Loading schema…')\n spin = watchSpin\n const rendererContext = {\n formatGeneratedCode: typegenConfig.formatGeneratedCode,\n generates: typegenConfig.generates,\n schema: typegenConfig.schema,\n }\n let renderProgress = createTypegenProgressRenderer(watchSpin, rendererContext)\n\n const typegenWatcher = runTypegenWatcher({\n config: typegenConfig,\n onProgress: (event) => {\n // 'schemaLoaded' is the first event of every generation cycle; the\n // renderer accumulates per-run state, so start each cycle fresh.\n if (event.type === 'schemaLoaded') {\n renderProgress = createTypegenProgressRenderer(watchSpin, rendererContext)\n }\n renderProgress(event)\n },\n workDir,\n })\n\n const stop = once(async () => {\n process.off('SIGINT', stop)\n process.off('SIGTERM', stop)\n\n if (watchSpin.isSpinning) {\n watchSpin.stop()\n }\n\n trace.log({\n step: 'stopped',\n ...typegenWatcher.getStats(),\n })\n trace.complete()\n\n try {\n await typegenWatcher.stop()\n } catch {\n // We're shutting down; a failure to close the watcher shouldn't hang\n // the process or surface as an unhandled rejection.\n }\n resolve()\n })\n\n process.on('SIGINT', stop)\n process.on('SIGTERM', stop)\n\n await promise\n } catch (error) {\n if (spin?.isSpinning) {\n spin.fail()\n }\n trace.error(error instanceof Error ? error : new Error(String(error)))\n // Errors already reported with `this.error()` keep their own exit code.\n if (error instanceof CLIError) throw error\n this.error(`${error instanceof Error ? error.message : 'Unknown error'}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n}\n"],"names":["stat","styleText","Flags","CLIError","exitCodes","SanityCommand","spinner","readConfig","runTypegenGenerate","runTypegenWatcher","TypegenWatchModeTrace","TypesGeneratedTrace","omit","once","formatPath","generateResourceTypes","resolveResourceSchemas","parseTypegenConfig","parseTypegenResources","createTypegenProgressRenderer","description","trim","TypegenGenerateCommand","examples","command","flags","string","watch","boolean","default","hiddenAliases","run","parse","runWatcher","runSingle","getConfig","spin","start","rootDir","getProjectRoot","config","getCliConfig","configPath","workDir","directory","legacyConfigPath","hasLegacyConfig","file","isFile","err","Error","code","fail","error","exit","RUNTIME_ERROR","typegen","warn","resources","path","type","succeed","trace","telemetry","typegenConfig","typegenConfigMethod","warning","warnings","output","resourceSpin","resolved","onResolved","entry","schemaPath","key","schemaVersion","onResolving","resource","schema","undefined","results","onProgress","formatGeneratedCode","generates","result","log","configMethod","configOverloadClientMethods","overloadClientMethods","complete","traceStats","isSpinning","String","message","USAGE_ERROR","resolve","promise","Promise","res","watchSpin","rendererContext","renderProgress","typegenWatcher","event","stop","process","off","step","getStats","on"],"mappings":"AAAA,SAAQA,IAAI,QAAO,mBAAkB;AACrC,SAAQC,SAAS,QAAO,YAAW;AAEnC,SAAQC,KAAK,QAAO,cAAa;AACjC,SAAQC,QAAQ,QAAO,qBAAoB;AAC3C,SAAQC,SAAS,EAAEC,aAAa,QAAO,mBAAkB;AACzD,SAAQC,OAAO,QAA6B,sBAAqB;AACjE,SACEC,UAAU,EACVC,kBAAkB,EAClBC,iBAAiB,EAEjBC,qBAAqB,EACrBC,mBAAmB,QACd,kBAAiB;AACxB,OAAOC,UAAU,oBAAmB;AACpC,OAAOC,UAAU,oBAAmB;AAEpC,SAAQC,UAAU,QAAO,sCAAqC;AAC9D,SACEC,qBAAqB,EACrBC,sBAAsB,QACjB,iDAAgD;AACvD,SAAQC,kBAAkB,QAAO,8CAA6C;AAC9E,SACEC,qBAAqB,QAEhB,iDAAgD;AACvD,SAAQC,6BAA6B,QAAO,iDAAgD;AAE5F,MAAMC,cAAc,CAAC;;AAErB,EAAEnB,UAAU,QAAQ,kBAAkB;;;;;;;;;;;;;;AActC,EAAEA,UAAU,QAAQ,SAAS;;oNAEuL,CAAC,CAACoB,IAAI;AAE1N,OAAO,MAAMC,+BAA+BjB;IAC1C,OAAgBe,cAAcA,YAAW;IAEzC,OAAgBG,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa,CAAC,uHAAuH,CAAC;QACxI;KACD,CAAA;IAED,OAAgBK,QAAQ;QACtB,eAAevB,MAAMwB,MAAM,CAAC;YAC1BN,aACE;QACJ;QACAO,OAAOzB,MAAM0B,OAAO,CAAC;YACnBC,SAAS;YACTT,aAAa;QACf;IACF,EAAC;IAED,OAAgBU,gBAA0B;QAAC;KAAmB,CAAA;IAE9D,MAAaC,MAAqB;QAChC,MAAM,EAACN,KAAK,EAAC,GAAG,MAAM,IAAI,CAACO,KAAK,CAACV;QAEjC,IAAIG,MAAME,KAAK,EAAE;YACf,MAAM,IAAI,CAACM,UAAU;YACrB;QACF;QAEA,MAAM,IAAI,CAACC,SAAS;IACtB;IAEA,MAAcC,YAMX;QACD,MAAMC,OAAO9B,QAAQ,CAAC,GAAG+B,KAAK,CAAC;QAE/B,IAAI;YACF,MAAM,EAACZ,KAAK,EAAC,GAAG,MAAM,IAAI,CAACO,KAAK,CAACV;YACjC,MAAMgB,UAAU,MAAM,IAAI,CAACC,cAAc;YACzC,MAAMC,SAAS,MAAM,IAAI,CAACC,YAAY;YAEtC,MAAMC,aAAajB,KAAK,CAAC,cAAc;YACvC,MAAMkB,UAAUL,QAAQM,SAAS;YAEjC,MAAMC,mBAAmBH,cAAc;YACvC,IAAII,kBAAkB;YAEtB,IAAI;gBACF,MAAMC,OAAO,MAAM/C,KAAK6C;gBACxBC,kBAAkBC,KAAKC,MAAM;YAC/B,EAAE,OAAOC,KAAK;gBACZ,IAAIA,eAAeC,SAAS,UAAUD,OAAOA,IAAIE,IAAI,KAAK,YAAYT,YAAY;oBAChFN,KAAKgB,IAAI;oBACT,IAAI,CAACC,KAAK,CAAC,CAAC,+BAA+B,EAAEX,YAAY,EAAE;wBACzDY,MAAMlD,UAAUmD,aAAa;oBAC/B;gBACF;gBAEA,IAAIN,eAAeC,SAAS,UAAUD,OAAOA,IAAIE,IAAI,KAAK,UAAU;oBAClEf,KAAKgB,IAAI;oBACT,IAAI,CAACC,KAAK,CAAC,CAAC,mDAAmD,EAAER,kBAAkB,EAAE;wBACnFS,MAAMlD,UAAUmD,aAAa;oBAC/B;gBACF;YACF;YAEA,IAAIf,QAAQgB,WAAWV,iBAAiB;gBACtCV,KAAKqB,IAAI,CACPxD,UACE,UACA,CAAC;;;IAGT,CAAC;gBAIG,MAAMyD,YAAYxC,sBAAsBsB,OAAOgB,OAAO,EAAEb;gBACxD,OAAO;oBACLH,QAAQkB,WAAWlB,UAAUvB,mBAAmBuB,OAAOgB,OAAO,IAAI,CAAC;oBACnEG,MAAMrB,QAAQqB,IAAI;oBAClBD;oBACAE,MAAM;oBACNjB;gBACF;YACF;YAEA,IAAIG,iBAAiB;gBACnBV,KAAKqB,IAAI,CACPxD,UACE,UACA,CAAC;;iFAEoE,CAAC;gBAG1E,OAAO;oBACLuC,QAAQ,MAAMjC,WAAWsC;oBACzBc,MAAMd;oBACNe,MAAM;oBACNjB;gBACF;YACF;YAEA,MAAMe,YAAYxC,sBAAsBsB,OAAOgB,OAAO,EAAEb;YACxDP,KAAKyB,OAAO,CAAC,CAAC,gCAAgC,CAAC;YAE/C,OAAO;gBACLrB,QAAQkB,WAAWlB,UAAUvB,mBAAmBuB,OAAOgB,OAAO,IAAI,CAAC;gBACnEG,MAAMrB,QAAQqB,IAAI;gBAClBD;gBACAE,MAAM;gBACNjB;YACF;QACF,EAAE,OAAOM,KAAK;YACZ,wEAAwE;YACxE,sEAAsE;YACtE,6DAA6D;YAC7D,IAAIA,eAAe9C,UAAU,MAAM8C;YACnCb,KAAKgB,IAAI;YACT,IAAI,CAACC,KAAK,CAAC,CAAC,yCAAyC,EAAEJ,KAAK,EAAE;gBAC5DK,MAAMlD,UAAUmD,aAAa;YAC/B;QACF;IACF;IAEA,MAAcrB,YAA2B;QACvC,MAAM4B,QAAQ,IAAI,CAACC,SAAS,CAACD,KAAK,CAACnD;QACnC,IAAIyB;QAEJ,IAAI;YACF,MAAM,EACJI,QAAQwB,aAAa,EACrBN,SAAS,EACTE,MAAMK,mBAAmB,EACzBtB,OAAO,EACR,GAAG,MAAM,IAAI,CAACR,SAAS;YACxB2B,MAAMzB,KAAK;YAEX,IAAIqB,WAAW;gBACb,KAAK,MAAMQ,WAAWR,UAAUS,QAAQ,CAAE;oBACxC,IAAI,CAACC,MAAM,CAACX,IAAI,CAACS;gBACnB;gBAEA,MAAMG,eAAe/D,QAAQ,CAAC;gBAC9B8B,OAAOiC;gBACP,MAAMC,WAAW,MAAMtD,uBAAuB;oBAC5CuD,YAAY,CAACC;wBACXH,aAAaR,OAAO,CAClB,gBAAgBW,QACZ,CAAC,MAAM,EAAE1D,WAAW0D,MAAMC,UAAU,EAAE,KAAK,EAAED,MAAME,GAAG,EAAE,GACxD,CAAC,4BAA4B,EAAEF,MAAME,GAAG,CAAC,EAAE,EAAEF,MAAMG,aAAa,CAAC,CAAC,CAAC;oBAE3E;oBACAC,aAAa,CAACC,UAAUH;wBACtBL,aAAahC,KAAK,CAChBwC,SAASC,MAAM,KAAKC,YAChB,CAAC,6BAA6B,EAAEL,IAAI,CAAC,CAAC,GACtC,CAAC,6BAA6B,EAAEA,IAAI,CAAC,CAAC;oBAE9C;oBACAhB,WAAWA,UAAUA,SAAS;oBAC9Bf;gBACF;gBAEA,MAAMqC,UAAU,MAAMjE,sBAAsB;oBAC1CyB,QAAQwB;oBACRiB,YAAY,CAACT;wBACXH,aAAahC,KAAK,CAAC,CAAC,qBAAqB,EAAEmC,MAAME,GAAG,CAAC,CAAC,CAAC;wBACvD,OAAOvD,8BAA8BkD,cAAc;4BACjDa,qBAAqBlB,cAAckB,mBAAmB;4BACtDC,WAAWX,MAAMK,QAAQ,CAACM,SAAS;4BACnCL,QAAQ,gBAAgBN,QAAQA,MAAMC,UAAU,GAAGD,MAAME,GAAG;wBAC9D;oBACF;oBACAJ;oBACA3B;gBACF;gBAEA,KAAK,MAAM,EAACyC,MAAM,EAAC,IAAIJ,QAAS;oBAC9BlB,MAAMuB,GAAG,CAAC;wBACRC,cAAcrB;wBACdsB,6BAA6BvB,cAAcwB,qBAAqB;wBAChE,GAAG5E,KAAKwE,QAAQ,QAAQ,WAAW;oBACrC;gBACF;gBACAtB,MAAM2B,QAAQ;gBACd;YACF;YAEArD,OAAO9B,QAAQ,CAAC,GAAG+B,KAAK,CAAC;YACzB,MAAM+C,SAAS,MAAM5E,mBAAmB;gBACtCgC,QAAQwB;gBACRiB,YAAY9D,8BAA8BiB,MAAM;oBAC9C8C,qBAAqBlB,cAAckB,mBAAmB;oBACtDC,WAAWnB,cAAcmB,SAAS;oBAClCL,QAAQd,cAAcc,MAAM;gBAC9B;gBACAnC;YACF;YAEA,MAAM+C,aAAa9E,KAAKwE,QAAQ,QAAQ;YAExCtB,MAAMuB,GAAG,CAAC;gBACRC,cAAcrB;gBACdsB,6BAA6BvB,cAAcwB,qBAAqB;gBAChE,GAAGE,UAAU;YACf;YACA5B,MAAM2B,QAAQ;QAChB,EAAE,OAAOpC,OAAO;YACd,IAAIjB,MAAMuD,YAAY;gBACpBvD,KAAKgB,IAAI;YACX;YACAU,MAAMT,KAAK,CAACA,iBAAiBH,QAAQG,QAAQ,IAAIH,MAAM0C,OAAOvC;YAC9D,IAAI,CAACA,KAAK,CAAC,GAAGA,iBAAiBH,QAAQG,MAAMwC,OAAO,GAAG,iBAAiB,EAAE;gBACxEvC,MAAMlD,UAAUmD,aAAa;YAC/B;QACF;IACF;IAEA,MAActB,aAA4B;QACxC,MAAM6B,QAAQ,IAAI,CAACC,SAAS,CAACD,KAAK,CAACpD;QACnC,IAAI0B;QAEJ,IAAI;YACF,MAAM,EAACI,QAAQwB,aAAa,EAAEN,SAAS,EAAEf,OAAO,EAAC,GAAG,MAAM,IAAI,CAACR,SAAS;YACxE,IAAIuB,WAAW;gBACb,IAAI,CAACL,KAAK,CACR,qGACA;oBAACC,MAAMlD,UAAU0F,WAAW;gBAAA;YAEhC;YACAhC,MAAMzB,KAAK;YAEX,IAAI0D,UAAsB,KAAO;YACjC,MAAMC,UAAU,IAAIC,QAAc,CAACC;gBACjCH,UAAUG;YACZ;YAEA,MAAMC,YAAY7F,QAAQ,CAAC,GAAG+B,KAAK,CAAC;YACpCD,OAAO+D;YACP,MAAMC,kBAAkB;gBACtBlB,qBAAqBlB,cAAckB,mBAAmB;gBACtDC,WAAWnB,cAAcmB,SAAS;gBAClCL,QAAQd,cAAcc,MAAM;YAC9B;YACA,IAAIuB,iBAAiBlF,8BAA8BgF,WAAWC;YAE9D,MAAME,iBAAiB7F,kBAAkB;gBACvC+B,QAAQwB;gBACRiB,YAAY,CAACsB;oBACX,mEAAmE;oBACnE,iEAAiE;oBACjE,IAAIA,MAAM3C,IAAI,KAAK,gBAAgB;wBACjCyC,iBAAiBlF,8BAA8BgF,WAAWC;oBAC5D;oBACAC,eAAeE;gBACjB;gBACA5D;YACF;YAEA,MAAM6D,OAAO3F,KAAK;gBAChB4F,QAAQC,GAAG,CAAC,UAAUF;gBACtBC,QAAQC,GAAG,CAAC,WAAWF;gBAEvB,IAAIL,UAAUR,UAAU,EAAE;oBACxBQ,UAAUK,IAAI;gBAChB;gBAEA1C,MAAMuB,GAAG,CAAC;oBACRsB,MAAM;oBACN,GAAGL,eAAeM,QAAQ,EAAE;gBAC9B;gBACA9C,MAAM2B,QAAQ;gBAEd,IAAI;oBACF,MAAMa,eAAeE,IAAI;gBAC3B,EAAE,OAAM;gBACN,qEAAqE;gBACrE,oDAAoD;gBACtD;gBACAT;YACF;YAEAU,QAAQI,EAAE,CAAC,UAAUL;YACrBC,QAAQI,EAAE,CAAC,WAAWL;YAEtB,MAAMR;QACR,EAAE,OAAO3C,OAAO;YACd,IAAIjB,MAAMuD,YAAY;gBACpBvD,KAAKgB,IAAI;YACX;YACAU,MAAMT,KAAK,CAACA,iBAAiBH,QAAQG,QAAQ,IAAIH,MAAM0C,OAAOvC;YAC9D,wEAAwE;YACxE,IAAIA,iBAAiBlD,UAAU,MAAMkD;YACrC,IAAI,CAACA,KAAK,CAAC,GAAGA,iBAAiBH,QAAQG,MAAMwC,OAAO,GAAG,iBAAiB,EAAE;gBACxEvC,MAAMlD,UAAUmD,aAAa;YAC/B;QACF;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/typegen/generate.ts"],"sourcesContent":["import {stat} from 'node:fs/promises'\nimport {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {exitCodes, SanityCommand} from '@sanity/cli-core'\nimport {spinner, type SpinnerInstance} from '@sanity/cli-core/ux'\nimport {\n readConfig,\n runTypegenGenerate,\n runTypegenWatcher,\n type TypeGenConfig,\n type TypegenProgressEvent,\n TypegenWatchModeTrace,\n TypesGeneratedTrace,\n} from '@sanity/codegen'\nimport omit from 'lodash-es/omit.js'\nimport once from 'lodash-es/once.js'\n\nimport {formatPath} from '../../actions/typegen/formatPath.js'\nimport {\n generateResourceTypes,\n type ResolvedResource,\n resolveResourceSchemas,\n} from '../../actions/typegen/generateResourceTypes.js'\nimport {parseTypegenConfig} from '../../actions/typegen/parseTypegenConfig.js'\nimport {\n parseTypegenResources,\n type TypegenResourcesConfig,\n} from '../../actions/typegen/parseTypegenResources.js'\nimport {createTypegenProgressRenderer} from '../../actions/typegen/renderTypegenProgress.js'\nimport {\n type ResourceTypesWatcher,\n watchResourceTypes,\n} from '../../actions/typegen/watchResourceTypes.js'\n\nconst description = `Sanity TypeGen\n\n${styleText('bold', 'Configuration:')}\nThis command can utilize configuration settings defined in a \\`sanity-typegen.json\\` file. These settings include:\n\n- \"path\": Specifies a glob pattern to locate your TypeScript or JavaScript files.\n Default: \"./src/**/*.{ts,tsx,js,jsx}\"\n\n- \"schema\": Defines the path to your Sanity schema file. This file should be generated using the \\`sanity schema extract\\` command.\n Default: \"schema.json\"\n\n- \"generates\": Indicates the path where the generated TypeScript type definitions will be saved.\n Default: \"./sanity.types.ts\"\n\nThe default configuration values listed above are used if not overridden in your \\`sanity-typegen.json\\` configuration file. To customize the behavior of the type generation, adjust these properties in the configuration file according to your project's needs.\n\n${styleText('bold', 'Note:')}\n- The \\`sanity schema extract\\` command is a prerequisite for extracting your Sanity Studio schema into a \\`schema.json\\` file, which is then used by the \\`sanity typegen generate\\` command to generate type definitions.\n- To generate types for several datasets, list them in \\`typegen.resources\\` in \\`sanity.cli.ts\\` (beta). Each resource uses its own \\`schema\\` file, or the schema bound to its dataset when \\`schema\\` is omitted. With \\`--watch\\`, a schema bound to a dataset is fetched once, when the watcher starts. Restart it after deploying a schema.`.trim()\n\nexport class TypegenGenerateCommand extends SanityCommand<typeof TypegenGenerateCommand> {\n static override description = description\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: `Generate TypeScript type definitions from a Sanity Studio schema extracted using the \\`sanity schema extract\\` command.`,\n },\n ]\n\n static override flags = {\n 'config-path': Flags.string({\n description:\n '[Default: sanity-typegen.json] Specifies the path to the typegen configuration file. This file should be a JSON file that contains settings for the type generation process.',\n }),\n watch: Flags.boolean({\n default: false,\n description: '[Default: false] Run the typegen in watch mode',\n }),\n }\n\n static override hiddenAliases: string[] = ['typegen:generate']\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(TypegenGenerateCommand)\n\n if (flags.watch) {\n await this.runWatcher()\n return\n }\n\n await this.runSingle()\n }\n\n private async getConfig(): Promise<{\n config: TypeGenConfig\n path?: string\n resources?: TypegenResourcesConfig\n type: 'cli' | 'legacy'\n workDir: string\n }> {\n const spin = spinner({}).start('Loading config…')\n\n try {\n const {flags} = await this.parse(TypegenGenerateCommand)\n const rootDir = await this.getProjectRoot()\n const config = await this.getCliConfig()\n\n const configPath = flags['config-path']\n const workDir = rootDir.directory\n\n const legacyConfigPath = configPath || 'sanity-typegen.json'\n let hasLegacyConfig = false\n\n try {\n const file = await stat(legacyConfigPath)\n hasLegacyConfig = file.isFile()\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT' && configPath) {\n spin.fail()\n this.error(`Typegen config file not found: ${configPath}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (err instanceof Error && 'code' in err && err.code !== 'ENOENT') {\n spin.fail()\n this.error(`Error when checking if typegen config file exists: ${legacyConfigPath}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n if (config?.typegen && hasLegacyConfig) {\n spin.warn(\n styleText(\n 'yellow',\n `You've specified typegen in your Sanity CLI config, but also have a typegen config.\n\n The config from the Sanity CLI config is used.\n `,\n ),\n )\n\n const resources = parseTypegenResources(config.typegen, workDir)\n return {\n config: resources?.config ?? parseTypegenConfig(config.typegen || {}),\n path: rootDir.path,\n resources,\n type: 'cli',\n workDir,\n }\n }\n\n if (hasLegacyConfig) {\n spin.warn(\n styleText(\n 'yellow',\n `The separate typegen config has been deprecated. Use \\`typegen\\` in the sanity CLI config instead.\n\n See: https://www.sanity.io/docs/help/configuring-typegen-in-sanity-cli-config`,\n ),\n )\n return {\n config: await readConfig(legacyConfigPath),\n path: legacyConfigPath,\n type: 'legacy',\n workDir,\n }\n }\n\n const resources = parseTypegenResources(config.typegen, workDir)\n spin.succeed(`Config loaded from sanity.cli.ts`)\n\n return {\n config: resources?.config ?? parseTypegenConfig(config.typegen || {}),\n path: rootDir.path,\n resources,\n type: 'cli',\n workDir,\n }\n } catch (err) {\n // The config-file checks above already reported a user-facing error via\n // `this.error()` (an oclif CLIError). Re-throw those as-is instead of\n // wrapping them a second time and failing the spinner twice.\n if (err instanceof CLIError) throw err\n spin.fail()\n this.error(`An error occurred during config loading: ${err}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n /**\n * Prints the resources' configuration warnings, then locates every resource's schema, reporting\n * each one on the spinner.\n */\n private async resolveResources(\n resources: TypegenResourcesConfig,\n spin: SpinnerInstance,\n workDir: string,\n {checkSchemaFiles}: {checkSchemaFiles: boolean},\n ): Promise<ResolvedResource[]> {\n for (const warning of resources.warnings) {\n this.output.warn(warning)\n }\n\n return resolveResourceSchemas({\n checkSchemaFiles,\n onResolved: (entry) => {\n spin.succeed(\n 'schemaPath' in entry\n ? `Using ${formatPath(entry.schemaPath)} for ${entry.key}`\n : `Fetched the schema bound to ${entry.key} (${entry.schemaVersion})`,\n )\n },\n onResolving: (resource, key) => {\n spin.start(\n resource.schema === undefined\n ? `Fetching the schema bound to ${key}…`\n : `Checking the schema file for ${key}…`,\n )\n },\n resources: resources.resources,\n workDir,\n })\n }\n\n private async runSingle(): Promise<void> {\n const trace = this.telemetry.trace(TypesGeneratedTrace)\n let spin: SpinnerInstance | undefined\n\n try {\n const {\n config: typegenConfig,\n resources,\n type: typegenConfigMethod,\n workDir,\n } = await this.getConfig()\n trace.start()\n\n if (resources) {\n const resourceSpin = spinner({})\n spin = resourceSpin\n const resolved = await this.resolveResources(resources, resourceSpin, workDir, {\n checkSchemaFiles: true,\n })\n\n const results = await generateResourceTypes({\n config: typegenConfig,\n onProgress: createResourceProgressHandler(resourceSpin, typegenConfig),\n resolved,\n workDir,\n })\n\n for (const {result} of results) {\n trace.log({\n configMethod: typegenConfigMethod,\n configOverloadClientMethods: typegenConfig.overloadClientMethods,\n ...omit(result, 'code', 'duration'),\n })\n }\n trace.complete()\n return\n }\n\n spin = spinner({}).start('Loading schema…')\n const result = await runTypegenGenerate({\n config: typegenConfig,\n onProgress: createTypegenProgressRenderer(spin, {\n formatGeneratedCode: typegenConfig.formatGeneratedCode,\n generates: typegenConfig.generates,\n schema: typegenConfig.schema,\n }),\n workDir,\n })\n\n const traceStats = omit(result, 'code', 'duration')\n\n trace.log({\n configMethod: typegenConfigMethod,\n configOverloadClientMethods: typegenConfig.overloadClientMethods,\n ...traceStats,\n })\n trace.complete()\n } catch (error) {\n if (spin?.isSpinning) {\n spin.fail()\n }\n trace.error(error instanceof Error ? error : new Error(String(error)))\n this.error(`${error instanceof Error ? error.message : 'Unknown error'}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async runWatcher(): Promise<void> {\n const trace = this.telemetry.trace(TypegenWatchModeTrace)\n let spin: SpinnerInstance | undefined\n\n try {\n const {config: typegenConfig, resources, workDir} = await this.getConfig()\n trace.start()\n\n let resolve: () => void = () => {}\n const promise = new Promise<void>((res) => {\n resolve = res\n })\n\n const watchSpin = spinner({})\n spin = watchSpin\n const typegenWatcher = resources\n ? await this.startResourceWatcher(typegenConfig, resources, watchSpin, workDir)\n : this.startSchemaWatcher(typegenConfig, watchSpin, workDir)\n\n const stop = once(async () => {\n process.off('SIGINT', stop)\n process.off('SIGTERM', stop)\n\n if (watchSpin.isSpinning) {\n watchSpin.stop()\n }\n\n trace.log({\n step: 'stopped',\n ...typegenWatcher.getStats(),\n })\n trace.complete()\n\n try {\n await typegenWatcher.stop()\n } catch {\n // We're shutting down; a failure to close the watcher shouldn't hang\n // the process or surface as an unhandled rejection.\n }\n resolve()\n })\n\n process.on('SIGINT', stop)\n process.on('SIGTERM', stop)\n\n await promise\n } catch (error) {\n if (spin?.isSpinning) {\n spin.fail()\n }\n trace.error(error instanceof Error ? error : new Error(String(error)))\n // Errors already reported with `this.error()` keep their own exit code.\n if (error instanceof CLIError) throw error\n this.error(`${error instanceof Error ? error.message : 'Unknown error'}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n /**\n * Locates every resource's schema once, then generates on each query or local schema change.\n * A schema bound to a dataset is fetched only here, so a schema deployed while the watcher runs\n * is used after a restart.\n */\n private async startResourceWatcher(\n config: TypeGenConfig,\n resources: TypegenResourcesConfig,\n spin: SpinnerInstance,\n workDir: string,\n ): Promise<ResourceTypesWatcher> {\n // A missing local schema file fails that resource's generation until the file appears,\n // instead of ending the watcher.\n const resolved = await this.resolveResources(resources, spin, workDir, {\n checkSchemaFiles: false,\n })\n\n return watchResourceTypes({\n config,\n onChange: (event, relativePath) => {\n this.output.log(`[${new Date().toLocaleTimeString()}] ${event}: ${relativePath}`)\n },\n onError: (error) => {\n spin.fail(error instanceof Error ? error.message : String(error))\n },\n onProgress: createResourceProgressHandler(spin, config),\n resolved,\n workDir,\n })\n }\n\n private startSchemaWatcher(\n config: TypeGenConfig,\n spin: SpinnerInstance,\n workDir: string,\n ): ReturnType<typeof runTypegenWatcher> {\n spin.start('Loading schema…')\n const rendererContext = {\n formatGeneratedCode: config.formatGeneratedCode,\n generates: config.generates,\n schema: config.schema,\n }\n let renderProgress = createTypegenProgressRenderer(spin, rendererContext)\n\n return runTypegenWatcher({\n config,\n onProgress: (event) => {\n // 'schemaLoaded' is the first event of every generation cycle; the\n // renderer accumulates per-run state, so start each cycle fresh.\n if (event.type === 'schemaLoaded') {\n renderProgress = createTypegenProgressRenderer(spin, rendererContext)\n }\n renderProgress(event)\n },\n workDir,\n })\n }\n}\n\n/**\n * Returns the progress handler for one resource's generation, which starts with a line naming\n * the resource. The renderer keeps per-run state, so each generation gets a new one.\n */\nfunction createResourceProgressHandler(\n spin: SpinnerInstance,\n config: TypeGenConfig,\n): (entry: ResolvedResource) => (event: TypegenProgressEvent) => void {\n return (entry) => {\n spin.start(`Generating types for ${entry.key}…`)\n return createTypegenProgressRenderer(spin, {\n formatGeneratedCode: config.formatGeneratedCode,\n generates: entry.resource.generates,\n schema: 'schemaPath' in entry ? entry.schemaPath : entry.key,\n })\n }\n}\n"],"names":["stat","styleText","Flags","CLIError","exitCodes","SanityCommand","spinner","readConfig","runTypegenGenerate","runTypegenWatcher","TypegenWatchModeTrace","TypesGeneratedTrace","omit","once","formatPath","generateResourceTypes","resolveResourceSchemas","parseTypegenConfig","parseTypegenResources","createTypegenProgressRenderer","watchResourceTypes","description","trim","TypegenGenerateCommand","examples","command","flags","string","watch","boolean","default","hiddenAliases","run","parse","runWatcher","runSingle","getConfig","spin","start","rootDir","getProjectRoot","config","getCliConfig","configPath","workDir","directory","legacyConfigPath","hasLegacyConfig","file","isFile","err","Error","code","fail","error","exit","RUNTIME_ERROR","typegen","warn","resources","path","type","succeed","resolveResources","checkSchemaFiles","warning","warnings","output","onResolved","entry","schemaPath","key","schemaVersion","onResolving","resource","schema","undefined","trace","telemetry","typegenConfig","typegenConfigMethod","resourceSpin","resolved","results","onProgress","createResourceProgressHandler","result","log","configMethod","configOverloadClientMethods","overloadClientMethods","complete","formatGeneratedCode","generates","traceStats","isSpinning","String","message","resolve","promise","Promise","res","watchSpin","typegenWatcher","startResourceWatcher","startSchemaWatcher","stop","process","off","step","getStats","on","onChange","event","relativePath","Date","toLocaleTimeString","onError","rendererContext","renderProgress"],"mappings":"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"}
|
|
@@ -13,6 +13,7 @@ export class UndeployCommand extends SanityCommand {
|
|
|
13
13
|
})
|
|
14
14
|
};
|
|
15
15
|
static description = 'Removes the deployed Sanity Studio/App from Sanity hosting';
|
|
16
|
+
static enableJsonFlag = true;
|
|
16
17
|
static examples = [
|
|
17
18
|
{
|
|
18
19
|
command: '<%= config.bin %> <%= command.id %>',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/undeploy.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type CliConfig, exitCodes, SanityCommand} from '@sanity/cli-core'\nimport {type UndeployAdapter} from '@sanity/cli-core/undeploy'\nimport {getWorkbench, resolveWorkbenchConfig} 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 args = {\n appId: Args.string({\n description:\n 'ID of the application to undeploy. Overrides `deployment.appId` in sanity.cli.ts',\n }),\n }\n\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 %> abc123',\n description: 'Undeploy the studio or application with the given ID',\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 {args, flags} = await this.parse(UndeployCommand)\n\n const projectConfig = await this.getCliConfig()\n const isApp = determineIsApp(projectConfig)\n if (args.appId) this.warnIfOverridingConfig(args.appId, projectConfig, isApp)\n // An explicit ID stands in for `deployment.appId`, which every adapter\n // already prefers over `studioHost` and the deprecated `app.id`.\n const cliConfig = args.appId\n ? {...projectConfig, deployment: {...projectConfig.deployment, appId: args.appId}}\n : projectConfig\n\n // Workbench apps and configs deploy through Brett, so they undeploy through\n // it too; plain projects keep the user-applications backend.\n const workbench = getWorkbench(cliConfig)\n const config = resolveWorkbenchConfig(cliConfig)\n if (args.appId && config) {\n this.error('An app ID cannot be used to undeploy a config. Run without the argument.', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n\n const adapter: UndeployAdapter =\n workbench || config\n ? createWorkbenchUndeployAdapter({\n appId: getAppId(cliConfig),\n config: config ?? undefined,\n organizationId: cliConfig.app?.organizationId,\n type: isApp ? 'coreApp' : 'studio',\n workbench: workbench ?? undefined,\n })\n : isApp\n ? createAppUndeployAdapter(cliConfig)\n : createStudioUndeployAdapter(cliConfig)\n\n await runUndeploy({flags, isUnattended: this.isUnattended(), output: this.output}, adapter)\n }\n\n private warnIfOverridingConfig(appId: string, cliConfig: CliConfig, isApp: boolean): void {\n const configuredAppId = getAppId(cliConfig)\n if (configuredAppId) {\n if (configuredAppId !== appId) {\n this.output.warn(\n `Using app ID \"${appId}\" instead of \"${configuredAppId}\" configured in sanity.cli.ts`,\n )\n }\n return\n }\n\n if (!isApp && cliConfig.studioHost) {\n this.output.warn(\n `Using app ID \"${appId}\" instead of studio host \"${cliConfig.studioHost}\" configured in sanity.cli.ts`,\n )\n }\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","getWorkbench","resolveWorkbenchConfig","createWorkbenchUndeployAdapter","createAppUndeployAdapter","createStudioUndeployAdapter","runUndeploy","getAppId","determineIsApp","UndeployCommand","args","appId","string","description","examples","command","flags","boolean","default","json","char","yes","run","parse","projectConfig","getCliConfig","isApp","warnIfOverridingConfig","cliConfig","deployment","workbench","config","error","exit","USAGE_ERROR","adapter","undefined","organizationId","app","type","isUnattended","output","configuredAppId","warn","studioHost"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAwBC,SAAS,EAAEC,aAAa,QAAO,mBAAkB;AAEzE,SAAQC,YAAY,EAAEC,sBAAsB,QAAO,+BAA8B;AACjF,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,wBAAwBT;IACnC,OAAgBU,OAAO;QACrBC,OAAOd,KAAKe,MAAM,CAAC;YACjBC,aACE;QACJ;IACF,EAAC;IAED,OAAgBA,cAAc,6DAA4D;IAE1F,OAAgBC,WAAW;QACzB;YACEC,SAAS;
|
|
1
|
+
{"version":3,"sources":["../../src/commands/undeploy.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type CliConfig, exitCodes, SanityCommand} from '@sanity/cli-core'\nimport {type UndeployAdapter} from '@sanity/cli-core/undeploy'\nimport {getWorkbench, resolveWorkbenchConfig} 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 args = {\n appId: Args.string({\n description:\n 'ID of the application to undeploy. Overrides `deployment.appId` in sanity.cli.ts',\n }),\n }\n\n static override description = 'Removes the deployed Sanity Studio/App from Sanity hosting'\n\n static override enableJsonFlag = true\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 %> abc123',\n description: 'Undeploy the studio or application with the given ID',\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 {args, flags} = await this.parse(UndeployCommand)\n\n const projectConfig = await this.getCliConfig()\n const isApp = determineIsApp(projectConfig)\n if (args.appId) this.warnIfOverridingConfig(args.appId, projectConfig, isApp)\n // An explicit ID stands in for `deployment.appId`, which every adapter\n // already prefers over `studioHost` and the deprecated `app.id`.\n const cliConfig = args.appId\n ? {...projectConfig, deployment: {...projectConfig.deployment, appId: args.appId}}\n : projectConfig\n\n // Workbench apps and configs deploy through Brett, so they undeploy through\n // it too; plain projects keep the user-applications backend.\n const workbench = getWorkbench(cliConfig)\n const config = resolveWorkbenchConfig(cliConfig)\n if (args.appId && config) {\n this.error('An app ID cannot be used to undeploy a config. Run without the argument.', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n\n const adapter: UndeployAdapter =\n workbench || config\n ? createWorkbenchUndeployAdapter({\n appId: getAppId(cliConfig),\n config: config ?? undefined,\n organizationId: cliConfig.app?.organizationId,\n type: isApp ? 'coreApp' : 'studio',\n workbench: workbench ?? undefined,\n })\n : isApp\n ? createAppUndeployAdapter(cliConfig)\n : createStudioUndeployAdapter(cliConfig)\n\n await runUndeploy({flags, isUnattended: this.isUnattended(), output: this.output}, adapter)\n }\n\n private warnIfOverridingConfig(appId: string, cliConfig: CliConfig, isApp: boolean): void {\n const configuredAppId = getAppId(cliConfig)\n if (configuredAppId) {\n if (configuredAppId !== appId) {\n this.output.warn(\n `Using app ID \"${appId}\" instead of \"${configuredAppId}\" configured in sanity.cli.ts`,\n )\n }\n return\n }\n\n if (!isApp && cliConfig.studioHost) {\n this.output.warn(\n `Using app ID \"${appId}\" instead of studio host \"${cliConfig.studioHost}\" configured in sanity.cli.ts`,\n )\n }\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","getWorkbench","resolveWorkbenchConfig","createWorkbenchUndeployAdapter","createAppUndeployAdapter","createStudioUndeployAdapter","runUndeploy","getAppId","determineIsApp","UndeployCommand","args","appId","string","description","enableJsonFlag","examples","command","flags","boolean","default","json","char","yes","run","parse","projectConfig","getCliConfig","isApp","warnIfOverridingConfig","cliConfig","deployment","workbench","config","error","exit","USAGE_ERROR","adapter","undefined","organizationId","app","type","isUnattended","output","configuredAppId","warn","studioHost"],"mappings":"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"}
|