@sanity/cli 7.18.0 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -4
- package/dist/SanityHelp.js +1 -35
- package/dist/SanityHelp.js.map +1 -1
- package/dist/actions/assets/assetFileError.js +9 -0
- package/dist/actions/assets/assetFileError.js.map +1 -0
- package/dist/actions/assets/uploadAssetFromFile.js +40 -0
- package/dist/actions/assets/uploadAssetFromFile.js.map +1 -0
- package/dist/actions/assets/uploadAssetWithProgress.js +76 -0
- package/dist/actions/assets/uploadAssetWithProgress.js.map +1 -0
- package/dist/actions/deploy/deployApp.js +39 -44
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployChecks.js +21 -13
- package/dist/actions/deploy/deployChecks.js.map +1 -1
- package/dist/actions/deploy/deployRunner.js +8 -7
- package/dist/actions/deploy/deployRunner.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +55 -35
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/deploymentPlan.js +17 -29
- package/dist/actions/deploy/deploymentPlan.js.map +1 -1
- package/dist/actions/deploy/resolveDeployTarget.js +2 -8
- package/dist/actions/deploy/resolveDeployTarget.js.map +1 -1
- package/dist/actions/dev/servers/getDevServerConfig.js +2 -8
- package/dist/actions/dev/servers/getDevServerConfig.js.map +1 -1
- package/dist/actions/dev/servers/startStudioDevServer.js +7 -1
- package/dist/actions/dev/servers/startStudioDevServer.js.map +1 -1
- package/dist/actions/init/bootstrapRemoteTemplate.js +2 -2
- package/dist/actions/init/bootstrapRemoteTemplate.js.map +1 -1
- package/dist/actions/init/sdkAppDependencies.js +1 -1
- package/dist/actions/init/sdkAppDependencies.js.map +1 -1
- package/dist/actions/init/studioDependencies.js +1 -1
- package/dist/actions/init/studioDependencies.js.map +1 -1
- package/dist/actions/schema/listSchemas.js +1 -1
- package/dist/actions/schema/listSchemas.js.map +1 -1
- package/dist/actions/tokens/constants.js +2 -2
- package/dist/actions/tokens/constants.js.map +1 -1
- package/dist/actions/tokens/expiry.js +35 -0
- package/dist/actions/tokens/expiry.js.map +1 -0
- package/dist/actions/tokens/types.js.map +1 -1
- package/dist/actions/tokens/validateRole.js +5 -2
- package/dist/actions/tokens/validateRole.js.map +1 -1
- package/dist/actions/typegen/count.js +6 -0
- package/dist/actions/typegen/count.js.map +1 -0
- package/dist/actions/typegen/formatPath.js +5 -0
- package/dist/actions/typegen/formatPath.js.map +1 -0
- package/dist/actions/typegen/percent.js +8 -0
- package/dist/actions/typegen/percent.js.map +1 -0
- package/dist/actions/typegen/renderTypegenProgress.js +88 -0
- package/dist/actions/typegen/renderTypegenProgress.js.map +1 -0
- package/dist/actions/undeploy/adapters.js +6 -9
- package/dist/actions/undeploy/adapters.js.map +1 -1
- package/dist/actions/undeploy/runUndeploy.js +12 -4
- package/dist/actions/undeploy/runUndeploy.js.map +1 -1
- package/dist/actions/undeploy/undeployPlan.js +6 -14
- package/dist/actions/undeploy/undeployPlan.js.map +1 -1
- package/dist/commands/assets/upload.js +160 -0
- package/dist/commands/assets/upload.js.map +1 -0
- package/dist/commands/backups/list.js +1 -1
- package/dist/commands/backups/list.js.map +1 -1
- package/dist/commands/datasets/copy.js +1 -1
- package/dist/commands/datasets/copy.js.map +1 -1
- package/dist/commands/login.js +2 -8
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/mcp/configure.js.map +1 -1
- package/dist/commands/migrations/list.js +1 -1
- package/dist/commands/migrations/list.js.map +1 -1
- package/dist/commands/migrations/run.js +67 -3
- package/dist/commands/migrations/run.js.map +1 -1
- package/dist/commands/new.js +4 -3
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/organizations/list.js +1 -1
- package/dist/commands/organizations/list.js.map +1 -1
- package/dist/commands/projects/list.js +39 -12
- package/dist/commands/projects/list.js.map +1 -1
- package/dist/commands/projects/unclaimed.js +39 -33
- package/dist/commands/projects/unclaimed.js.map +1 -1
- package/dist/commands/tokens/create.js +92 -7
- package/dist/commands/tokens/create.js.map +1 -1
- package/dist/commands/tokens/delete.js +2 -2
- package/dist/commands/tokens/delete.js.map +1 -1
- package/dist/commands/tokens/list.js +12 -11
- package/dist/commands/tokens/list.js.map +1 -1
- package/dist/commands/tokens/rotate.js +95 -0
- package/dist/commands/tokens/rotate.js.map +1 -0
- package/dist/commands/typegen/generate.js +222 -0
- package/dist/commands/typegen/generate.js.map +1 -0
- package/dist/commands/users/list.js +8 -8
- package/dist/commands/users/list.js.map +1 -1
- package/dist/exports/_internal.d.ts +29 -0
- package/dist/exports/_internal.js +1 -0
- package/dist/exports/_internal.js.map +1 -1
- package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js +6 -0
- package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js.map +1 -1
- package/dist/exports/invokeSanityCli/help.js +4 -0
- package/dist/exports/invokeSanityCli/help.js.map +1 -1
- package/dist/exports/invokeSanityCli/index.js +2 -0
- package/dist/exports/invokeSanityCli/index.js.map +1 -1
- package/dist/hooks/commandNotFound/topicAliases.js +13 -40
- package/dist/hooks/commandNotFound/topicAliases.js.map +1 -1
- package/dist/hooks/prerun/setupTelemetry.js +3 -2
- package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
- package/dist/server/vite/plugin-typegen.js +4 -16
- package/dist/server/vite/plugin-typegen.js.map +1 -1
- package/dist/services/assets.js +46 -0
- package/dist/services/assets.js.map +1 -0
- package/dist/services/tokens.js +81 -31
- package/dist/services/tokens.js.map +1 -1
- package/dist/topicAliases.js +43 -0
- package/dist/topicAliases.js.map +1 -1
- package/dist/util/parseArguments.js +7 -2
- package/dist/util/parseArguments.js.map +1 -1
- package/dist/util/readTokenFromStdin.js +17 -0
- package/dist/util/readTokenFromStdin.js.map +1 -0
- package/dist/util/responsiveTable.js +97 -0
- package/dist/util/responsiveTable.js.map +1 -0
- package/dist/util/telemetry/commandTelemetry.js +34 -0
- package/dist/util/telemetry/commandTelemetry.js.map +1 -0
- package/dist/util/unclaimedProjects.js +10 -0
- package/dist/util/unclaimedProjects.js.map +1 -1
- package/oclif.config.js +2 -4
- package/oclif.manifest.json +688 -476
- package/package.json +12 -10
- package/templates/shopify/components/inputs/ShopifyMetafield.tsx +20 -0
- package/templates/shopify/docs/features.md +24 -0
- package/templates/shopify/schemaTypes/index.ts +2 -0
- package/templates/shopify/schemaTypes/objects/shopify/shopifyCollectionType.ts +18 -1
- package/templates/shopify/schemaTypes/objects/shopify/shopifyMetafieldType.ts +47 -0
- package/templates/shopify/schemaTypes/objects/shopify/shopifyProductType.ts +17 -0
- package/templates/shopify/utils/formatMetafieldValue.ts +30 -0
- package/templates/shopify-online-storefront/components/inputs/ShopifyMetafield.tsx +22 -0
- package/templates/shopify-online-storefront/schemaTypes/index.ts +4 -0
- package/templates/shopify-online-storefront/schemaTypes/objects/shop.ts +16 -0
- package/templates/shopify-online-storefront/schemaTypes/objects/shopifyCollection.ts +19 -0
- package/templates/shopify-online-storefront/schemaTypes/objects/shopifyMetafield.ts +53 -0
- package/templates/shopify-online-storefront/schemaTypes/objects/shopifyProduct.ts +19 -0
- package/templates/shopify-online-storefront/utils/formatMetafieldValue.ts +30 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/tokens/list.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/tokens/list.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\n\nimport {type Robot} from '../../actions/tokens/types.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {getProjectMembership, getTokens} from '../../services/tokens.js'\nimport {Table} from '../../util/responsiveTable.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: Robot[]\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: exitCodes.RUNTIME_ERROR})\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', name: 'label', title: 'Label'},\n {alignment: 'left', name: 'id', title: 'ID'},\n {alignment: 'left', name: 'roles', title: 'Roles'},\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 = getProjectMembership(token, projectId)?.roleNames.join(', ') || 'No roles'\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":["Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","promptForProject","getProjectMembership","getTokens","Table","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","RUNTIME_ERROR","log","JSON","stringify","length","table","columns","alignment","name","title","token","roles","roleNames","join","addRow","expires","expiresAt","slice","id","label","render"],"mappings":"AAAA,SAAQA,KAAK,QAAO,cAAa;AACjC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AAGvD,SAAQC,gBAAgB,QAAO,oCAAmC;AAClE,SAAQC,oBAAoB,EAAEC,SAAS,QAAO,2BAA0B;AACxE,SAAQC,KAAK,QAAO,gCAA+B;AACnD,SAAQC,gBAAgB,QAAO,4BAA2B;AAE1D,MAAMC,iBAAiBP,SAAS;AAEhC,OAAO,MAAMQ,0BAA0BT;IACrC,OAAgBU,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,MAAMjB,MAAMkB,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,IACRrB,iBAAiB;oBACfsB,qBAAqB;wBAAC;4BAACC,OAAO;4BAAQC,YAAY;wBAAuB;qBAAE;gBAC7E;QACJ;QAEA,IAAIC;QACJ,IAAI;YACFA,SAAS,MAAMvB,UAAUiB;QAC3B,EAAE,OAAOO,OAAO;YACd,MAAMC,UAAU5B,gBAAgB2B;YAChCrB,eAAe,CAAC,kCAAkC,EAAEc,WAAW,EAAEO;YACjE,IAAI,CAACA,KAAK,CAAC,CAAC,8BAA8B,EAAEC,SAAS,EAAE;gBAACC,MAAMhC,UAAUiC,aAAa;YAAA;QACvF;QAEA,IAAIX,YAAY;YACd,IAAI,CAACY,GAAG,CAACC,KAAKC,SAAS,CAACP,QAAQ,MAAM;YACtC;QACF;QAEA,IAAIA,OAAOQ,MAAM,KAAK,GAAG;YACvB,IAAI,CAACH,GAAG,CAAC;YACT;QACF;QAEA,MAAMI,QAAQ,IAAI/B,MAAM;YACtBgC,SAAS;gBACP;oBAACC,WAAW;oBAAQC,MAAM;oBAASC,OAAO;gBAAO;gBACjD;oBAACF,WAAW;oBAAQC,MAAM;oBAAMC,OAAO;gBAAI;gBAC3C;oBAACF,WAAW;oBAAQC,MAAM;oBAASC,OAAO;gBAAO;gBACjD;oBAACF,WAAW;oBAAQC,MAAM;oBAAWC,OAAO;gBAAS;aACtD;YACDA,OAAO,CAAC,MAAM,EAAEb,OAAOQ,MAAM,CAAC,WAAW,CAAC;QAC5C;QAEA,KAAK,MAAMM,SAASd,OAAQ;YAC1B,MAAMe,QAAQvC,qBAAqBsC,OAAOpB,YAAYsB,UAAUC,KAAK,SAAS;YAE9ER,MAAMS,MAAM,CAAC;gBACXC,SAASL,MAAMM,SAAS,GAAGN,MAAMM,SAAS,CAACC,KAAK,CAAC,GAAG,MAAM;gBAC1DC,IAAIR,MAAMQ,EAAE;gBACZC,OAAOT,MAAMS,KAAK;gBAClBR;YACF;QACF;QAEA,IAAI,CAACV,GAAG,CAACI,MAAMe,MAAM;IACvB;AACF"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
|
|
3
|
+
import { getErrorMessage } from '@sanity/cli-core/errors';
|
|
4
|
+
import { isHttpError } from '@sanity/client';
|
|
5
|
+
import { rotateToken } from '../../services/tokens.js';
|
|
6
|
+
import { readTokenFromStdin } from '../../util/readTokenFromStdin.js';
|
|
7
|
+
const tokensRotateDebug = subdebug('tokens:rotate');
|
|
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
|
+
export class RotateTokenCommand extends SanityCommand {
|
|
10
|
+
static description = 'Rotate an API token, replacing its secret with a new one';
|
|
11
|
+
static examples = [
|
|
12
|
+
{
|
|
13
|
+
command: 'echo "$SANITY_TOKEN" | <%= config.bin %> <%= command.id %>',
|
|
14
|
+
description: 'Rotate the token piped on standard input'
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
command: '<%= config.bin %> <%= command.id %> < token.txt',
|
|
18
|
+
description: 'Rotate a token read from a file'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
command: 'echo "$SANITY_TOKEN" | <%= config.bin %> <%= command.id %> --json',
|
|
22
|
+
description: 'Output the rotated token as JSON'
|
|
23
|
+
}
|
|
24
|
+
];
|
|
25
|
+
static flags = {
|
|
26
|
+
json: Flags.boolean({
|
|
27
|
+
default: false,
|
|
28
|
+
description: 'Output as JSON'
|
|
29
|
+
}),
|
|
30
|
+
token: Flags.string({
|
|
31
|
+
char: 't',
|
|
32
|
+
description: 'Token to rotate (prefer standard input to keep it out of shell history)',
|
|
33
|
+
helpValue: '<token>'
|
|
34
|
+
})
|
|
35
|
+
};
|
|
36
|
+
static hiddenAliases = [
|
|
37
|
+
'token:rotate'
|
|
38
|
+
];
|
|
39
|
+
async run() {
|
|
40
|
+
const { flags } = await this.parse(RotateTokenCommand);
|
|
41
|
+
const { json } = flags;
|
|
42
|
+
const token = flags.token?.trim() || await this.readTokenArg();
|
|
43
|
+
try {
|
|
44
|
+
tokensRotateDebug('Rotating API token');
|
|
45
|
+
const robot = await rotateToken(token);
|
|
46
|
+
if (json) {
|
|
47
|
+
this.log(JSON.stringify(robot, null, 2));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
this.log('API token rotated');
|
|
51
|
+
this.log(`Label: ${robot.label}`);
|
|
52
|
+
this.log(`ID: ${robot.id}`);
|
|
53
|
+
if (robot.expiresAt) {
|
|
54
|
+
this.log(`Expires: ${robot.expiresAt}`);
|
|
55
|
+
}
|
|
56
|
+
this.log(`Token: ${robot.token}`);
|
|
57
|
+
this.log('');
|
|
58
|
+
this.log("Copy the token now. It won't be shown again.");
|
|
59
|
+
this.log('The previous token was revoked and no longer works.');
|
|
60
|
+
} catch (error) {
|
|
61
|
+
tokensRotateDebug('Error rotating token', error);
|
|
62
|
+
if (isHttpError(error) && error.statusCode === 401) {
|
|
63
|
+
this.error('Token is invalid, expired, or was already rotated or revoked. Check that you are passing the current token.', {
|
|
64
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
if (isHttpError(error) && error.statusCode === 403) {
|
|
68
|
+
this.error('The token is not an API token and cannot be rotated. Personal tokens are renewed by logging in again.', {
|
|
69
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
this.error(`Token rotation failed:\n${getErrorMessage(error)}`, {
|
|
73
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async readTokenArg() {
|
|
78
|
+
let token;
|
|
79
|
+
try {
|
|
80
|
+
token = await readTokenFromStdin(TOKEN_USAGE_HINT);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
return this.error(getErrorMessage(error), {
|
|
83
|
+
exit: exitCodes.USAGE_ERROR
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
if (!token) {
|
|
87
|
+
this.error(TOKEN_USAGE_HINT, {
|
|
88
|
+
exit: exitCodes.USAGE_ERROR
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return token;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//# sourceMappingURL=rotate.js.map
|
|
@@ -0,0 +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 json: Flags.boolean({\n default: false,\n description: 'Output as JSON',\n }),\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.log(JSON.stringify(robot, null, 2))\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","examples","command","flags","json","boolean","default","token","string","char","helpValue","hiddenAliases","run","parse","trim","readTokenArg","robot","log","JSON","stringify","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,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ;QACtBC,MAAMf,MAAMgB,OAAO,CAAC;YAClBC,SAAS;YACTN,aAAa;QACf;QACAO,OAAOlB,MAAMmB,MAAM,CAAC;YAClBC,MAAM;YACNT,aAAa;YACbU,WAAW;QACb;IACF,EAAC;IAED,OAAgBC,gBAA0B;QAAC;KAAe,CAAA;IAE1D,MAAaC,MAAqB;QAChC,MAAM,EAACT,KAAK,EAAC,GAAG,MAAM,IAAI,CAACU,KAAK,CAACd;QACjC,MAAM,EAACK,IAAI,EAAC,GAAGD;QAEf,MAAMI,QAAQJ,MAAMI,KAAK,EAAEO,UAAW,MAAM,IAAI,CAACC,YAAY;QAE7D,IAAI;YACFlB,kBAAkB;YAClB,MAAMmB,QAAQ,MAAMrB,YAAYY;YAEhC,IAAIH,MAAM;gBACR,IAAI,CAACa,GAAG,CAACC,KAAKC,SAAS,CAACH,OAAO,MAAM;gBACrC;YACF;YAEA,IAAI,CAACC,GAAG,CAAC;YACT,IAAI,CAACA,GAAG,CAAC,CAAC,OAAO,EAAED,MAAMI,KAAK,EAAE;YAChC,IAAI,CAACH,GAAG,CAAC,CAAC,IAAI,EAAED,MAAMK,EAAE,EAAE;YAC1B,IAAIL,MAAMM,SAAS,EAAE;gBACnB,IAAI,CAACL,GAAG,CAAC,CAAC,SAAS,EAAED,MAAMM,SAAS,EAAE;YACxC;YACA,IAAI,CAACL,GAAG,CAAC,CAAC,OAAO,EAAED,MAAMT,KAAK,EAAE;YAChC,IAAI,CAACU,GAAG,CAAC;YACT,IAAI,CAACA,GAAG,CAAC;YACT,IAAI,CAACA,GAAG,CAAC;QACX,EAAE,OAAOM,OAAO;YACd1B,kBAAkB,wBAAwB0B;YAE1C,IAAI7B,YAAY6B,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CACR,+GACA;oBAACE,MAAMnC,UAAUoC,aAAa;gBAAA;YAElC;YACA,IAAIhC,YAAY6B,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CACR,yGACA;oBAACE,MAAMnC,UAAUoC,aAAa;gBAAA;YAElC;YAEA,IAAI,CAACH,KAAK,CAAC,CAAC,wBAAwB,EAAE9B,gBAAgB8B,QAAQ,EAAE;gBAC9DE,MAAMnC,UAAUoC,aAAa;YAC/B;QACF;IACF;IAEA,MAAcX,eAAgC;QAC5C,IAAIR;QACJ,IAAI;YACFA,QAAQ,MAAMX,mBAAmBE;QACnC,EAAE,OAAOyB,OAAO;YACd,OAAO,IAAI,CAACA,KAAK,CAAC9B,gBAAgB8B,QAAQ;gBAACE,MAAMnC,UAAUqC,WAAW;YAAA;QACxE;QAEA,IAAI,CAACpB,OAAO;YACV,IAAI,CAACgB,KAAK,CAACzB,kBAAkB;gBAAC2B,MAAMnC,UAAUqC,WAAW;YAAA;QAC3D;QAEA,OAAOpB;IACT;AACF"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { stat } from 'node:fs/promises';
|
|
2
|
+
import { styleText } from 'node:util';
|
|
3
|
+
import { Flags } from '@oclif/core';
|
|
4
|
+
import { CLIError } from '@oclif/core/errors';
|
|
5
|
+
import { SanityCommand } from '@sanity/cli-core';
|
|
6
|
+
import { spinner } from '@sanity/cli-core/ux';
|
|
7
|
+
import { configDefinition, readConfig, runTypegenGenerate, runTypegenWatcher, TypegenWatchModeTrace, TypesGeneratedTrace } from '@sanity/codegen';
|
|
8
|
+
import omit from 'lodash-es/omit.js';
|
|
9
|
+
import once from 'lodash-es/once.js';
|
|
10
|
+
import { createTypegenProgressRenderer } from '../../actions/typegen/renderTypegenProgress.js';
|
|
11
|
+
const description = `Sanity TypeGen
|
|
12
|
+
|
|
13
|
+
${styleText('bold', 'Configuration:')}
|
|
14
|
+
This command can utilize configuration settings defined in a \`sanity-typegen.json\` file. These settings include:
|
|
15
|
+
|
|
16
|
+
- "path": Specifies a glob pattern to locate your TypeScript or JavaScript files.
|
|
17
|
+
Default: "./src/**/*.{ts,tsx,js,jsx}"
|
|
18
|
+
|
|
19
|
+
- "schema": Defines the path to your Sanity schema file. This file should be generated using the \`sanity schema extract\` command.
|
|
20
|
+
Default: "schema.json"
|
|
21
|
+
|
|
22
|
+
- "generates": Indicates the path where the generated TypeScript type definitions will be saved.
|
|
23
|
+
Default: "./sanity.types.ts"
|
|
24
|
+
|
|
25
|
+
The 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.
|
|
26
|
+
|
|
27
|
+
${styleText('bold', 'Note:')}
|
|
28
|
+
- 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.`.trim();
|
|
29
|
+
export class TypegenGenerateCommand extends SanityCommand {
|
|
30
|
+
static description = description;
|
|
31
|
+
static examples = [
|
|
32
|
+
{
|
|
33
|
+
command: '<%= config.bin %> <%= command.id %>',
|
|
34
|
+
description: `Generate TypeScript type definitions from a Sanity Studio schema extracted using the \`sanity schema extract\` command.`
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
static flags = {
|
|
38
|
+
'config-path': Flags.string({
|
|
39
|
+
description: '[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.'
|
|
40
|
+
}),
|
|
41
|
+
watch: Flags.boolean({
|
|
42
|
+
default: false,
|
|
43
|
+
description: '[Default: false] Run the typegen in watch mode'
|
|
44
|
+
})
|
|
45
|
+
};
|
|
46
|
+
static hiddenAliases = [
|
|
47
|
+
'typegen:generate'
|
|
48
|
+
];
|
|
49
|
+
async run() {
|
|
50
|
+
const { flags } = await this.parse(TypegenGenerateCommand);
|
|
51
|
+
if (flags.watch) {
|
|
52
|
+
await this.runWatcher();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
await this.runSingle();
|
|
56
|
+
}
|
|
57
|
+
async getConfig() {
|
|
58
|
+
const spin = spinner({}).start('Loading config…');
|
|
59
|
+
try {
|
|
60
|
+
const { flags } = await this.parse(TypegenGenerateCommand);
|
|
61
|
+
const rootDir = await this.getProjectRoot();
|
|
62
|
+
const config = await this.getCliConfig();
|
|
63
|
+
const configPath = flags['config-path'];
|
|
64
|
+
const workDir = rootDir.directory;
|
|
65
|
+
const legacyConfigPath = configPath || 'sanity-typegen.json';
|
|
66
|
+
let hasLegacyConfig = false;
|
|
67
|
+
try {
|
|
68
|
+
const file = await stat(legacyConfigPath);
|
|
69
|
+
hasLegacyConfig = file.isFile();
|
|
70
|
+
} catch (err) {
|
|
71
|
+
if (err instanceof Error && 'code' in err && err.code === 'ENOENT' && configPath) {
|
|
72
|
+
spin.fail();
|
|
73
|
+
this.error(`Typegen config file not found: ${configPath}`, {
|
|
74
|
+
exit: 1
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
if (err instanceof Error && 'code' in err && err.code !== 'ENOENT') {
|
|
78
|
+
spin.fail();
|
|
79
|
+
this.error(`Error when checking if typegen config file exists: ${legacyConfigPath}`, {
|
|
80
|
+
exit: 1
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (config?.typegen && hasLegacyConfig) {
|
|
85
|
+
spin.warn(styleText('yellow', `You've specified typegen in your Sanity CLI config, but also have a typegen config.
|
|
86
|
+
|
|
87
|
+
The config from the Sanity CLI config is used.
|
|
88
|
+
`));
|
|
89
|
+
return {
|
|
90
|
+
config: configDefinition.parse(config.typegen || {}),
|
|
91
|
+
path: rootDir.path,
|
|
92
|
+
type: 'cli',
|
|
93
|
+
workDir
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (hasLegacyConfig) {
|
|
97
|
+
spin.warn(styleText('yellow', `The separate typegen config has been deprecated. Use \`typegen\` in the sanity CLI config instead.
|
|
98
|
+
|
|
99
|
+
See: https://www.sanity.io/docs/help/configuring-typegen-in-sanity-cli-config`));
|
|
100
|
+
return {
|
|
101
|
+
config: await readConfig(legacyConfigPath),
|
|
102
|
+
path: legacyConfigPath,
|
|
103
|
+
type: 'legacy',
|
|
104
|
+
workDir
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
spin.succeed(`Config loaded from sanity.cli.ts`);
|
|
108
|
+
return {
|
|
109
|
+
config: configDefinition.parse(config.typegen || {}),
|
|
110
|
+
path: rootDir.path,
|
|
111
|
+
type: 'cli',
|
|
112
|
+
workDir
|
|
113
|
+
};
|
|
114
|
+
} catch (err) {
|
|
115
|
+
// The config-file checks above already reported a user-facing error via
|
|
116
|
+
// `this.error()` (an oclif CLIError). Re-throw those as-is instead of
|
|
117
|
+
// wrapping them a second time and failing the spinner twice.
|
|
118
|
+
if (err instanceof CLIError) throw err;
|
|
119
|
+
spin.fail();
|
|
120
|
+
this.error(`An error occurred during config loading: ${err}`, {
|
|
121
|
+
exit: 1
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async runSingle() {
|
|
126
|
+
const trace = this.telemetry.trace(TypesGeneratedTrace);
|
|
127
|
+
let spin;
|
|
128
|
+
try {
|
|
129
|
+
const { config: typegenConfig, type: typegenConfigMethod, workDir } = await this.getConfig();
|
|
130
|
+
trace.start();
|
|
131
|
+
spin = spinner({}).start('Loading schema…');
|
|
132
|
+
const result = await runTypegenGenerate({
|
|
133
|
+
config: typegenConfig,
|
|
134
|
+
onProgress: createTypegenProgressRenderer(spin, {
|
|
135
|
+
formatGeneratedCode: typegenConfig.formatGeneratedCode,
|
|
136
|
+
generates: typegenConfig.generates,
|
|
137
|
+
schema: typegenConfig.schema
|
|
138
|
+
}),
|
|
139
|
+
workDir
|
|
140
|
+
});
|
|
141
|
+
const traceStats = omit(result, 'code', 'duration');
|
|
142
|
+
trace.log({
|
|
143
|
+
configMethod: typegenConfigMethod,
|
|
144
|
+
configOverloadClientMethods: typegenConfig.overloadClientMethods,
|
|
145
|
+
...traceStats
|
|
146
|
+
});
|
|
147
|
+
trace.complete();
|
|
148
|
+
} catch (error) {
|
|
149
|
+
if (spin?.isSpinning) {
|
|
150
|
+
spin.fail();
|
|
151
|
+
}
|
|
152
|
+
trace.error(error instanceof Error ? error : new Error(String(error)));
|
|
153
|
+
this.error(`${error instanceof Error ? error.message : 'Unknown error'}`, {
|
|
154
|
+
exit: 1
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
async runWatcher() {
|
|
159
|
+
const trace = this.telemetry.trace(TypegenWatchModeTrace);
|
|
160
|
+
let spin;
|
|
161
|
+
try {
|
|
162
|
+
const { config: typegenConfig, workDir } = await this.getConfig();
|
|
163
|
+
trace.start();
|
|
164
|
+
let resolve = ()=>{};
|
|
165
|
+
const promise = new Promise((res)=>{
|
|
166
|
+
resolve = res;
|
|
167
|
+
});
|
|
168
|
+
const watchSpin = spinner({}).start('Loading schema…');
|
|
169
|
+
spin = watchSpin;
|
|
170
|
+
const rendererContext = {
|
|
171
|
+
formatGeneratedCode: typegenConfig.formatGeneratedCode,
|
|
172
|
+
generates: typegenConfig.generates,
|
|
173
|
+
schema: typegenConfig.schema
|
|
174
|
+
};
|
|
175
|
+
let renderProgress = createTypegenProgressRenderer(watchSpin, rendererContext);
|
|
176
|
+
const typegenWatcher = runTypegenWatcher({
|
|
177
|
+
config: typegenConfig,
|
|
178
|
+
onProgress: (event)=>{
|
|
179
|
+
// 'schemaLoaded' is the first event of every generation cycle; the
|
|
180
|
+
// renderer accumulates per-run state, so start each cycle fresh.
|
|
181
|
+
if (event.type === 'schemaLoaded') {
|
|
182
|
+
renderProgress = createTypegenProgressRenderer(watchSpin, rendererContext);
|
|
183
|
+
}
|
|
184
|
+
renderProgress(event);
|
|
185
|
+
},
|
|
186
|
+
workDir
|
|
187
|
+
});
|
|
188
|
+
const stop = once(async ()=>{
|
|
189
|
+
process.off('SIGINT', stop);
|
|
190
|
+
process.off('SIGTERM', stop);
|
|
191
|
+
if (watchSpin.isSpinning) {
|
|
192
|
+
watchSpin.stop();
|
|
193
|
+
}
|
|
194
|
+
trace.log({
|
|
195
|
+
step: 'stopped',
|
|
196
|
+
...typegenWatcher.getStats()
|
|
197
|
+
});
|
|
198
|
+
trace.complete();
|
|
199
|
+
try {
|
|
200
|
+
await typegenWatcher.stop();
|
|
201
|
+
} catch {
|
|
202
|
+
// We're shutting down; a failure to close the watcher shouldn't hang
|
|
203
|
+
// the process or surface as an unhandled rejection.
|
|
204
|
+
}
|
|
205
|
+
resolve();
|
|
206
|
+
});
|
|
207
|
+
process.on('SIGINT', stop);
|
|
208
|
+
process.on('SIGTERM', stop);
|
|
209
|
+
await promise;
|
|
210
|
+
} catch (error) {
|
|
211
|
+
if (spin?.isSpinning) {
|
|
212
|
+
spin.fail();
|
|
213
|
+
}
|
|
214
|
+
trace.error(error instanceof Error ? error : new Error(String(error)));
|
|
215
|
+
this.error(`${error instanceof Error ? error.message : 'Unknown error'}`, {
|
|
216
|
+
exit: 1
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +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 {SanityCommand} from '@sanity/cli-core'\nimport {spinner, type SpinnerInstance} from '@sanity/cli-core/ux'\nimport {\n configDefinition,\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 {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.`.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 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}`, {exit: 1})\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: 1,\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 return {\n config: configDefinition.parse(config.typegen || {}),\n path: rootDir.path,\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 spin.succeed(`Config loaded from sanity.cli.ts`)\n\n return {\n config: configDefinition.parse(config.typegen || {}),\n path: rootDir.path,\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}`, {exit: 1})\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 {config: typegenConfig, type: typegenConfigMethod, workDir} = await this.getConfig()\n trace.start()\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'}`, {exit: 1})\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, 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({}).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 this.error(`${error instanceof Error ? error.message : 'Unknown error'}`, {exit: 1})\n }\n }\n}\n"],"names":["stat","styleText","Flags","CLIError","SanityCommand","spinner","configDefinition","readConfig","runTypegenGenerate","runTypegenWatcher","TypegenWatchModeTrace","TypesGeneratedTrace","omit","once","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","typegen","warn","path","type","succeed","trace","telemetry","typegenConfig","typegenConfigMethod","result","onProgress","formatGeneratedCode","generates","schema","traceStats","log","configMethod","configOverloadClientMethods","overloadClientMethods","complete","isSpinning","String","message","resolve","promise","Promise","res","watchSpin","rendererContext","renderProgress","typegenWatcher","event","stop","process","off","step","getStats","on"],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
2
|
import { Flags } from '@oclif/core';
|
|
3
3
|
import { SanityCommand } from '@sanity/cli-core';
|
|
4
|
-
import { Table } from 'console-table-printer';
|
|
5
4
|
import sortBy from 'lodash-es/sortBy.js';
|
|
6
5
|
import { getMembersForProject } from '../../actions/users/getMembersForProject.js';
|
|
7
6
|
import { promptForProject } from '../../prompts/promptForProject.js';
|
|
7
|
+
import { Table } from '../../util/responsiveTable.js';
|
|
8
8
|
import { getProjectIdFlag } from '../../util/sharedFlags.js';
|
|
9
9
|
const sortFields = [
|
|
10
10
|
'id',
|
|
@@ -105,35 +105,35 @@ export class List extends SanityCommand {
|
|
|
105
105
|
]), [
|
|
106
106
|
sortFields.indexOf(sort)
|
|
107
107
|
]);
|
|
108
|
-
const rows = order === 'asc' ? ordered : ordered.toReversed()
|
|
108
|
+
const rows = (order === 'asc' ? ordered : ordered.toReversed()).map(([id, name, roles, date])=>[
|
|
109
|
+
id,
|
|
110
|
+
name,
|
|
111
|
+
roles,
|
|
112
|
+
date.split('T')[0]
|
|
113
|
+
]);
|
|
109
114
|
const table = new Table({
|
|
110
115
|
columns: [
|
|
111
116
|
{
|
|
112
117
|
alignment: 'left',
|
|
113
|
-
maxLen: 30,
|
|
114
118
|
name: 'id',
|
|
115
119
|
title: 'ID'
|
|
116
120
|
},
|
|
117
121
|
{
|
|
118
122
|
alignment: 'left',
|
|
119
|
-
maxLen: 40,
|
|
120
123
|
name: 'name',
|
|
121
124
|
title: 'Name'
|
|
122
125
|
},
|
|
123
126
|
{
|
|
124
127
|
alignment: 'left',
|
|
125
|
-
maxLen: 30,
|
|
126
128
|
name: 'roles',
|
|
127
129
|
title: 'Roles'
|
|
128
130
|
},
|
|
129
131
|
{
|
|
130
132
|
alignment: 'left',
|
|
131
|
-
maxLen: 12,
|
|
132
133
|
name: 'date',
|
|
133
134
|
title: 'Date'
|
|
134
135
|
}
|
|
135
|
-
]
|
|
136
|
-
rowSeparator: true
|
|
136
|
+
]
|
|
137
137
|
});
|
|
138
138
|
for (const [id, name, roles, date] of rows){
|
|
139
139
|
const isPending = id === '<pending>';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/users/list.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\nimport
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/users/list.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\nimport sortBy from 'lodash-es/sortBy.js'\n\nimport {getMembersForProject} from '../../actions/users/getMembersForProject.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {Table} from '../../util/responsiveTable.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst sortFields = ['id', 'name', 'role', 'date']\n\nfunction dimText(value: string, isDim: boolean): string {\n return isDim ? styleText('dim', value) : value\n}\n\nexport class List extends SanityCommand<typeof List> {\n static override description = 'List project members'\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List all users of the project',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --no-invitations --no-robots',\n description: 'List all users of the project, but exclude pending invitations and robots',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --sort role',\n description: 'List all users, sorted by role',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --project-id abc123',\n description: 'List users for a specific project',\n },\n ]\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to list users for',\n semantics: 'override',\n }),\n invitations: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Includes or excludes pending invitations',\n }),\n order: Flags.string({\n default: 'asc',\n description: 'Sort output ascending/descending',\n options: ['asc', 'desc'],\n }),\n robots: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Includes or excludes robots (token users)',\n }),\n sort: Flags.string({\n default: 'date',\n description: 'Sort users by specified column',\n options: ['id', 'name', 'role', 'date'],\n }),\n }\n\n static override hiddenAliases: string[] = ['user:list']\n\n public async run(): Promise<void> {\n const {invitations, order, robots, sort} = this.flags\n\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [\n {grant: 'read', permission: 'sanity.project'},\n {grant: 'read', permission: 'sanity.project.members'},\n ],\n }),\n })\n\n const members = await getMembersForProject({\n includeInvitations: invitations,\n includeRobots: robots,\n projectId,\n })\n\n if (members.length === 0) {\n this.log('No members found for this project.')\n return\n }\n\n const ordered = sortBy(\n members.map(({date, id, name, roles}) => [\n id,\n name,\n roles\n ?.map((role) => role.title)\n .join(', ')\n .trim() || '-',\n date,\n ]),\n [sortFields.indexOf(sort)],\n )\n\n const rows = (order === 'asc' ? ordered : ordered.toReversed()).map(\n ([id, name, roles, date]) => [id, name, roles, date.split('T')[0]],\n )\n\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'id', title: 'ID'},\n {alignment: 'left', name: 'name', title: 'Name'},\n {alignment: 'left', name: 'roles', title: 'Roles'},\n {alignment: 'left', name: 'date', title: 'Date'},\n ],\n })\n\n for (const [id, name, roles, date] of rows) {\n const isPending = id === '<pending>'\n table.addRow({\n date: dimText(date, isPending),\n id: dimText(id, isPending),\n name: dimText(name, isPending),\n roles: dimText(roles, isPending),\n })\n }\n\n this.log(table.render())\n }\n}\n"],"names":["styleText","Flags","SanityCommand","sortBy","getMembersForProject","promptForProject","Table","getProjectIdFlag","sortFields","dimText","value","isDim","List","description","examples","command","flags","semantics","invitations","boolean","allowNo","default","order","string","options","robots","sort","hiddenAliases","run","projectId","getProjectId","fallback","requiredPermissions","grant","permission","members","includeInvitations","includeRobots","length","log","ordered","map","date","id","name","roles","role","title","join","trim","indexOf","rows","toReversed","split","table","columns","alignment","isPending","addRow","render"],"mappings":"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"}
|
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
import { getStudioEnvironmentVariables } from "@sanity/cli-build/_internal/env";
|
|
2
|
+
import { Interfaces } from "@oclif/core";
|
|
2
3
|
import { Schema } from "@sanity/types";
|
|
3
4
|
import { StudioEnvVariablesOptions } from "@sanity/cli-build/_internal/env";
|
|
4
5
|
|
|
6
|
+
/** @internal */
|
|
7
|
+
export declare interface CommandTelemetry {
|
|
8
|
+
redactedFlags: readonly RedactedFlag[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare type CommandTelemetryConfig<Flags extends Interfaces.FlagInput> = {
|
|
12
|
+
redact?: readonly OptionFlagName<Flags>[];
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/** @internal */
|
|
16
|
+
export declare function defineCommandTelemetry<
|
|
17
|
+
const Flags extends Interfaces.FlagInput,
|
|
18
|
+
>(flags: Flags, config: CommandTelemetryConfig<Flags>): CommandTelemetry;
|
|
19
|
+
|
|
5
20
|
/**
|
|
6
21
|
* Extracts all serializable properties from userland schema types,
|
|
7
22
|
* so they best-effort can be used as definitions for Schema.compile.
|
|
@@ -85,6 +100,20 @@ declare type ManifestValidationRule = {
|
|
|
85
100
|
flag: string;
|
|
86
101
|
};
|
|
87
102
|
|
|
103
|
+
declare type OptionFlagName<Flags extends Interfaces.FlagInput> = string &
|
|
104
|
+
{
|
|
105
|
+
[Name in keyof Flags]: Flags[Name] extends {
|
|
106
|
+
type: "option";
|
|
107
|
+
}
|
|
108
|
+
? Name
|
|
109
|
+
: never;
|
|
110
|
+
}[keyof Flags];
|
|
111
|
+
|
|
112
|
+
declare interface RedactedFlag {
|
|
113
|
+
canonical: string;
|
|
114
|
+
flags: readonly string[];
|
|
115
|
+
}
|
|
116
|
+
|
|
88
117
|
export { StudioEnvVariablesOptions };
|
|
89
118
|
|
|
90
119
|
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { extractManifestSchemaTypes } from '../actions/manifest/extractWorkspaceManifest.js';
|
|
2
|
+
export { defineCommandTelemetry } from '../util/telemetry/commandTelemetry.js';
|
|
2
3
|
export { getStudioEnvironmentVariables } from '@sanity/cli-build/_internal/env';
|
|
3
4
|
|
|
4
5
|
//# sourceMappingURL=_internal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/_internal.ts"],"sourcesContent":["export {extractManifestSchemaTypes} from '../actions/manifest/extractWorkspaceManifest.js'\nexport {\n getStudioEnvironmentVariables,\n type StudioEnvVariablesOptions,\n} from '@sanity/cli-build/_internal/env'\n"],"names":["extractManifestSchemaTypes","getStudioEnvironmentVariables"],"mappings":"AAAA,SAAQA,0BAA0B,QAAO,kDAAiD;AAC1F,SACEC,6BAA6B,QAExB,kCAAiC"}
|
|
1
|
+
{"version":3,"sources":["../../src/exports/_internal.ts"],"sourcesContent":["export {extractManifestSchemaTypes} from '../actions/manifest/extractWorkspaceManifest.js'\nexport {type CommandTelemetry, defineCommandTelemetry} from '../util/telemetry/commandTelemetry.js'\nexport {\n getStudioEnvironmentVariables,\n type StudioEnvVariablesOptions,\n} from '@sanity/cli-build/_internal/env'\n"],"names":["extractManifestSchemaTypes","defineCommandTelemetry","getStudioEnvironmentVariables"],"mappings":"AAAA,SAAQA,0BAA0B,QAAO,kDAAiD;AAC1F,SAA+BC,sBAAsB,QAAO,wCAAuC;AACnG,SACEC,6BAA6B,QAExB,kCAAiC"}
|
|
@@ -44,6 +44,8 @@ function apiValidator({ args, flags }) {
|
|
|
44
44
|
],
|
|
45
45
|
validate: apiValidator
|
|
46
46
|
}),
|
|
47
|
+
// Reads a file from the machine running the command and must only run locally.
|
|
48
|
+
'assets:upload': deny,
|
|
47
49
|
'backups:disable': allow,
|
|
48
50
|
// Writes a downloaded backup to the local filesystem.
|
|
49
51
|
'backups:download': deny,
|
|
@@ -175,6 +177,10 @@ function apiValidator({ args, flags }) {
|
|
|
175
177
|
'tokens:delete': deny,
|
|
176
178
|
// Exposes authentication credential metadata.
|
|
177
179
|
'tokens:list': deny,
|
|
180
|
+
// Replaces authentication credentials and exposes the new secret.
|
|
181
|
+
'tokens:rotate': deny,
|
|
182
|
+
// Reads the local schema and source files and writes generated types to the project.
|
|
183
|
+
'typegen:generate': deny,
|
|
178
184
|
// Loads local CLI and workbench configuration to identify the deployed Studio or application.
|
|
179
185
|
undeploy: deny,
|
|
180
186
|
// Grants a user access to a project.
|