@sanity/cli 8.21.0 → 8.22.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 +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/deployStudioSchemasAndManifestsWorker.js +6 -15
- package/dist/actions/deploy/deployStudioSchemasAndManifestsWorker.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/deploySchemas.js.map +1 -1
- package/dist/actions/schema/extractSchemaWatcher.js +69 -14
- package/dist/actions/schema/extractSchemaWatcher.js.map +1 -1
- package/dist/actions/schema/listSchemas.js +2 -3
- package/dist/actions/schema/listSchemas.js.map +1 -1
- package/dist/actions/schema/updateWorkspaceSchema.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/list.js +2 -6
- 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/telemetry/init.telemetry.js.map +1 -1
- package/oclif.manifest.json +2340 -2311
- package/package.json +6 -5
|
@@ -1,4 +1,3 @@
|
|
|
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
3
|
import { MissingOrganizationError, resolveOrganizationId } from '../../actions/context/resolveOrganizationId.js';
|
|
@@ -8,6 +7,7 @@ import { getOrganizationFlag } from '../../util/sharedFlags.js';
|
|
|
8
7
|
const listContextDebug = subdebug('context:list');
|
|
9
8
|
export class ListKnowledgeBasesCommand extends SanityCommand {
|
|
10
9
|
static description = 'List knowledge bases in an organization';
|
|
10
|
+
static enableJsonFlag = true;
|
|
11
11
|
static examples = [
|
|
12
12
|
{
|
|
13
13
|
command: '<%= config.bin %> <%= command.id %>',
|
|
@@ -26,10 +26,6 @@ export class ListKnowledgeBasesCommand extends SanityCommand {
|
|
|
26
26
|
...getOrganizationFlag({
|
|
27
27
|
description: 'Organization to list knowledge bases for',
|
|
28
28
|
semantics: 'override'
|
|
29
|
-
}),
|
|
30
|
-
json: Flags.boolean({
|
|
31
|
-
default: false,
|
|
32
|
-
description: 'Output knowledge bases in JSON format'
|
|
33
29
|
})
|
|
34
30
|
};
|
|
35
31
|
async run() {
|
|
@@ -57,7 +53,7 @@ export class ListKnowledgeBasesCommand extends SanityCommand {
|
|
|
57
53
|
});
|
|
58
54
|
}
|
|
59
55
|
if (json) {
|
|
60
|
-
this.
|
|
56
|
+
this.logJson(knowledgeBases);
|
|
61
57
|
return;
|
|
62
58
|
}
|
|
63
59
|
if (knowledgeBases.length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/context/list.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/context/list.ts"],"sourcesContent":["import {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\n\nimport {\n MissingOrganizationError,\n resolveOrganizationId,\n} from '../../actions/context/resolveOrganizationId.js'\nimport {listKnowledgeBases} from '../../services/context.js'\nimport {Table} from '../../util/responsiveTable.js'\nimport {getOrganizationFlag} from '../../util/sharedFlags.js'\n\nconst listContextDebug = subdebug('context:list')\n\nexport class ListKnowledgeBasesCommand extends SanityCommand<typeof ListKnowledgeBasesCommand> {\n static override description = 'List knowledge bases in an organization'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List knowledge bases, selecting the organization interactively',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --organization org-abc123',\n description: 'List knowledge bases in a specific organization',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --organization org-abc123 --json',\n description: 'Output knowledge bases as JSON',\n },\n ]\n\n static override flags = {\n ...getOrganizationFlag({\n description: 'Organization to list knowledge bases for',\n semantics: 'override',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {json, organization} = this.flags\n\n let organizationId: string\n try {\n organizationId = await resolveOrganizationId({\n configuredOrganizationId: (await this.tryGetCliConfig()).app?.organizationId,\n flagOrganizationId: organization,\n unattended: this.isUnattended(),\n })\n } catch (error) {\n listContextDebug('Error resolving organization', error)\n this.error(getErrorMessage(error), {\n exit:\n error instanceof MissingOrganizationError\n ? exitCodes.USAGE_ERROR\n : exitCodes.RUNTIME_ERROR,\n })\n }\n\n let knowledgeBases\n try {\n knowledgeBases = await listKnowledgeBases(organizationId)\n } catch (error) {\n listContextDebug('Error listing knowledge bases', error)\n this.error(`Failed to list knowledge bases: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (json) {\n this.logJson(knowledgeBases)\n return\n }\n\n if (knowledgeBases.length === 0) {\n this.log('No knowledge bases found')\n return\n }\n\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'id', title: 'ID'},\n {alignment: 'left', name: 'title', title: 'Title'},\n {alignment: 'left', name: 'state', title: 'State'},\n {alignment: 'right', name: 'openIssues', title: 'Open issues'},\n {alignment: 'left', name: 'updatedAt', title: 'Updated'},\n ],\n })\n\n for (const {openIssueCount, publicId, state, title, updatedAt} of knowledgeBases) {\n table.addRow({id: publicId, openIssues: openIssueCount, state, title, updatedAt})\n }\n\n this.log(table.render())\n }\n}\n"],"names":["exitCodes","SanityCommand","subdebug","getErrorMessage","MissingOrganizationError","resolveOrganizationId","listKnowledgeBases","Table","getOrganizationFlag","listContextDebug","ListKnowledgeBasesCommand","description","enableJsonFlag","examples","command","flags","semantics","run","json","organization","organizationId","configuredOrganizationId","tryGetCliConfig","app","flagOrganizationId","unattended","isUnattended","error","exit","USAGE_ERROR","RUNTIME_ERROR","knowledgeBases","logJson","length","log","table","columns","alignment","name","title","openIssueCount","publicId","state","updatedAt","addRow","id","openIssues","render"],"mappings":"AACA,SAAQA,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AAEvD,SACEC,wBAAwB,EACxBC,qBAAqB,QAChB,iDAAgD;AACvD,SAAQC,kBAAkB,QAAO,4BAA2B;AAC5D,SAAQC,KAAK,QAAO,gCAA+B;AACnD,SAAQC,mBAAmB,QAAO,4BAA2B;AAE7D,MAAMC,mBAAmBP,SAAS;AAElC,OAAO,MAAMQ,kCAAkCT;IAC7C,OAAgBU,cAAc,0CAAyC;IAEvE,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;QACtB,GAAGP,oBAAoB;YACrBG,aAAa;YACbK,WAAW;QACb,EAAE;IACJ,EAAqB;IAErB,MAAaC,MAAqB;QAChC,MAAM,EAACC,IAAI,EAAEC,YAAY,EAAC,GAAG,IAAI,CAACJ,KAAK;QAEvC,IAAIK;QACJ,IAAI;YACFA,iBAAiB,MAAMf,sBAAsB;gBAC3CgB,0BAA0B,AAAC,CAAA,MAAM,IAAI,CAACC,eAAe,EAAC,EAAGC,GAAG,EAAEH;gBAC9DI,oBAAoBL;gBACpBM,YAAY,IAAI,CAACC,YAAY;YAC/B;QACF,EAAE,OAAOC,OAAO;YACdlB,iBAAiB,gCAAgCkB;YACjD,IAAI,CAACA,KAAK,CAACxB,gBAAgBwB,QAAQ;gBACjCC,MACED,iBAAiBvB,2BACbJ,UAAU6B,WAAW,GACrB7B,UAAU8B,aAAa;YAC/B;QACF;QAEA,IAAIC;QACJ,IAAI;YACFA,iBAAiB,MAAMzB,mBAAmBc;QAC5C,EAAE,OAAOO,OAAO;YACdlB,iBAAiB,iCAAiCkB;YAClD,IAAI,CAACA,KAAK,CAAC,CAAC,gCAAgC,EAAExB,gBAAgBwB,QAAQ,EAAE;gBACtEC,MAAM5B,UAAU8B,aAAa;YAC/B;QACF;QAEA,IAAIZ,MAAM;YACR,IAAI,CAACc,OAAO,CAACD;YACb;QACF;QAEA,IAAIA,eAAeE,MAAM,KAAK,GAAG;YAC/B,IAAI,CAACC,GAAG,CAAC;YACT;QACF;QAEA,MAAMC,QAAQ,IAAI5B,MAAM;YACtB6B,SAAS;gBACP;oBAACC,WAAW;oBAAQC,MAAM;oBAAMC,OAAO;gBAAI;gBAC3C;oBAACF,WAAW;oBAAQC,MAAM;oBAASC,OAAO;gBAAO;gBACjD;oBAACF,WAAW;oBAAQC,MAAM;oBAASC,OAAO;gBAAO;gBACjD;oBAACF,WAAW;oBAASC,MAAM;oBAAcC,OAAO;gBAAa;gBAC7D;oBAACF,WAAW;oBAAQC,MAAM;oBAAaC,OAAO;gBAAS;aACxD;QACH;QAEA,KAAK,MAAM,EAACC,cAAc,EAAEC,QAAQ,EAAEC,KAAK,EAAEH,KAAK,EAAEI,SAAS,EAAC,IAAIZ,eAAgB;YAChFI,MAAMS,MAAM,CAAC;gBAACC,IAAIJ;gBAAUK,YAAYN;gBAAgBE;gBAAOH;gBAAOI;YAAS;QACjF;QAEA,IAAI,CAACT,GAAG,CAACC,MAAMY,MAAM;IACvB;AACF"}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -16,6 +16,7 @@ export class DeployCommand extends SanityCommand {
|
|
|
16
16
|
})
|
|
17
17
|
};
|
|
18
18
|
static description = 'Builds and deploys Sanity Studio or application to Sanity hosting';
|
|
19
|
+
static enableJsonFlag = true;
|
|
19
20
|
static examples = [
|
|
20
21
|
{
|
|
21
22
|
command: '<%= config.bin %> <%= command.id %>',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {getWorkbench, resolveWorkbenchConfig} from '@sanity/workbench-cli/deploy'\n\nimport {deployApp} from '../actions/deploy/deployApp.js'\nimport {deployDebug} from '../actions/deploy/deployDebug.js'\nimport {deployStudio} from '../actions/deploy/deployStudio.js'\nimport {getAppId} from '../util/appId.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\nimport {dirIsEmptyOrNonExistent} from '../util/dirIsEmptyOrNonExistent.js'\n\nexport class DeployCommand extends SanityCommand<typeof DeployCommand> {\n static override args = {\n sourceDir: Args.directory({\n description: 'Source directory',\n }),\n }\n\n static override description = 'Builds and deploys Sanity Studio or application to Sanity hosting'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Build and deploy the studio to Sanity hosting',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --no-minify --source-maps',\n description: 'Deploys non-minified build with source maps',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --schema-required',\n description:\n 'Fail fast on schema store fails - for when other services rely on the stored schema',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external',\n description: 'Register an externally hosted studio (studioHost contains full URL)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external --url https://apps.example.com',\n description: 'Register an externally hosted studio, served from the provided origin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --create --title \"My App\" --yes --json',\n description:\n 'Create and deploy an App SDK app without prompts. Save application.id as deployment.appId, then omit --create on later deploys',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --create --title \"My App\" --dry-run --json',\n description: 'Preview a new App SDK deployment without creating or uploading anything',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --url my-studio --yes',\n description: 'Deploy a studio without prompts using its hostname',\n },\n ]\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n deprecated: true,\n description: 'Automatically update the studio to the latest version',\n }),\n build: Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'Build the studio before deploying (use --no-build to deploy existing `dist/` output)',\n }),\n create: Flags.boolean({\n description: 'Create a new App SDK app, even if the organization has other apps',\n exclusive: ['external', 'url'],\n }),\n 'dry-run': Flags.boolean({\n default: false,\n description: 'Report what would be deployed without uploading or creating anything',\n }),\n external: Flags.boolean({\n default: false,\n description: 'Register an externally hosted studio',\n exclusive: ['source-maps', 'minify'],\n }),\n json: Flags.boolean({\n char: 'j',\n default: false,\n description: 'Output the result as JSON',\n }),\n minify: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Minify built JavaScript (use --no-minify to skip for faster builds)',\n }),\n 'schema-required': Flags.boolean({\n default: false,\n description: 'Fail if schema deployment fails',\n }),\n 'source-maps': Flags.boolean({\n default: false,\n description: 'Enable source maps for built bundles (increases size of bundle)',\n }),\n title: Flags.string({\n description:\n 'Title for a newly created application or studio. For apps, use --create to select creation when the organization already has apps',\n }),\n url: Flags.string({\n description:\n 'Studio URL for deployment. For external deploys, the full URL. For hosted studios, the hostname (e.g. \"my-studio\" or \"my-studio.sanity.studio\")',\n }),\n verbose: Flags.boolean({\n default: false,\n description: 'Enable verbose logging',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(DeployCommand)\n\n const cliConfig = await this.getCliConfig()\n const projectRoot = await this.getProjectRoot()\n\n const isApp = determineIsApp(cliConfig)\n\n if (flags.create) {\n if (!isApp) {\n return this.output.error(\n '--create is only supported for App SDK apps. For a studio, use --url <hostname>.',\n )\n }\n if (getAppId(cliConfig)) {\n return this.output.error(\n '--create cannot be used with a configured app ID. Omit --create to deploy to that app, or remove deployment.appId and app.id to create a new one.',\n )\n }\n if (getWorkbench(cliConfig) || resolveWorkbenchConfig(cliConfig)) {\n return this.output.error(\n '--create is not supported for this app configuration. Omit --create and run sanity deploy.',\n )\n }\n }\n\n const defaultOutputDir = path.resolve(path.join(projectRoot.directory, 'dist'))\n const sourceDir = path.resolve(process.cwd(), this.args.sourceDir || defaultOutputDir)\n\n // Skip the directory check if the studio is externally hosted\n if (this.args.sourceDir && this.args.sourceDir !== 'dist' && !flags.external) {\n let relativeOutput = path.relative(process.cwd(), sourceDir)\n if (relativeOutput[0] !== '.') {\n relativeOutput = `./${relativeOutput}`\n }\n\n if (!this.isUnattended() && !flags['dry-run']) {\n const isEmpty = await dirIsEmptyOrNonExistent(sourceDir)\n const shouldProceed =\n isEmpty ||\n (await confirm({\n default: false,\n message: `\"${relativeOutput}\" is not empty, do you want to proceed?`,\n }))\n\n if (!shouldProceed) {\n this.output.error('Cancelled.', {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n // Keep --json's stdout clean for the payload\n if (!flags.json) this.output.log(`Building to ${relativeOutput}\\n`)\n }\n\n // Force yes downstream: build/app resolution otherwise prompts for prerelease/version choices\n const deployFlags = this.isUnattended() || flags['dry-run'] ? {...flags, yes: true} : flags\n\n if (isApp) {\n deployDebug('Deploying app')\n await deployApp({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n } else {\n deployDebug('Deploying studio')\n await deployStudio({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n }\n }\n}\n"],"names":["path","Args","Flags","exitCodes","SanityCommand","confirm","getWorkbench","resolveWorkbenchConfig","deployApp","deployDebug","deployStudio","getAppId","determineIsApp","dirIsEmptyOrNonExistent","DeployCommand","args","sourceDir","directory","description","examples","command","flags","boolean","allowNo","deprecated","build","default","create","exclusive","external","json","char","minify","title","string","url","verbose","yes","run","parse","cliConfig","getCliConfig","projectRoot","getProjectRoot","isApp","output","error","defaultOutputDir","resolve","join","process","cwd","relativeOutput","relative","isUnattended","isEmpty","shouldProceed","message","exit","RUNTIME_ERROR","log","deployFlags"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {getWorkbench, resolveWorkbenchConfig} from '@sanity/workbench-cli/deploy'\n\nimport {deployApp} from '../actions/deploy/deployApp.js'\nimport {deployDebug} from '../actions/deploy/deployDebug.js'\nimport {deployStudio} from '../actions/deploy/deployStudio.js'\nimport {getAppId} from '../util/appId.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\nimport {dirIsEmptyOrNonExistent} from '../util/dirIsEmptyOrNonExistent.js'\n\nexport class DeployCommand extends SanityCommand<typeof DeployCommand> {\n static override args = {\n sourceDir: Args.directory({\n description: 'Source directory',\n }),\n }\n\n static override description = 'Builds and deploys Sanity Studio or application to Sanity hosting'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Build and deploy the studio to Sanity hosting',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --no-minify --source-maps',\n description: 'Deploys non-minified build with source maps',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --schema-required',\n description:\n 'Fail fast on schema store fails - for when other services rely on the stored schema',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external',\n description: 'Register an externally hosted studio (studioHost contains full URL)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external --url https://apps.example.com',\n description: 'Register an externally hosted studio, served from the provided origin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --create --title \"My App\" --yes --json',\n description:\n 'Create and deploy an App SDK app without prompts. Save application.id as deployment.appId, then omit --create on later deploys',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --create --title \"My App\" --dry-run --json',\n description: 'Preview a new App SDK deployment without creating or uploading anything',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --url my-studio --yes',\n description: 'Deploy a studio without prompts using its hostname',\n },\n ]\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n deprecated: true,\n description: 'Automatically update the studio to the latest version',\n }),\n build: Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'Build the studio before deploying (use --no-build to deploy existing `dist/` output)',\n }),\n create: Flags.boolean({\n description: 'Create a new App SDK app, even if the organization has other apps',\n exclusive: ['external', 'url'],\n }),\n 'dry-run': Flags.boolean({\n default: false,\n description: 'Report what would be deployed without uploading or creating anything',\n }),\n external: Flags.boolean({\n default: false,\n description: 'Register an externally hosted studio',\n exclusive: ['source-maps', 'minify'],\n }),\n json: Flags.boolean({\n char: 'j',\n default: false,\n description: 'Output the result as JSON',\n }),\n minify: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Minify built JavaScript (use --no-minify to skip for faster builds)',\n }),\n 'schema-required': Flags.boolean({\n default: false,\n description: 'Fail if schema deployment fails',\n }),\n 'source-maps': Flags.boolean({\n default: false,\n description: 'Enable source maps for built bundles (increases size of bundle)',\n }),\n title: Flags.string({\n description:\n 'Title for a newly created application or studio. For apps, use --create to select creation when the organization already has apps',\n }),\n url: Flags.string({\n description:\n 'Studio URL for deployment. For external deploys, the full URL. For hosted studios, the hostname (e.g. \"my-studio\" or \"my-studio.sanity.studio\")',\n }),\n verbose: Flags.boolean({\n default: false,\n description: 'Enable verbose logging',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(DeployCommand)\n\n const cliConfig = await this.getCliConfig()\n const projectRoot = await this.getProjectRoot()\n\n const isApp = determineIsApp(cliConfig)\n\n if (flags.create) {\n if (!isApp) {\n return this.output.error(\n '--create is only supported for App SDK apps. For a studio, use --url <hostname>.',\n )\n }\n if (getAppId(cliConfig)) {\n return this.output.error(\n '--create cannot be used with a configured app ID. Omit --create to deploy to that app, or remove deployment.appId and app.id to create a new one.',\n )\n }\n if (getWorkbench(cliConfig) || resolveWorkbenchConfig(cliConfig)) {\n return this.output.error(\n '--create is not supported for this app configuration. Omit --create and run sanity deploy.',\n )\n }\n }\n\n const defaultOutputDir = path.resolve(path.join(projectRoot.directory, 'dist'))\n const sourceDir = path.resolve(process.cwd(), this.args.sourceDir || defaultOutputDir)\n\n // Skip the directory check if the studio is externally hosted\n if (this.args.sourceDir && this.args.sourceDir !== 'dist' && !flags.external) {\n let relativeOutput = path.relative(process.cwd(), sourceDir)\n if (relativeOutput[0] !== '.') {\n relativeOutput = `./${relativeOutput}`\n }\n\n if (!this.isUnattended() && !flags['dry-run']) {\n const isEmpty = await dirIsEmptyOrNonExistent(sourceDir)\n const shouldProceed =\n isEmpty ||\n (await confirm({\n default: false,\n message: `\"${relativeOutput}\" is not empty, do you want to proceed?`,\n }))\n\n if (!shouldProceed) {\n this.output.error('Cancelled.', {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n // Keep --json's stdout clean for the payload\n if (!flags.json) this.output.log(`Building to ${relativeOutput}\\n`)\n }\n\n // Force yes downstream: build/app resolution otherwise prompts for prerelease/version choices\n const deployFlags = this.isUnattended() || flags['dry-run'] ? {...flags, yes: true} : flags\n\n if (isApp) {\n deployDebug('Deploying app')\n await deployApp({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n } else {\n deployDebug('Deploying studio')\n await deployStudio({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n }\n }\n}\n"],"names":["path","Args","Flags","exitCodes","SanityCommand","confirm","getWorkbench","resolveWorkbenchConfig","deployApp","deployDebug","deployStudio","getAppId","determineIsApp","dirIsEmptyOrNonExistent","DeployCommand","args","sourceDir","directory","description","enableJsonFlag","examples","command","flags","boolean","allowNo","deprecated","build","default","create","exclusive","external","json","char","minify","title","string","url","verbose","yes","run","parse","cliConfig","getCliConfig","projectRoot","getProjectRoot","isApp","output","error","defaultOutputDir","resolve","join","process","cwd","relativeOutput","relative","isUnattended","isEmpty","shouldProceed","message","exit","RUNTIME_ERROR","log","deployFlags"],"mappings":"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"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -27,6 +27,7 @@ export class DoctorCommand extends SanityCommand {
|
|
|
27
27
|
})
|
|
28
28
|
};
|
|
29
29
|
static description = 'Run diagnostics on your Sanity project';
|
|
30
|
+
static enableJsonFlag = true;
|
|
30
31
|
static examples = [
|
|
31
32
|
'<%= config.bin %> <%= command.id %>',
|
|
32
33
|
{
|
|
@@ -65,7 +66,7 @@ export class DoctorCommand extends SanityCommand {
|
|
|
65
66
|
cwd
|
|
66
67
|
}, checks);
|
|
67
68
|
if (flags.json) {
|
|
68
|
-
this.
|
|
69
|
+
this.logJson(results);
|
|
69
70
|
} else {
|
|
70
71
|
for (const check of results.checks){
|
|
71
72
|
this.printCheck(check);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/doctor.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\n\nimport {type DoctorCheckName, doctorChecks, KNOWN_CHECKS} from '../actions/doctor/checks/index.js'\nimport {runDoctorChecks} from '../actions/doctor/runDoctorChecks.js'\nimport {\n type CheckMessage,\n type CheckResultStatus,\n type CheckResultWithMeta,\n type DoctorCheck,\n type DoctorResults,\n type MessageType,\n} from '../actions/doctor/types.js'\n\nconst STATUS_SYMBOLS: Record<CheckResultStatus, string> = {\n error: logSymbols.error,\n passed: logSymbols.success,\n warning: logSymbols.warning,\n}\n\nconst MESSAGE_SYMBOLS: Record<MessageType, string> = {\n error: logSymbols.error,\n info: logSymbols.info,\n success: logSymbols.success,\n warning: logSymbols.warning,\n}\n\nexport class DoctorCommand extends SanityCommand<typeof DoctorCommand> {\n // strict=false allows variadic args — validation is handled by getChecks().\n // options is omitted here because oclif's help formatter uses it for display,\n // but actual validation is done explicitly in getChecks() for clear error messages.\n static override args = {\n checks: Args.string({\n description: `Checks to enable (defaults to all). Valid: ${KNOWN_CHECKS.join(', ')}`,\n multiple: true,\n required: false,\n }),\n }\n\n static override description = 'Run diagnostics on your Sanity project'\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n {command: '<%= config.bin %> <%= command.id %> --json', description: 'Output results as JSON'},\n {\n command: '<%= config.bin %> <%= command.id %> cli',\n description: 'Only run CLI-related diagnostics',\n },\n ]\n\n static override flags = {\n json: Flags.boolean({\n char: 'j',\n default: false,\n description: 'Output results as JSON',\n }),\n }\n\n // Needed for variable argument count\n static override strict = false\n\n public async run(): Promise<void> {\n const {argv, flags} = await this.parse(DoctorCommand)\n\n let checks: Array<DoctorCheck>\n try {\n checks = getChecks(argv)\n } catch (err) {\n return this.output.error(err instanceof Error ? err.message : String(err), {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n const cwd = process.cwd()\n\n if (!flags.json) {\n this.output.log('Running diagnostics...\\n')\n }\n\n const results = await runDoctorChecks({cwd}, checks)\n\n if (flags.json) {\n this.
|
|
1
|
+
{"version":3,"sources":["../../src/commands/doctor.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\n\nimport {type DoctorCheckName, doctorChecks, KNOWN_CHECKS} from '../actions/doctor/checks/index.js'\nimport {runDoctorChecks} from '../actions/doctor/runDoctorChecks.js'\nimport {\n type CheckMessage,\n type CheckResultStatus,\n type CheckResultWithMeta,\n type DoctorCheck,\n type DoctorResults,\n type MessageType,\n} from '../actions/doctor/types.js'\n\nconst STATUS_SYMBOLS: Record<CheckResultStatus, string> = {\n error: logSymbols.error,\n passed: logSymbols.success,\n warning: logSymbols.warning,\n}\n\nconst MESSAGE_SYMBOLS: Record<MessageType, string> = {\n error: logSymbols.error,\n info: logSymbols.info,\n success: logSymbols.success,\n warning: logSymbols.warning,\n}\n\nexport class DoctorCommand extends SanityCommand<typeof DoctorCommand> {\n // strict=false allows variadic args — validation is handled by getChecks().\n // options is omitted here because oclif's help formatter uses it for display,\n // but actual validation is done explicitly in getChecks() for clear error messages.\n static override args = {\n checks: Args.string({\n description: `Checks to enable (defaults to all). Valid: ${KNOWN_CHECKS.join(', ')}`,\n multiple: true,\n required: false,\n }),\n }\n\n static override description = 'Run diagnostics on your Sanity project'\n\n static override enableJsonFlag = true\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n {command: '<%= config.bin %> <%= command.id %> --json', description: 'Output results as JSON'},\n {\n command: '<%= config.bin %> <%= command.id %> cli',\n description: 'Only run CLI-related diagnostics',\n },\n ]\n\n static override flags = {\n json: Flags.boolean({\n char: 'j',\n default: false,\n description: 'Output results as JSON',\n }),\n }\n\n // Needed for variable argument count\n static override strict = false\n\n public async run(): Promise<void> {\n const {argv, flags} = await this.parse(DoctorCommand)\n\n let checks: Array<DoctorCheck>\n try {\n checks = getChecks(argv)\n } catch (err) {\n return this.output.error(err instanceof Error ? err.message : String(err), {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n const cwd = process.cwd()\n\n if (!flags.json) {\n this.output.log('Running diagnostics...\\n')\n }\n\n const results = await runDoctorChecks({cwd}, checks)\n\n if (flags.json) {\n this.logJson(results)\n } else {\n for (const check of results.checks) {\n this.printCheck(check)\n }\n\n this.printSummary(results.summary)\n }\n\n // Exit with error code if any checks failed\n if (results.summary.errors > 0) {\n return this.exit(exitCodes.RUNTIME_ERROR)\n }\n }\n\n private printCheck(check: CheckResultWithMeta): void {\n const symbol = STATUS_SYMBOLS[check.status]\n const title =\n check.status === 'passed'\n ? check.title\n : styleText(check.status === 'error' ? 'red' : 'yellow', check.title)\n\n this.output.log(`${symbol} ${title}`)\n\n for (const message of check.messages) {\n this.printMessage(message)\n }\n\n this.output.log('') // Empty line between checks\n }\n\n private printMessage(message: CheckMessage): void {\n const symbol = MESSAGE_SYMBOLS[message.type]\n const text =\n message.type === 'error'\n ? styleText('red', message.text)\n : message.type === 'warning'\n ? styleText('yellow', message.text)\n : message.text\n\n this.output.log(` ${symbol} ${text}`)\n\n if (message.suggestions?.length) {\n for (const suggestion of message.suggestions) {\n this.output.log(` ${styleText('dim', '→')} ${suggestion}`)\n }\n }\n }\n\n private printSummary(summary: DoctorResults['summary']): void {\n const parts: string[] = []\n\n if (summary.passed > 0) {\n parts.push(styleText('green', `${summary.passed} passed`))\n }\n if (summary.warnings > 0) {\n parts.push(\n styleText('yellow', `${summary.warnings} warning${summary.warnings === 1 ? '' : 's'}`),\n )\n }\n if (summary.errors > 0) {\n parts.push(styleText('red', `${summary.errors} error${summary.errors === 1 ? '' : 's'}`))\n }\n\n this.output.log(`Summary: ${parts.join(', ')}`)\n }\n}\n\nfunction getChecks(argv: unknown[]): Array<DoctorCheck> {\n // strict=false means oclif does NOT validate Args.string({ options }) — we must\n // validate explicitly. Filter to string args that aren't flags.\n const stringArgs = argv.filter(\n (item): item is string => typeof item === 'string' && !item.startsWith('-'),\n )\n\n const unknownChecks = stringArgs.filter(\n (item) => !(KNOWN_CHECKS as readonly string[]).includes(item),\n )\n if (unknownChecks.length > 0) {\n throw new Error(\n `Unknown check${unknownChecks.length === 1 ? '' : 's'}: ${unknownChecks.join(', ')}. Valid checks: ${KNOWN_CHECKS.join(', ')}`,\n )\n }\n\n const checkNames = stringArgs as DoctorCheckName[]\n return checkNames.length > 0\n ? checkNames.map((check) => doctorChecks[check])\n : Object.values(doctorChecks)\n}\n"],"names":["styleText","Args","Flags","exitCodes","SanityCommand","logSymbols","doctorChecks","KNOWN_CHECKS","runDoctorChecks","STATUS_SYMBOLS","error","passed","success","warning","MESSAGE_SYMBOLS","info","DoctorCommand","args","checks","string","description","join","multiple","required","enableJsonFlag","examples","command","flags","json","boolean","char","default","strict","run","argv","parse","getChecks","err","output","Error","message","String","exit","USAGE_ERROR","cwd","process","log","results","logJson","check","printCheck","printSummary","summary","errors","RUNTIME_ERROR","symbol","status","title","messages","printMessage","type","text","suggestions","length","suggestion","parts","push","warnings","stringArgs","filter","item","startsWith","unknownChecks","includes","checkNames","map","Object","values"],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ import open from 'open';
|
|
|
4
4
|
const listOpenapiDebug = subdebug('openapi:list');
|
|
5
5
|
export class ListOpenApiCommand extends SanityCommand {
|
|
6
6
|
static description = 'List all available OpenAPI specifications';
|
|
7
|
+
static enableJsonFlag = true;
|
|
7
8
|
static examples = [
|
|
8
9
|
{
|
|
9
10
|
command: '<%= config.bin %> <%= command.id %>',
|
|
@@ -19,9 +20,6 @@ export class ListOpenApiCommand extends SanityCommand {
|
|
|
19
20
|
}
|
|
20
21
|
];
|
|
21
22
|
static flags = {
|
|
22
|
-
json: Flags.boolean({
|
|
23
|
-
description: 'Output JSON'
|
|
24
|
-
}),
|
|
25
23
|
web: Flags.boolean({
|
|
26
24
|
char: 'w',
|
|
27
25
|
description: 'Open HTTP Reference in web browser'
|
|
@@ -46,7 +44,7 @@ export class ListOpenApiCommand extends SanityCommand {
|
|
|
46
44
|
});
|
|
47
45
|
}
|
|
48
46
|
if (json) {
|
|
49
|
-
this.
|
|
47
|
+
this.logJson(specs);
|
|
50
48
|
return;
|
|
51
49
|
}
|
|
52
50
|
if (specs.length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/openapi/list.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport open from 'open'\n\ninterface OpenAPISpec {\n description: string\n slug: string\n title: string\n}\n\nconst listOpenapiDebug = subdebug('openapi:list')\n\nexport class ListOpenApiCommand extends SanityCommand<typeof ListOpenApiCommand> {\n static override description = 'List all available OpenAPI specifications'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List all available OpenAPI specs',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --json',\n description: 'List with JSON output',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --web',\n description: 'Open HTTP Reference in browser',\n },\n ]\n\n static override flags = {\n
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/openapi/list.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport open from 'open'\n\ninterface OpenAPISpec {\n description: string\n slug: string\n title: string\n}\n\nconst listOpenapiDebug = subdebug('openapi:list')\n\nexport class ListOpenApiCommand extends SanityCommand<typeof ListOpenApiCommand> {\n static override description = 'List all available OpenAPI specifications'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List all available OpenAPI specs',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --json',\n description: 'List with JSON output',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --web',\n description: 'Open HTTP Reference in browser',\n },\n ]\n\n static override flags = {\n web: Flags.boolean({\n char: 'w',\n description: 'Open HTTP Reference in web browser',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(ListOpenApiCommand)\n const {json, web} = flags\n\n if (web) {\n const url = 'https://www.sanity.io/docs/http-reference'\n this.log(`Opening ${url}`)\n await open(url)\n return\n }\n\n let specs: OpenAPISpec[]\n try {\n specs = await this.getSpecs()\n } catch (error) {\n listOpenapiDebug('Error fetching OpenAPI specs', error)\n\n this.error('The OpenAPI service is currently unavailable. Please try again later.', {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (json) {\n this.logJson(specs)\n return\n }\n\n if (specs.length === 0) {\n this.log('No OpenAPI specifications available.')\n return\n }\n\n // Human-readable table format\n this.log(`\\nFound ${specs.length} OpenAPI specification(s):\\n`)\n\n for (const spec of specs) {\n this.log(`Title: ${spec.title}`)\n this.log(`Slug: ${spec.slug}`)\n if (spec.description) {\n this.log(`Description: ${spec.description}`)\n }\n this.log('')\n }\n\n this.log(`Use 'sanity openapi get <slug>' to retrieve a specific specification.`)\n }\n\n private async getSpecs(): Promise<OpenAPISpec[]> {\n const response = await fetch('https://www.sanity.io/docs/api/openapi', {\n signal: AbortSignal.timeout(10_000),\n })\n\n if (response.ok) {\n const data = await response.json()\n return Array.isArray(data?.specs) ? data.specs : []\n }\n\n throw response\n }\n}\n"],"names":["Flags","exitCodes","SanityCommand","subdebug","open","listOpenapiDebug","ListOpenApiCommand","description","enableJsonFlag","examples","command","flags","web","boolean","char","run","parse","json","url","log","specs","getSpecs","error","exit","RUNTIME_ERROR","logJson","length","spec","title","slug","response","fetch","signal","AbortSignal","timeout","ok","data","Array","isArray"],"mappings":"AAAA,SAAQA,KAAK,QAAO,cAAa;AACjC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,OAAOC,UAAU,OAAM;AAQvB,MAAMC,mBAAmBF,SAAS;AAElC,OAAO,MAAMG,2BAA2BJ;IACtC,OAAgBK,cAAc,4CAA2C;IAEzE,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,KAAKZ,MAAMa,OAAO,CAAC;YACjBC,MAAM;YACNP,aAAa;QACf;IACF,EAAC;IAED,MAAaQ,MAAqB;QAChC,MAAM,EAACJ,KAAK,EAAC,GAAG,MAAM,IAAI,CAACK,KAAK,CAACV;QACjC,MAAM,EAACW,IAAI,EAAEL,GAAG,EAAC,GAAGD;QAEpB,IAAIC,KAAK;YACP,MAAMM,MAAM;YACZ,IAAI,CAACC,GAAG,CAAC,CAAC,QAAQ,EAAED,KAAK;YACzB,MAAMd,KAAKc;YACX;QACF;QAEA,IAAIE;QACJ,IAAI;YACFA,QAAQ,MAAM,IAAI,CAACC,QAAQ;QAC7B,EAAE,OAAOC,OAAO;YACdjB,iBAAiB,gCAAgCiB;YAEjD,IAAI,CAACA,KAAK,CAAC,yEAAyE;gBAClFC,MAAMtB,UAAUuB,aAAa;YAC/B;QACF;QAEA,IAAIP,MAAM;YACR,IAAI,CAACQ,OAAO,CAACL;YACb;QACF;QAEA,IAAIA,MAAMM,MAAM,KAAK,GAAG;YACtB,IAAI,CAACP,GAAG,CAAC;YACT;QACF;QAEA,8BAA8B;QAC9B,IAAI,CAACA,GAAG,CAAC,CAAC,QAAQ,EAAEC,MAAMM,MAAM,CAAC,4BAA4B,CAAC;QAE9D,KAAK,MAAMC,QAAQP,MAAO;YACxB,IAAI,CAACD,GAAG,CAAC,CAAC,OAAO,EAAEQ,KAAKC,KAAK,EAAE;YAC/B,IAAI,CAACT,GAAG,CAAC,CAAC,MAAM,EAAEQ,KAAKE,IAAI,EAAE;YAC7B,IAAIF,KAAKpB,WAAW,EAAE;gBACpB,IAAI,CAACY,GAAG,CAAC,CAAC,aAAa,EAAEQ,KAAKpB,WAAW,EAAE;YAC7C;YACA,IAAI,CAACY,GAAG,CAAC;QACX;QAEA,IAAI,CAACA,GAAG,CAAC,CAAC,qEAAqE,CAAC;IAClF;IAEA,MAAcE,WAAmC;QAC/C,MAAMS,WAAW,MAAMC,MAAM,0CAA0C;YACrEC,QAAQC,YAAYC,OAAO,CAAC;QAC9B;QAEA,IAAIJ,SAASK,EAAE,EAAE;YACf,MAAMC,OAAO,MAAMN,SAASb,IAAI;YAChC,OAAOoB,MAAMC,OAAO,CAACF,MAAMhB,SAASgB,KAAKhB,KAAK,GAAG,EAAE;QACrD;QAEA,MAAMU;IACR;AACF"}
|
|
@@ -24,6 +24,7 @@ export class CreateProjectCommand extends SanityCommand {
|
|
|
24
24
|
})
|
|
25
25
|
};
|
|
26
26
|
static description = 'Create a new Sanity project';
|
|
27
|
+
static enableJsonFlag = true;
|
|
27
28
|
static examples = [
|
|
28
29
|
{
|
|
29
30
|
command: '<%= config.bin %> <%= command.id %>',
|
|
@@ -66,10 +67,6 @@ export class CreateProjectCommand extends SanityCommand {
|
|
|
66
67
|
'public'
|
|
67
68
|
]
|
|
68
69
|
}),
|
|
69
|
-
json: Flags.boolean({
|
|
70
|
-
default: false,
|
|
71
|
-
description: 'Output in JSON format'
|
|
72
|
-
}),
|
|
73
70
|
organization: Flags.string({
|
|
74
71
|
description: 'Organization to create the project in',
|
|
75
72
|
helpValue: '<slug|id>'
|
|
@@ -167,13 +164,13 @@ export class CreateProjectCommand extends SanityCommand {
|
|
|
167
164
|
return;
|
|
168
165
|
} catch (error) {
|
|
169
166
|
debug(`Error creating dataset: ${error}`);
|
|
170
|
-
this.output.
|
|
167
|
+
this.output.logDiagnostic(`Warning: Project created but dataset creation failed: ${error}`);
|
|
171
168
|
return;
|
|
172
169
|
}
|
|
173
170
|
}
|
|
174
171
|
async printProjectCreationSuccess(organization, project, dataset) {
|
|
175
172
|
if (this.flags.json) {
|
|
176
|
-
this.
|
|
173
|
+
this.logJson(project);
|
|
177
174
|
return;
|
|
178
175
|
}
|
|
179
176
|
this.output.log(`Project created successfully!`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/projects/create.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {exitCodes} from '@sanity/cli-core'\nimport {subdebug} from '@sanity/cli-core/debug'\nimport {SanityCommand} from '@sanity/cli-core/SanityCommand'\nimport {confirm, spinner} from '@sanity/cli-core/ux'\nimport {type DatasetResponse} from '@sanity/client'\n\nimport {createDataset} from '../../actions/dataset/create.js'\nimport {validateDatasetName} from '../../actions/dataset/validateDatasetName.js'\nimport {getOrganization} from '../../actions/organizations/getOrganization.js'\nimport {getManageUrl} from '../../actions/projects/getManageUrl.js'\nimport {promptForDatasetName} from '../../prompts/promptForDatasetName.js'\nimport {promptForDefaultConfig} from '../../prompts/promptForDefaultConfig.js'\nimport {promptForProjectName} from '../../prompts/promptForProjectName.js'\nimport {listDatasets} from '../../services/datasets.js'\nimport {getProjectFeatures} from '../../services/getProjectFeatures.js'\nimport {\n type OrganizationCreateResponse,\n type ProjectOrganization,\n} from '../../services/organizations.js'\nimport {createProject, type CreateProjectResult} from '../../services/projects.js'\nimport {getCliUser} from '../../services/user.js'\n\nconst debug = subdebug('projects:create')\n\nexport class CreateProjectCommand extends SanityCommand<typeof CreateProjectCommand> {\n static override args = {\n projectName: Args.string({\n description: 'Name of the project to create',\n required: false,\n }),\n }\n\n static override description = 'Create a new Sanity project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Interactively create a project',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"My New Project\"',\n description: 'Create a project named \"My New Project\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"My Project\" --organization=my-org',\n description: 'Create a project in a specific organization',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \"My Project\" --dataset=staging --dataset-visibility=private',\n description: 'Create a project with a private dataset named \"staging\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"CI Project\" --yes --json',\n description: 'Create a project non-interactively with JSON output',\n },\n ]\n\n static override flags = {\n dataset: Flags.string({\n description: 'Create a dataset. Prompts for visibility unless specified or --yes used',\n parse: async (input) => {\n const datasetNameError = validateDatasetName(input)\n if (datasetNameError) {\n throw new CLIError(datasetNameError, {exit: exitCodes.USAGE_ERROR})\n }\n\n return input\n },\n }),\n 'dataset-visibility': Flags.string({\n description: 'Dataset visibility: public or private',\n options: ['private', 'public'],\n }),\n json: Flags.boolean({\n default: false,\n description: 'Output in JSON format',\n }),\n organization: Flags.string({\n description: 'Organization to create the project in',\n helpValue: '<slug|id>',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Skip prompts and use defaults (project: \"My Sanity Project\", dataset: production, visibility: public)',\n }),\n }\n\n static override hiddenAliases: string[] = ['project:create']\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(CreateProjectCommand)\n const {projectName} = args\n const {dataset, 'dataset-visibility': datasetVisibility, organization, yes} = flags\n const user = await getCliUser()\n\n const finalProjectName =\n projectName ||\n (yes || this.isUnattended() ? 'My Sanity Project' : await promptForProjectName())\n\n debug('Creating project with options: %O', {\n dataset,\n datasetVisibility,\n organizationId: organization,\n projectName,\n unattended: yes,\n })\n\n let chosenOrganization: OrganizationCreateResponse | ProjectOrganization | undefined\n try {\n chosenOrganization = await getOrganization({\n isUnattended: this.isUnattended(),\n output: this.output,\n requestedId: organization,\n user,\n })\n } catch (error) {\n const errorText = organization\n ? `Failed to retrieve organization ${organization}`\n : 'Failed to retrieve an organization'\n return this.output.error(`${errorText}: ${error}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n const spin = spinner('Creating project').start()\n let newProject\n try {\n newProject = await createProject({\n displayName: finalProjectName,\n metadata: {\n integration: 'cli',\n },\n organizationId: chosenOrganization?.id,\n })\n spin.succeed('Project created successfully')\n } catch (error) {\n spin.fail()\n debug(`Failed to create project: ${error}`)\n return this.output.error(`Failed to create project: ${error}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n let newDataset: DatasetResponse | undefined\n // If dataset name specified, or in attended mode (to prompt for dataset name), create a dataset.\n if (dataset || !this.isUnattended()) {\n newDataset = await this.handleDatasetCreation(\n newProject.projectId,\n dataset,\n datasetVisibility,\n )\n }\n\n this.printProjectCreationSuccess(chosenOrganization, newProject, newDataset)\n }\n\n private async handleDatasetCreation(\n projectId: string,\n datasetFromFlag?: string,\n datasetVisibility?: string,\n ): Promise<DatasetResponse | undefined> {\n try {\n let datasetName: string | undefined = datasetFromFlag\n const existingDatasets = await listDatasets(projectId)\n const existingDatasetNames = existingDatasets.map((ds) => ds.name)\n\n // Prompt for dataset in interactive mode if not provided\n if (!datasetName && !this.isUnattended()) {\n const wantsDataset = await confirm({\n default: true,\n message: 'Would you like to create a dataset?',\n })\n\n if (wantsDataset) {\n const defaultConfig = await promptForDefaultConfig()\n\n datasetName = defaultConfig\n ? 'production'\n : await promptForDatasetName({}, existingDatasetNames)\n }\n }\n\n // Create dataset if we have a name\n if (datasetName) {\n const projectFeatures = await getProjectFeatures(projectId)\n return await createDataset({\n datasetName,\n isUnattended: this.isUnattended(),\n output: this.output,\n projectFeatures,\n projectId,\n silent: this.flags.json,\n visibility: datasetVisibility,\n })\n }\n\n return\n } catch (error) {\n debug(`Error creating dataset: ${error}`)\n this.output.warn(`Project created but dataset creation failed: ${error}`)\n return\n }\n }\n\n private async printProjectCreationSuccess(\n organization: OrganizationCreateResponse | ProjectOrganization | undefined,\n project: CreateProjectResult,\n dataset: DatasetResponse | undefined,\n ) {\n if (this.flags.json) {\n this.output.log(JSON.stringify(project, null, 2))\n return\n }\n\n this.output.log(`Project created successfully!`)\n this.output.log(`ID: ${project.projectId}`)\n this.output.log(`Name: ${project.displayName}`)\n this.output.log(`Organization: ${organization?.name || 'Personal'}`)\n\n if (dataset) {\n this.output.log(`Dataset: ${dataset.datasetName} (${dataset.aclMode})`)\n }\n\n this.output.log(``)\n this.output.log(`Manage your project: ${getManageUrl(project.projectId)}`)\n }\n}\n"],"names":["Args","Flags","CLIError","exitCodes","subdebug","SanityCommand","confirm","spinner","createDataset","validateDatasetName","getOrganization","getManageUrl","promptForDatasetName","promptForDefaultConfig","promptForProjectName","listDatasets","getProjectFeatures","createProject","getCliUser","debug","CreateProjectCommand","args","projectName","string","description","required","examples","command","flags","dataset","parse","input","datasetNameError","exit","USAGE_ERROR","options","json","boolean","default","organization","helpValue","yes","char","hiddenAliases","run","datasetVisibility","user","finalProjectName","isUnattended","organizationId","unattended","chosenOrganization","output","requestedId","error","errorText","RUNTIME_ERROR","spin","start","newProject","displayName","metadata","integration","id","succeed","fail","newDataset","handleDatasetCreation","projectId","printProjectCreationSuccess","datasetFromFlag","datasetName","existingDatasets","existingDatasetNames","map","ds","name","wantsDataset","message","defaultConfig","projectFeatures","silent","visibility","warn","project","log","JSON","stringify","aclMode"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/projects/create.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {exitCodes} from '@sanity/cli-core'\nimport {subdebug} from '@sanity/cli-core/debug'\nimport {SanityCommand} from '@sanity/cli-core/SanityCommand'\nimport {confirm, spinner} from '@sanity/cli-core/ux'\nimport {type DatasetResponse} from '@sanity/client'\n\nimport {createDataset} from '../../actions/dataset/create.js'\nimport {validateDatasetName} from '../../actions/dataset/validateDatasetName.js'\nimport {getOrganization} from '../../actions/organizations/getOrganization.js'\nimport {getManageUrl} from '../../actions/projects/getManageUrl.js'\nimport {promptForDatasetName} from '../../prompts/promptForDatasetName.js'\nimport {promptForDefaultConfig} from '../../prompts/promptForDefaultConfig.js'\nimport {promptForProjectName} from '../../prompts/promptForProjectName.js'\nimport {listDatasets} from '../../services/datasets.js'\nimport {getProjectFeatures} from '../../services/getProjectFeatures.js'\nimport {\n type OrganizationCreateResponse,\n type ProjectOrganization,\n} from '../../services/organizations.js'\nimport {createProject, type CreateProjectResult} from '../../services/projects.js'\nimport {getCliUser} from '../../services/user.js'\n\nconst debug = subdebug('projects:create')\n\nexport class CreateProjectCommand extends SanityCommand<typeof CreateProjectCommand> {\n static override args = {\n projectName: Args.string({\n description: 'Name of the project to create',\n required: false,\n }),\n }\n\n static override description = 'Create a new Sanity project'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Interactively create a project',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"My New Project\"',\n description: 'Create a project named \"My New Project\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"My Project\" --organization=my-org',\n description: 'Create a project in a specific organization',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \"My Project\" --dataset=staging --dataset-visibility=private',\n description: 'Create a project with a private dataset named \"staging\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"CI Project\" --yes --json',\n description: 'Create a project non-interactively with JSON output',\n },\n ]\n\n static override flags = {\n dataset: Flags.string({\n description: 'Create a dataset. Prompts for visibility unless specified or --yes used',\n parse: async (input) => {\n const datasetNameError = validateDatasetName(input)\n if (datasetNameError) {\n throw new CLIError(datasetNameError, {exit: exitCodes.USAGE_ERROR})\n }\n\n return input\n },\n }),\n 'dataset-visibility': Flags.string({\n description: 'Dataset visibility: public or private',\n options: ['private', 'public'],\n }),\n organization: Flags.string({\n description: 'Organization to create the project in',\n helpValue: '<slug|id>',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Skip prompts and use defaults (project: \"My Sanity Project\", dataset: production, visibility: public)',\n }),\n }\n\n static override hiddenAliases: string[] = ['project:create']\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(CreateProjectCommand)\n const {projectName} = args\n const {dataset, 'dataset-visibility': datasetVisibility, organization, yes} = flags\n const user = await getCliUser()\n\n const finalProjectName =\n projectName ||\n (yes || this.isUnattended() ? 'My Sanity Project' : await promptForProjectName())\n\n debug('Creating project with options: %O', {\n dataset,\n datasetVisibility,\n organizationId: organization,\n projectName,\n unattended: yes,\n })\n\n let chosenOrganization: OrganizationCreateResponse | ProjectOrganization | undefined\n try {\n chosenOrganization = await getOrganization({\n isUnattended: this.isUnattended(),\n output: this.output,\n requestedId: organization,\n user,\n })\n } catch (error) {\n const errorText = organization\n ? `Failed to retrieve organization ${organization}`\n : 'Failed to retrieve an organization'\n return this.output.error(`${errorText}: ${error}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n const spin = spinner('Creating project').start()\n let newProject\n try {\n newProject = await createProject({\n displayName: finalProjectName,\n metadata: {\n integration: 'cli',\n },\n organizationId: chosenOrganization?.id,\n })\n spin.succeed('Project created successfully')\n } catch (error) {\n spin.fail()\n debug(`Failed to create project: ${error}`)\n return this.output.error(`Failed to create project: ${error}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n let newDataset: DatasetResponse | undefined\n // If dataset name specified, or in attended mode (to prompt for dataset name), create a dataset.\n if (dataset || !this.isUnattended()) {\n newDataset = await this.handleDatasetCreation(\n newProject.projectId,\n dataset,\n datasetVisibility,\n )\n }\n\n this.printProjectCreationSuccess(chosenOrganization, newProject, newDataset)\n }\n\n private async handleDatasetCreation(\n projectId: string,\n datasetFromFlag?: string,\n datasetVisibility?: string,\n ): Promise<DatasetResponse | undefined> {\n try {\n let datasetName: string | undefined = datasetFromFlag\n const existingDatasets = await listDatasets(projectId)\n const existingDatasetNames = existingDatasets.map((ds) => ds.name)\n\n // Prompt for dataset in interactive mode if not provided\n if (!datasetName && !this.isUnattended()) {\n const wantsDataset = await confirm({\n default: true,\n message: 'Would you like to create a dataset?',\n })\n\n if (wantsDataset) {\n const defaultConfig = await promptForDefaultConfig()\n\n datasetName = defaultConfig\n ? 'production'\n : await promptForDatasetName({}, existingDatasetNames)\n }\n }\n\n // Create dataset if we have a name\n if (datasetName) {\n const projectFeatures = await getProjectFeatures(projectId)\n return await createDataset({\n datasetName,\n isUnattended: this.isUnattended(),\n output: this.output,\n projectFeatures,\n projectId,\n silent: this.flags.json,\n visibility: datasetVisibility,\n })\n }\n\n return\n } catch (error) {\n debug(`Error creating dataset: ${error}`)\n this.output.logDiagnostic(`Warning: Project created but dataset creation failed: ${error}`)\n return\n }\n }\n\n private async printProjectCreationSuccess(\n organization: OrganizationCreateResponse | ProjectOrganization | undefined,\n project: CreateProjectResult,\n dataset: DatasetResponse | undefined,\n ) {\n if (this.flags.json) {\n this.logJson(project)\n return\n }\n\n this.output.log(`Project created successfully!`)\n this.output.log(`ID: ${project.projectId}`)\n this.output.log(`Name: ${project.displayName}`)\n this.output.log(`Organization: ${organization?.name || 'Personal'}`)\n\n if (dataset) {\n this.output.log(`Dataset: ${dataset.datasetName} (${dataset.aclMode})`)\n }\n\n this.output.log(``)\n this.output.log(`Manage your project: ${getManageUrl(project.projectId)}`)\n }\n}\n"],"names":["Args","Flags","CLIError","exitCodes","subdebug","SanityCommand","confirm","spinner","createDataset","validateDatasetName","getOrganization","getManageUrl","promptForDatasetName","promptForDefaultConfig","promptForProjectName","listDatasets","getProjectFeatures","createProject","getCliUser","debug","CreateProjectCommand","args","projectName","string","description","required","enableJsonFlag","examples","command","flags","dataset","parse","input","datasetNameError","exit","USAGE_ERROR","options","organization","helpValue","yes","boolean","char","default","hiddenAliases","run","datasetVisibility","user","finalProjectName","isUnattended","organizationId","unattended","chosenOrganization","output","requestedId","error","errorText","RUNTIME_ERROR","spin","start","newProject","displayName","metadata","integration","id","succeed","fail","newDataset","handleDatasetCreation","projectId","printProjectCreationSuccess","datasetFromFlag","datasetName","existingDatasets","existingDatasetNames","map","ds","name","wantsDataset","message","defaultConfig","projectFeatures","silent","json","visibility","logDiagnostic","project","logJson","log","aclMode"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAQC,QAAQ,QAAO,qBAAoB;AAC3C,SAAQC,SAAS,QAAO,mBAAkB;AAC1C,SAAQC,QAAQ,QAAO,yBAAwB;AAC/C,SAAQC,aAAa,QAAO,iCAAgC;AAC5D,SAAQC,OAAO,EAAEC,OAAO,QAAO,sBAAqB;AAGpD,SAAQC,aAAa,QAAO,kCAAiC;AAC7D,SAAQC,mBAAmB,QAAO,+CAA8C;AAChF,SAAQC,eAAe,QAAO,iDAAgD;AAC9E,SAAQC,YAAY,QAAO,yCAAwC;AACnE,SAAQC,oBAAoB,QAAO,wCAAuC;AAC1E,SAAQC,sBAAsB,QAAO,0CAAyC;AAC9E,SAAQC,oBAAoB,QAAO,wCAAuC;AAC1E,SAAQC,YAAY,QAAO,6BAA4B;AACvD,SAAQC,kBAAkB,QAAO,uCAAsC;AAKvE,SAAQC,aAAa,QAAiC,6BAA4B;AAClF,SAAQC,UAAU,QAAO,yBAAwB;AAEjD,MAAMC,QAAQf,SAAS;AAEvB,OAAO,MAAMgB,6BAA6Bf;IACxC,OAAgBgB,OAAO;QACrBC,aAAatB,KAAKuB,MAAM,CAAC;YACvBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,8BAA6B;IAE3D,OAAgBE,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SACE;YACFJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;KACD,CAAA;IAED,OAAgBK,QAAQ;QACtBC,SAAS7B,MAAMsB,MAAM,CAAC;YACpBC,aAAa;YACbO,OAAO,OAAOC;gBACZ,MAAMC,mBAAmBxB,oBAAoBuB;gBAC7C,IAAIC,kBAAkB;oBACpB,MAAM,IAAI/B,SAAS+B,kBAAkB;wBAACC,MAAM/B,UAAUgC,WAAW;oBAAA;gBACnE;gBAEA,OAAOH;YACT;QACF;QACA,sBAAsB/B,MAAMsB,MAAM,CAAC;YACjCC,aAAa;YACbY,SAAS;gBAAC;gBAAW;aAAS;QAChC;QACAC,cAAcpC,MAAMsB,MAAM,CAAC;YACzBC,aAAa;YACbc,WAAW;QACb;QACAC,KAAKtC,MAAMuC,OAAO,CAAC;YACjBC,MAAM;YACNC,SAAS;YACTlB,aACE;QACJ;IACF,EAAC;IAED,OAAgBmB,gBAA0B;QAAC;KAAiB,CAAA;IAE5D,MAAaC,MAAqB;QAChC,MAAM,EAACvB,IAAI,EAAEQ,KAAK,EAAC,GAAG,MAAM,IAAI,CAACE,KAAK,CAACX;QACvC,MAAM,EAACE,WAAW,EAAC,GAAGD;QACtB,MAAM,EAACS,OAAO,EAAE,sBAAsBe,iBAAiB,EAAER,YAAY,EAAEE,GAAG,EAAC,GAAGV;QAC9E,MAAMiB,OAAO,MAAM5B;QAEnB,MAAM6B,mBACJzB,eACCiB,CAAAA,OAAO,IAAI,CAACS,YAAY,KAAK,sBAAsB,MAAMlC,sBAAqB;QAEjFK,MAAM,qCAAqC;YACzCW;YACAe;YACAI,gBAAgBZ;YAChBf;YACA4B,YAAYX;QACd;QAEA,IAAIY;QACJ,IAAI;YACFA,qBAAqB,MAAMzC,gBAAgB;gBACzCsC,cAAc,IAAI,CAACA,YAAY;gBAC/BI,QAAQ,IAAI,CAACA,MAAM;gBACnBC,aAAahB;gBACbS;YACF;QACF,EAAE,OAAOQ,OAAO;YACd,MAAMC,YAAYlB,eACd,CAAC,gCAAgC,EAAEA,cAAc,GACjD;YACJ,OAAO,IAAI,CAACe,MAAM,CAACE,KAAK,CAAC,GAAGC,UAAU,EAAE,EAAED,OAAO,EAAE;gBAACpB,MAAM/B,UAAUqD,aAAa;YAAA;QACnF;QAEA,MAAMC,OAAOlD,QAAQ,oBAAoBmD,KAAK;QAC9C,IAAIC;QACJ,IAAI;YACFA,aAAa,MAAM1C,cAAc;gBAC/B2C,aAAab;gBACbc,UAAU;oBACRC,aAAa;gBACf;gBACAb,gBAAgBE,oBAAoBY;YACtC;YACAN,KAAKO,OAAO,CAAC;QACf,EAAE,OAAOV,OAAO;YACdG,KAAKQ,IAAI;YACT9C,MAAM,CAAC,0BAA0B,EAAEmC,OAAO;YAC1C,OAAO,IAAI,CAACF,MAAM,CAACE,KAAK,CAAC,CAAC,0BAA0B,EAAEA,OAAO,EAAE;gBAC7DpB,MAAM/B,UAAUqD,aAAa;YAC/B;QACF;QAEA,IAAIU;QACJ,iGAAiG;QACjG,IAAIpC,WAAW,CAAC,IAAI,CAACkB,YAAY,IAAI;YACnCkB,aAAa,MAAM,IAAI,CAACC,qBAAqB,CAC3CR,WAAWS,SAAS,EACpBtC,SACAe;QAEJ;QAEA,IAAI,CAACwB,2BAA2B,CAAClB,oBAAoBQ,YAAYO;IACnE;IAEA,MAAcC,sBACZC,SAAiB,EACjBE,eAAwB,EACxBzB,iBAA0B,EACY;QACtC,IAAI;YACF,IAAI0B,cAAkCD;YACtC,MAAME,mBAAmB,MAAMzD,aAAaqD;YAC5C,MAAMK,uBAAuBD,iBAAiBE,GAAG,CAAC,CAACC,KAAOA,GAAGC,IAAI;YAEjE,yDAAyD;YACzD,IAAI,CAACL,eAAe,CAAC,IAAI,CAACvB,YAAY,IAAI;gBACxC,MAAM6B,eAAe,MAAMvE,QAAQ;oBACjCoC,SAAS;oBACToC,SAAS;gBACX;gBAEA,IAAID,cAAc;oBAChB,MAAME,gBAAgB,MAAMlE;oBAE5B0D,cAAcQ,gBACV,eACA,MAAMnE,qBAAqB,CAAC,GAAG6D;gBACrC;YACF;YAEA,mCAAmC;YACnC,IAAIF,aAAa;gBACf,MAAMS,kBAAkB,MAAMhE,mBAAmBoD;gBACjD,OAAO,MAAM5D,cAAc;oBACzB+D;oBACAvB,cAAc,IAAI,CAACA,YAAY;oBAC/BI,QAAQ,IAAI,CAACA,MAAM;oBACnB4B;oBACAZ;oBACAa,QAAQ,IAAI,CAACpD,KAAK,CAACqD,IAAI;oBACvBC,YAAYtC;gBACd;YACF;YAEA;QACF,EAAE,OAAOS,OAAO;YACdnC,MAAM,CAAC,wBAAwB,EAAEmC,OAAO;YACxC,IAAI,CAACF,MAAM,CAACgC,aAAa,CAAC,CAAC,sDAAsD,EAAE9B,OAAO;YAC1F;QACF;IACF;IAEA,MAAce,4BACZhC,YAA0E,EAC1EgD,OAA4B,EAC5BvD,OAAoC,EACpC;QACA,IAAI,IAAI,CAACD,KAAK,CAACqD,IAAI,EAAE;YACnB,IAAI,CAACI,OAAO,CAACD;YACb;QACF;QAEA,IAAI,CAACjC,MAAM,CAACmC,GAAG,CAAC,CAAC,6BAA6B,CAAC;QAC/C,IAAI,CAACnC,MAAM,CAACmC,GAAG,CAAC,CAAC,IAAI,EAAEF,QAAQjB,SAAS,EAAE;QAC1C,IAAI,CAAChB,MAAM,CAACmC,GAAG,CAAC,CAAC,MAAM,EAAEF,QAAQzB,WAAW,EAAE;QAC9C,IAAI,CAACR,MAAM,CAACmC,GAAG,CAAC,CAAC,cAAc,EAAElD,cAAcuC,QAAQ,YAAY;QAEnE,IAAI9C,SAAS;YACX,IAAI,CAACsB,MAAM,CAACmC,GAAG,CAAC,CAAC,SAAS,EAAEzD,QAAQyC,WAAW,CAAC,EAAE,EAAEzC,QAAQ0D,OAAO,CAAC,CAAC,CAAC;QACxE;QAEA,IAAI,CAACpC,MAAM,CAACmC,GAAG,CAAC,EAAE;QAClB,IAAI,CAACnC,MAAM,CAACmC,GAAG,CAAC,CAAC,qBAAqB,EAAE5E,aAAa0E,QAAQjB,SAAS,GAAG;IAC3E;AACF"}
|
|
@@ -12,6 +12,7 @@ Regenerates a manifest file by default. To reuse an existing manifest, use --no-
|
|
|
12
12
|
`.trim();
|
|
13
13
|
export class ListSchemaCommand extends SanityCommand {
|
|
14
14
|
static description = description;
|
|
15
|
+
static enableJsonFlag = true;
|
|
15
16
|
static examples = [
|
|
16
17
|
{
|
|
17
18
|
command: '<%= config.bin %> <%= command.id %>',
|
|
@@ -41,9 +42,6 @@ export class ListSchemaCommand extends SanityCommand {
|
|
|
41
42
|
description: 'Fetch a single schema by id',
|
|
42
43
|
helpValue: '<schema_id>'
|
|
43
44
|
}),
|
|
44
|
-
json: Flags.boolean({
|
|
45
|
-
description: 'Get schema as json'
|
|
46
|
-
}),
|
|
47
45
|
'manifest-dir': Flags.directory({
|
|
48
46
|
default: './dist/static',
|
|
49
47
|
description: 'Directory containing manifest file',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/schemas/list.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand} from '@sanity/cli-core'\n\nimport {listSchemas} from '../../actions/schema/listSchemas.js'\nimport {schemasListDebug} from '../../actions/schema/utils/debug.js'\nimport {parseWorkspaceSchemaId} from '../../actions/schema/utils/schemaStoreValidation.js'\n\nconst description = `\nList all schemas in the current dataset.\n\nNote: This command is experimental and subject to change.\n\nRegenerates a manifest file by default. To reuse an existing manifest, use --no-extract-manifest.\n`.trim()\n\nexport class ListSchemaCommand extends SanityCommand<typeof ListSchemaCommand> {\n static override description = description\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List all schemas found in any workspace dataset in a table',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --id _.schemas.workspaceName',\n description: 'Get a schema for a given id',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --json',\n description: 'Get stored schemas as pretty-printed json-array',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --json --id _.schemas.workspaceName',\n description: 'Get singular stored schema as pretty-printed json-object',\n },\n ]\n\n static override flags = {\n 'extract-manifest': Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Regenerate manifest before listing (use --no-extract-manifest to skip)',\n hidden: true,\n }),\n id: Flags.string({\n description: 'Fetch a single schema by id',\n helpValue: '<schema_id>',\n }),\n
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/schemas/list.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand} from '@sanity/cli-core'\n\nimport {listSchemas} from '../../actions/schema/listSchemas.js'\nimport {schemasListDebug} from '../../actions/schema/utils/debug.js'\nimport {parseWorkspaceSchemaId} from '../../actions/schema/utils/schemaStoreValidation.js'\n\nconst description = `\nList all schemas in the current dataset.\n\nNote: This command is experimental and subject to change.\n\nRegenerates a manifest file by default. To reuse an existing manifest, use --no-extract-manifest.\n`.trim()\n\nexport class ListSchemaCommand extends SanityCommand<typeof ListSchemaCommand> {\n static override description = description\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List all schemas found in any workspace dataset in a table',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --id _.schemas.workspaceName',\n description: 'Get a schema for a given id',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --json',\n description: 'Get stored schemas as pretty-printed json-array',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --json --id _.schemas.workspaceName',\n description: 'Get singular stored schema as pretty-printed json-object',\n },\n ]\n\n static override flags = {\n 'extract-manifest': Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Regenerate manifest before listing (use --no-extract-manifest to skip)',\n hidden: true,\n }),\n id: Flags.string({\n description: 'Fetch a single schema by id',\n helpValue: '<schema_id>',\n }),\n 'manifest-dir': Flags.directory({\n default: './dist/static',\n description: 'Directory containing manifest file',\n helpValue: '<directory>',\n hidden: true,\n }),\n }\n\n static override hiddenAliases: string[] = ['schema:list']\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(ListSchemaCommand)\n const errors: string[] = []\n const id = parseWorkspaceSchemaId(errors, flags.id)?.schemaId\n if (errors.length > 0) {\n this.error(`Invalid arguments:\\n${errors.map((error) => ` - ${error}`).join('\\n')}`, {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n\n try {\n const projectRoot = await this.getProjectRoot()\n\n await listSchemas({\n configPath: projectRoot.path,\n id,\n json: !!flags.json,\n output: this.output,\n workDir: projectRoot.directory,\n })\n } catch (error) {\n schemasListDebug('Failed to list schemas', error)\n\n const errorMessage = error instanceof Error ? error.message : String(error)\n this.error(`Failed to list schemas:\\n${errorMessage}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n}\n"],"names":["Flags","exitCodes","SanityCommand","listSchemas","schemasListDebug","parseWorkspaceSchemaId","description","trim","ListSchemaCommand","enableJsonFlag","examples","command","flags","boolean","allowNo","default","hidden","id","string","helpValue","directory","hiddenAliases","run","parse","errors","schemaId","length","error","map","join","exit","USAGE_ERROR","projectRoot","getProjectRoot","configPath","path","json","output","workDir","errorMessage","Error","message","String","RUNTIME_ERROR"],"mappings":"AAAA,SAAQA,KAAK,QAAO,cAAa;AACjC,SAAQC,SAAS,EAAEC,aAAa,QAAO,mBAAkB;AAEzD,SAAQC,WAAW,QAAO,sCAAqC;AAC/D,SAAQC,gBAAgB,QAAO,sCAAqC;AACpE,SAAQC,sBAAsB,QAAO,sDAAqD;AAE1F,MAAMC,cAAc,CAAC;;;;;;AAMrB,CAAC,CAACC,IAAI;AAEN,OAAO,MAAMC,0BAA0BN;IACrC,OAAgBI,cAAcA,YAAW;IAEzC,OAAgBG,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTL,aAAa;QACf;QACA;YACEK,SAAS;YACTL,aAAa;QACf;QACA;YACEK,SAAS;YACTL,aAAa;QACf;QACA;YACEK,SAAS;YACTL,aAAa;QACf;KACD,CAAA;IAED,OAAgBM,QAAQ;QACtB,oBAAoBZ,MAAMa,OAAO,CAAC;YAChCC,SAAS;YACTC,SAAS;YACTT,aAAa;YACbU,QAAQ;QACV;QACAC,IAAIjB,MAAMkB,MAAM,CAAC;YACfZ,aAAa;YACba,WAAW;QACb;QACA,gBAAgBnB,MAAMoB,SAAS,CAAC;YAC9BL,SAAS;YACTT,aAAa;YACba,WAAW;YACXH,QAAQ;QACV;IACF,EAAC;IAED,OAAgBK,gBAA0B;QAAC;KAAc,CAAA;IAEzD,MAAaC,MAAqB;QAChC,MAAM,EAACV,KAAK,EAAC,GAAG,MAAM,IAAI,CAACW,KAAK,CAACf;QACjC,MAAMgB,SAAmB,EAAE;QAC3B,MAAMP,KAAKZ,uBAAuBmB,QAAQZ,MAAMK,EAAE,GAAGQ;QACrD,IAAID,OAAOE,MAAM,GAAG,GAAG;YACrB,IAAI,CAACC,KAAK,CAAC,CAAC,oBAAoB,EAAEH,OAAOI,GAAG,CAAC,CAACD,QAAU,CAAC,IAAI,EAAEA,OAAO,EAAEE,IAAI,CAAC,OAAO,EAAE;gBACpFC,MAAM7B,UAAU8B,WAAW;YAC7B;QACF;QAEA,IAAI;YACF,MAAMC,cAAc,MAAM,IAAI,CAACC,cAAc;YAE7C,MAAM9B,YAAY;gBAChB+B,YAAYF,YAAYG,IAAI;gBAC5BlB;gBACAmB,MAAM,CAAC,CAACxB,MAAMwB,IAAI;gBAClBC,QAAQ,IAAI,CAACA,MAAM;gBACnBC,SAASN,YAAYZ,SAAS;YAChC;QACF,EAAE,OAAOO,OAAO;YACdvB,iBAAiB,0BAA0BuB;YAE3C,MAAMY,eAAeZ,iBAAiBa,QAAQb,MAAMc,OAAO,GAAGC,OAAOf;YACrE,IAAI,CAACA,KAAK,CAAC,CAAC,yBAAyB,EAAEY,cAAc,EAAE;gBAACT,MAAM7B,UAAU0C,aAAa;YAAA;QACvF;IACF;AACF"}
|
|
@@ -29,6 +29,7 @@ export class CreateTokenCommand extends SanityCommand {
|
|
|
29
29
|
})
|
|
30
30
|
};
|
|
31
31
|
static description = 'Create a new API token with access to an organization and its projects';
|
|
32
|
+
static enableJsonFlag = true;
|
|
32
33
|
static examples = [
|
|
33
34
|
{
|
|
34
35
|
command: '<%= config.bin %> <%= command.id %> "My API Token"',
|
|
@@ -73,10 +74,6 @@ export class CreateTokenCommand extends SanityCommand {
|
|
|
73
74
|
helpValue: 'context=editor',
|
|
74
75
|
multiple: true
|
|
75
76
|
}),
|
|
76
|
-
json: Flags.boolean({
|
|
77
|
-
default: false,
|
|
78
|
-
description: 'Output as JSON'
|
|
79
|
-
}),
|
|
80
77
|
role: Flags.string({
|
|
81
78
|
description: 'Role to assign on the project (defaults to viewer in unattended mode)',
|
|
82
79
|
helpValue: 'viewer'
|
|
@@ -130,7 +127,7 @@ export class CreateTokenCommand extends SanityCommand {
|
|
|
130
127
|
});
|
|
131
128
|
}
|
|
132
129
|
if (flags.json) {
|
|
133
|
-
this.
|
|
130
|
+
this.logJson(token);
|
|
134
131
|
return;
|
|
135
132
|
}
|
|
136
133
|
this.log('API token created');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/tokens/create.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage, isProjectRootNotFoundError} from '@sanity/cli-core/errors'\nimport {input, select} from '@sanity/cli-core/ux'\nimport {ClientError} from '@sanity/client'\n\nimport {\n MissingOrganizationError,\n resolveOrganizationId,\n} from '../../actions/context/resolveOrganizationId.js'\nimport {expiryInDays, parseExpiryDate} from '../../actions/tokens/expiry.js'\nimport {\n DEFAULT_ROLE,\n findGrantConflict,\n formatGrant,\n getProjectTokenMembership,\n type Grant,\n parseGrant,\n projectGrantKey,\n toMemberships,\n} from '../../actions/tokens/grants.js'\nimport {type RobotWithToken} from '../../actions/tokens/types.js'\nimport {validateRole} from '../../actions/tokens/validateRole.js'\nimport {promptForGrants} from '../../prompts/promptForGrants.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {listProjects} from '../../services/projects.js'\nimport {createOrganizationToken, createToken} from '../../services/tokens.js'\nimport {getOrganizationFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst tokensCreateDebug = subdebug('tokens:create')\n\ntype Access = {\n expiresAt: string | undefined\n grants: Grant[]\n\n organizationId?: string\n roleTitle?: string\n}\n\n// Mirrors the expiry presets offered by sanity.io/manage\nconst EXPIRY_PRESET_DAYS = [30, 60, 90]\n\nconst ORGANIZATION_FORBIDDEN_MESSAGE =\n 'You need permission to create organization tokens. Grant a single project to create a project token instead.'\n\nexport class CreateTokenCommand extends SanityCommand<typeof CreateTokenCommand> {\n static override args = {\n label: Args.string({\n description: 'Label for the new token',\n required: false,\n }),\n }\n\n static override description =\n 'Create a new API token with access to an organization and its projects'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> \"My API Token\"',\n description: 'Create a token, choosing its access interactively',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \"CI Token\" --grant context=developer --grant blueprints --grant project:abc123=editor',\n description: 'Create an organization token with Context, Blueprints and project access',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"My Token\" --project-id abc123 --role=editor',\n description: 'Create a project token with editor role',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"CI Token\" --role=editor --yes',\n description: 'Create a project token in unattended mode',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"Build Token\" --expires-at 2027-01-01',\n description: 'Create a token that expires on a given date',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"API Token\" --json',\n description: 'Output token information as JSON',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to create token in',\n semantics: 'override',\n }),\n ...getOrganizationFlag({\n description: 'Organization to create an organization token in',\n semantics: 'override',\n }),\n 'expires-at': Flags.string({\n description: 'Date or timestamp the token expires (ISO 8601; tokens never expire by default)',\n helpValue: '2027-01-01',\n }),\n grant: Flags.string({\n description:\n 'Access to grant, as <permission>[=<role>] or project:<projectId>=<role>[,<role>]. Permissions: context, blueprints, media-library, canvas, sdk-apps, access, deploy-studios. Repeatable',\n helpValue: 'context=editor',\n multiple: true,\n }),\n json: Flags.boolean({\n default: false,\n description: 'Output as JSON',\n }),\n role: Flags.string({\n description: 'Role to assign on the project (defaults to viewer in unattended mode)',\n helpValue: 'viewer',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description: 'Skip prompts and use defaults (unattended mode)',\n }),\n }\n\n static override hiddenAliases: string[] = ['tokens:add', 'token:add', 'token:create']\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(CreateTokenCommand)\n const {label: givenLabel} = args\n\n const label = givenLabel === undefined ? await this.promptForLabel() : givenLabel.trim()\n if (!label) {\n this.error('Token label cannot be empty. Pass a non-empty value as the `<label>` argument.', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n\n const flagExpiresAt = this.parseExpiryFlag(flags['expires-at'])\n const getExpiry = async () =>\n flags['expires-at'] === undefined ? this.promptForExpiry() : flagExpiresAt\n const flagGrants = (flags.grant ?? []).map((value) => this.parseGrantFlag(value))\n const grantConflict = findGrantConflict(flagGrants)\n if (grantConflict) {\n this.error(grantConflict, {exit: exitCodes.USAGE_ERROR})\n }\n\n const {expiresAt, grants, organizationId, roleTitle}: Access =\n this.isUnattended() || flagGrants.length > 0 || flags.role !== undefined\n ? {...(await this.getFlagGrants(flagGrants)), expiresAt: await getExpiry()}\n : await this.promptForAccess(getExpiry)\n\n let token: RobotWithToken\n try {\n token = await this.createTokenForGrants({\n expiresAt,\n grants,\n label,\n organizationId,\n })\n } catch (error) {\n if (error instanceof CLIError) throw error\n tokensCreateDebug('Error creating token', error)\n this.error(`Token creation failed:\\n${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (flags.json) {\n this.log(JSON.stringify(token, null, 2))\n return\n }\n\n this.log('API token created')\n this.log(`Label: ${token.label}`)\n this.log(`ID: ${token.id}`)\n if (roleTitle) {\n this.log(`Role: ${roleTitle}`)\n }\n if (token.expiresAt) {\n this.log(`Expires: ${token.expiresAt}`)\n }\n this.log(`Token: ${token.token}`)\n this.log('')\n this.log(\"Copy the token now. It won't be shown again.\")\n\n if (!this.isUnattended()) {\n this.log('')\n this.log('To create the same token without prompts:')\n this.log(` ${formatCreateCommand(this.config.bin, {expiresAt, grants, label, token})}`)\n }\n }\n\n private async createTokenForGrants(options: {\n expiresAt: string | undefined\n grants: Grant[]\n label: string\n organizationId: string | undefined\n }): Promise<RobotWithToken> {\n const {expiresAt, grants, label} = options\n const projectMembership = getProjectTokenMembership(grants)\n if (projectMembership) {\n const {resourceId: projectId, roleNames} = projectMembership\n return createToken({expiresAt, label, projectId, roleNames})\n }\n\n const organizationId = options.organizationId ?? (await this.resolveOrganization())\n try {\n return await createOrganizationToken({\n expiresAt,\n label,\n memberships: toMemberships(grants, organizationId),\n organizationId,\n })\n } catch (error) {\n if (error instanceof ClientError && error.statusCode === 403) {\n throw new Error(ORGANIZATION_FORBIDDEN_MESSAGE, {cause: error})\n }\n throw error\n }\n }\n\n private async getFlagGrants(grants: Grant[]): Promise<{grants: Grant[]; roleTitle?: string}> {\n const {'project-id': projectIdFlag, role} = this.flags\n if (grants.length > 0 && !projectIdFlag && !role) {\n return {grants}\n }\n\n const projectId = await this.resolveProjectId()\n const projectKey = projectGrantKey(projectId)\n if (grants.some((grant) => grant.key === projectKey)) {\n if (role) {\n this.error(\n `Set the role for project ${projectId} with either --role or --grant ${projectKey}=<role>, not both.`,\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n return {grants}\n }\n\n const projectRole = role ? await validateRole(role, projectId, this.output) : DEFAULT_ROLE\n\n return {\n grants: [...grants, {key: projectKey, roles: [projectRole.name]}],\n roleTitle: grants.length === 0 ? projectRole.title : undefined,\n }\n }\n\n private parseExpiryFlag(value: string | undefined): string | undefined {\n if (value === undefined) {\n return undefined\n }\n\n const parsed = parseExpiryDate(value)\n if ('error' in parsed) {\n this.error(parsed.error, {exit: exitCodes.USAGE_ERROR})\n }\n\n return parsed.expiresAt\n }\n\n private parseGrantFlag(value: string): Grant {\n const parsed = parseGrant(value.trim())\n if ('error' in parsed) {\n this.error(parsed.error, {exit: exitCodes.USAGE_ERROR})\n }\n\n return parsed.grant\n }\n\n private async promptForAccess(getExpiry: () => Promise<string | undefined>): Promise<Access> {\n const requestedProjectId = this.flags['project-id']\n const configProjectId = (await this.tryGetCliConfig()).api?.projectId\n const projects = await listProjects({onlyExplicitMembership: false})\n const organizationOf = (projectId: string | undefined) =>\n projects.find((project) => project.id === projectId)?.organizationId ?? undefined\n const organizationId = await this.resolveOrganization({\n fallback: organizationOf(configProjectId),\n preferred: organizationOf(requestedProjectId),\n })\n const organizationProjects = projects.filter(\n (project) => project.organizationId === organizationId,\n )\n if (requestedProjectId && !organizationProjects.some(({id}) => id === requestedProjectId)) {\n this.error(\n `Project ${requestedProjectId} isn't in organization ${organizationId}, or you don't have access to it.`,\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n const expiresAt = await getExpiry()\n const grants = await promptForGrants({\n preselectedProjectId: requestedProjectId,\n projects: organizationProjects,\n })\n return {expiresAt, grants, organizationId}\n }\n\n private async promptForExpiry(): Promise<string | undefined> {\n if (this.isUnattended()) {\n return undefined // Tokens never expire by default\n }\n\n const choice = await select({\n choices: [\n {name: 'Never', value: 'never'},\n ...EXPIRY_PRESET_DAYS.map((days) => ({\n name: `${days} days (${expiryInDays(days).slice(0, 10)})`,\n value: String(days),\n })),\n {name: 'Custom date', value: 'custom'},\n ],\n default: 'never',\n message: 'Token expiry:',\n })\n\n if (choice === 'never') {\n return undefined\n }\n\n if (choice === 'custom') {\n const value = await input({\n message: 'Expiry date (ISO 8601, e.g. 2027-01-01):',\n validate: (input) => {\n const parsed = parseExpiryDate(input.trim())\n return 'error' in parsed ? parsed.error : true\n },\n })\n const parsed = parseExpiryDate(value.trim())\n return 'error' in parsed ? undefined : parsed.expiresAt\n }\n\n return expiryInDays(Number(choice))\n }\n\n private async promptForLabel(): Promise<string> {\n if (this.isUnattended()) {\n this.error('Token label is required. Pass it as the `<label>` argument.', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n\n const label = await input({\n message: 'Token label:',\n validate: (value) => {\n if (!value || !value.trim()) {\n return 'Label cannot be empty'\n }\n return true\n },\n })\n\n return label.trim()\n }\n\n private async resolveOrganization(\n projectOrganizations: {fallback?: string; preferred?: string} = {},\n ): Promise<string> {\n const {fallback, preferred} = projectOrganizations\n try {\n return await resolveOrganizationId({\n configuredOrganizationId:\n preferred ?? (await this.tryGetCliConfig()).app?.organizationId ?? fallback,\n flagOrganizationId: this.flags.organization,\n unattended: this.isUnattended(),\n })\n } catch (error) {\n tokensCreateDebug('Error resolving organization', error)\n this.error(getErrorMessage(error), {\n exit:\n error instanceof MissingOrganizationError\n ? exitCodes.USAGE_ERROR\n : exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async resolveProjectId(): Promise<string> {\n if (!this.isUnattended()) {\n return this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [\n {grant: 'read', permission: 'sanity.project.roles'},\n {grant: 'create', permission: 'sanity.project.tokens'},\n ],\n }),\n })\n }\n\n try {\n return await this.getProjectId()\n } catch (error) {\n if (!isProjectRootNotFoundError(error)) throw error\n this.error(\n 'Token access is required. Pass at least one `--grant`, or `--project-id` to create a project token.',\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n }\n}\n\nfunction quoteShellArg(value: string): string {\n return /^[\\w./:@=,-]+$/.test(value) ? value : `'${value.replaceAll(\"'\", String.raw`'\\''`)}'`\n}\n\nfunction formatCreateCommand(\n bin: string,\n {\n expiresAt,\n grants,\n label,\n token,\n }: {\n expiresAt: string | undefined\n grants: Grant[]\n label: string\n token: RobotWithToken\n },\n): string {\n const organizationId =\n token.managedBy?.resourceType === 'organization' ? token.managedBy.resourceId : undefined\n return [\n `${bin} tokens create`,\n quoteShellArg(label),\n ...(organizationId ? [`--organization ${organizationId}`] : []),\n ...(expiresAt ? [`--expires-at ${expiresAt}`] : []),\n ...grants.map((grant) => `--grant ${formatGrant(grant)}`),\n '--yes',\n ].join(' ')\n}\n"],"names":["Args","Flags","CLIError","exitCodes","SanityCommand","subdebug","getErrorMessage","isProjectRootNotFoundError","input","select","ClientError","MissingOrganizationError","resolveOrganizationId","expiryInDays","parseExpiryDate","DEFAULT_ROLE","findGrantConflict","formatGrant","getProjectTokenMembership","parseGrant","projectGrantKey","toMemberships","validateRole","promptForGrants","promptForProject","listProjects","createOrganizationToken","createToken","getOrganizationFlag","getProjectIdFlag","tokensCreateDebug","EXPIRY_PRESET_DAYS","ORGANIZATION_FORBIDDEN_MESSAGE","CreateTokenCommand","args","label","string","description","required","examples","command","flags","semantics","helpValue","grant","multiple","json","boolean","default","role","yes","char","hiddenAliases","run","parse","givenLabel","undefined","promptForLabel","trim","error","exit","USAGE_ERROR","flagExpiresAt","parseExpiryFlag","getExpiry","promptForExpiry","flagGrants","map","value","parseGrantFlag","grantConflict","expiresAt","grants","organizationId","roleTitle","isUnattended","length","getFlagGrants","promptForAccess","token","createTokenForGrants","RUNTIME_ERROR","log","JSON","stringify","id","formatCreateCommand","config","bin","options","projectMembership","resourceId","projectId","roleNames","resolveOrganization","memberships","statusCode","Error","cause","projectIdFlag","resolveProjectId","projectKey","some","key","projectRole","output","roles","name","title","parsed","requestedProjectId","configProjectId","tryGetCliConfig","api","projects","onlyExplicitMembership","organizationOf","find","project","fallback","preferred","organizationProjects","filter","preselectedProjectId","choice","choices","days","slice","String","message","validate","Number","projectOrganizations","configuredOrganizationId","app","flagOrganizationId","organization","unattended","getProjectId","requiredPermissions","permission","quoteShellArg","test","replaceAll","raw","managedBy","resourceType","join"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/tokens/create.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage, isProjectRootNotFoundError} from '@sanity/cli-core/errors'\nimport {input, select} from '@sanity/cli-core/ux'\nimport {ClientError} from '@sanity/client'\n\nimport {\n MissingOrganizationError,\n resolveOrganizationId,\n} from '../../actions/context/resolveOrganizationId.js'\nimport {expiryInDays, parseExpiryDate} from '../../actions/tokens/expiry.js'\nimport {\n DEFAULT_ROLE,\n findGrantConflict,\n formatGrant,\n getProjectTokenMembership,\n type Grant,\n parseGrant,\n projectGrantKey,\n toMemberships,\n} from '../../actions/tokens/grants.js'\nimport {type RobotWithToken} from '../../actions/tokens/types.js'\nimport {validateRole} from '../../actions/tokens/validateRole.js'\nimport {promptForGrants} from '../../prompts/promptForGrants.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {listProjects} from '../../services/projects.js'\nimport {createOrganizationToken, createToken} from '../../services/tokens.js'\nimport {getOrganizationFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst tokensCreateDebug = subdebug('tokens:create')\n\ntype Access = {\n expiresAt: string | undefined\n grants: Grant[]\n\n organizationId?: string\n roleTitle?: string\n}\n\n// Mirrors the expiry presets offered by sanity.io/manage\nconst EXPIRY_PRESET_DAYS = [30, 60, 90]\n\nconst ORGANIZATION_FORBIDDEN_MESSAGE =\n 'You need permission to create organization tokens. Grant a single project to create a project token instead.'\n\nexport class CreateTokenCommand extends SanityCommand<typeof CreateTokenCommand> {\n static override args = {\n label: Args.string({\n description: 'Label for the new token',\n required: false,\n }),\n }\n\n static override description =\n 'Create a new API token with access to an organization and its projects'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> \"My API Token\"',\n description: 'Create a token, choosing its access interactively',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \"CI Token\" --grant context=developer --grant blueprints --grant project:abc123=editor',\n description: 'Create an organization token with Context, Blueprints and project access',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"My Token\" --project-id abc123 --role=editor',\n description: 'Create a project token with editor role',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"CI Token\" --role=editor --yes',\n description: 'Create a project token in unattended mode',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"Build Token\" --expires-at 2027-01-01',\n description: 'Create a token that expires on a given date',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"API Token\" --json',\n description: 'Output token information as JSON',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to create token in',\n semantics: 'override',\n }),\n ...getOrganizationFlag({\n description: 'Organization to create an organization token in',\n semantics: 'override',\n }),\n 'expires-at': Flags.string({\n description: 'Date or timestamp the token expires (ISO 8601; tokens never expire by default)',\n helpValue: '2027-01-01',\n }),\n grant: Flags.string({\n description:\n 'Access to grant, as <permission>[=<role>] or project:<projectId>=<role>[,<role>]. Permissions: context, blueprints, media-library, canvas, sdk-apps, access, deploy-studios. Repeatable',\n helpValue: 'context=editor',\n multiple: true,\n }),\n role: Flags.string({\n description: 'Role to assign on the project (defaults to viewer in unattended mode)',\n helpValue: 'viewer',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description: 'Skip prompts and use defaults (unattended mode)',\n }),\n }\n\n static override hiddenAliases: string[] = ['tokens:add', 'token:add', 'token:create']\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(CreateTokenCommand)\n const {label: givenLabel} = args\n\n const label = givenLabel === undefined ? await this.promptForLabel() : givenLabel.trim()\n if (!label) {\n this.error('Token label cannot be empty. Pass a non-empty value as the `<label>` argument.', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n\n const flagExpiresAt = this.parseExpiryFlag(flags['expires-at'])\n const getExpiry = async () =>\n flags['expires-at'] === undefined ? this.promptForExpiry() : flagExpiresAt\n const flagGrants = (flags.grant ?? []).map((value) => this.parseGrantFlag(value))\n const grantConflict = findGrantConflict(flagGrants)\n if (grantConflict) {\n this.error(grantConflict, {exit: exitCodes.USAGE_ERROR})\n }\n\n const {expiresAt, grants, organizationId, roleTitle}: Access =\n this.isUnattended() || flagGrants.length > 0 || flags.role !== undefined\n ? {...(await this.getFlagGrants(flagGrants)), expiresAt: await getExpiry()}\n : await this.promptForAccess(getExpiry)\n\n let token: RobotWithToken\n try {\n token = await this.createTokenForGrants({\n expiresAt,\n grants,\n label,\n organizationId,\n })\n } catch (error) {\n if (error instanceof CLIError) throw error\n tokensCreateDebug('Error creating token', error)\n this.error(`Token creation failed:\\n${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (flags.json) {\n this.logJson(token)\n return\n }\n\n this.log('API token created')\n this.log(`Label: ${token.label}`)\n this.log(`ID: ${token.id}`)\n if (roleTitle) {\n this.log(`Role: ${roleTitle}`)\n }\n if (token.expiresAt) {\n this.log(`Expires: ${token.expiresAt}`)\n }\n this.log(`Token: ${token.token}`)\n this.log('')\n this.log(\"Copy the token now. It won't be shown again.\")\n\n if (!this.isUnattended()) {\n this.log('')\n this.log('To create the same token without prompts:')\n this.log(` ${formatCreateCommand(this.config.bin, {expiresAt, grants, label, token})}`)\n }\n }\n\n private async createTokenForGrants(options: {\n expiresAt: string | undefined\n grants: Grant[]\n label: string\n organizationId: string | undefined\n }): Promise<RobotWithToken> {\n const {expiresAt, grants, label} = options\n const projectMembership = getProjectTokenMembership(grants)\n if (projectMembership) {\n const {resourceId: projectId, roleNames} = projectMembership\n return createToken({expiresAt, label, projectId, roleNames})\n }\n\n const organizationId = options.organizationId ?? (await this.resolveOrganization())\n try {\n return await createOrganizationToken({\n expiresAt,\n label,\n memberships: toMemberships(grants, organizationId),\n organizationId,\n })\n } catch (error) {\n if (error instanceof ClientError && error.statusCode === 403) {\n throw new Error(ORGANIZATION_FORBIDDEN_MESSAGE, {cause: error})\n }\n throw error\n }\n }\n\n private async getFlagGrants(grants: Grant[]): Promise<{grants: Grant[]; roleTitle?: string}> {\n const {'project-id': projectIdFlag, role} = this.flags\n if (grants.length > 0 && !projectIdFlag && !role) {\n return {grants}\n }\n\n const projectId = await this.resolveProjectId()\n const projectKey = projectGrantKey(projectId)\n if (grants.some((grant) => grant.key === projectKey)) {\n if (role) {\n this.error(\n `Set the role for project ${projectId} with either --role or --grant ${projectKey}=<role>, not both.`,\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n return {grants}\n }\n\n const projectRole = role ? await validateRole(role, projectId, this.output) : DEFAULT_ROLE\n\n return {\n grants: [...grants, {key: projectKey, roles: [projectRole.name]}],\n roleTitle: grants.length === 0 ? projectRole.title : undefined,\n }\n }\n\n private parseExpiryFlag(value: string | undefined): string | undefined {\n if (value === undefined) {\n return undefined\n }\n\n const parsed = parseExpiryDate(value)\n if ('error' in parsed) {\n this.error(parsed.error, {exit: exitCodes.USAGE_ERROR})\n }\n\n return parsed.expiresAt\n }\n\n private parseGrantFlag(value: string): Grant {\n const parsed = parseGrant(value.trim())\n if ('error' in parsed) {\n this.error(parsed.error, {exit: exitCodes.USAGE_ERROR})\n }\n\n return parsed.grant\n }\n\n private async promptForAccess(getExpiry: () => Promise<string | undefined>): Promise<Access> {\n const requestedProjectId = this.flags['project-id']\n const configProjectId = (await this.tryGetCliConfig()).api?.projectId\n const projects = await listProjects({onlyExplicitMembership: false})\n const organizationOf = (projectId: string | undefined) =>\n projects.find((project) => project.id === projectId)?.organizationId ?? undefined\n const organizationId = await this.resolveOrganization({\n fallback: organizationOf(configProjectId),\n preferred: organizationOf(requestedProjectId),\n })\n const organizationProjects = projects.filter(\n (project) => project.organizationId === organizationId,\n )\n if (requestedProjectId && !organizationProjects.some(({id}) => id === requestedProjectId)) {\n this.error(\n `Project ${requestedProjectId} isn't in organization ${organizationId}, or you don't have access to it.`,\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n const expiresAt = await getExpiry()\n const grants = await promptForGrants({\n preselectedProjectId: requestedProjectId,\n projects: organizationProjects,\n })\n return {expiresAt, grants, organizationId}\n }\n\n private async promptForExpiry(): Promise<string | undefined> {\n if (this.isUnattended()) {\n return undefined // Tokens never expire by default\n }\n\n const choice = await select({\n choices: [\n {name: 'Never', value: 'never'},\n ...EXPIRY_PRESET_DAYS.map((days) => ({\n name: `${days} days (${expiryInDays(days).slice(0, 10)})`,\n value: String(days),\n })),\n {name: 'Custom date', value: 'custom'},\n ],\n default: 'never',\n message: 'Token expiry:',\n })\n\n if (choice === 'never') {\n return undefined\n }\n\n if (choice === 'custom') {\n const value = await input({\n message: 'Expiry date (ISO 8601, e.g. 2027-01-01):',\n validate: (input) => {\n const parsed = parseExpiryDate(input.trim())\n return 'error' in parsed ? parsed.error : true\n },\n })\n const parsed = parseExpiryDate(value.trim())\n return 'error' in parsed ? undefined : parsed.expiresAt\n }\n\n return expiryInDays(Number(choice))\n }\n\n private async promptForLabel(): Promise<string> {\n if (this.isUnattended()) {\n this.error('Token label is required. Pass it as the `<label>` argument.', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n\n const label = await input({\n message: 'Token label:',\n validate: (value) => {\n if (!value || !value.trim()) {\n return 'Label cannot be empty'\n }\n return true\n },\n })\n\n return label.trim()\n }\n\n private async resolveOrganization(\n projectOrganizations: {fallback?: string; preferred?: string} = {},\n ): Promise<string> {\n const {fallback, preferred} = projectOrganizations\n try {\n return await resolveOrganizationId({\n configuredOrganizationId:\n preferred ?? (await this.tryGetCliConfig()).app?.organizationId ?? fallback,\n flagOrganizationId: this.flags.organization,\n unattended: this.isUnattended(),\n })\n } catch (error) {\n tokensCreateDebug('Error resolving organization', error)\n this.error(getErrorMessage(error), {\n exit:\n error instanceof MissingOrganizationError\n ? exitCodes.USAGE_ERROR\n : exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async resolveProjectId(): Promise<string> {\n if (!this.isUnattended()) {\n return this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [\n {grant: 'read', permission: 'sanity.project.roles'},\n {grant: 'create', permission: 'sanity.project.tokens'},\n ],\n }),\n })\n }\n\n try {\n return await this.getProjectId()\n } catch (error) {\n if (!isProjectRootNotFoundError(error)) throw error\n this.error(\n 'Token access is required. Pass at least one `--grant`, or `--project-id` to create a project token.',\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n }\n}\n\nfunction quoteShellArg(value: string): string {\n return /^[\\w./:@=,-]+$/.test(value) ? value : `'${value.replaceAll(\"'\", String.raw`'\\''`)}'`\n}\n\nfunction formatCreateCommand(\n bin: string,\n {\n expiresAt,\n grants,\n label,\n token,\n }: {\n expiresAt: string | undefined\n grants: Grant[]\n label: string\n token: RobotWithToken\n },\n): string {\n const organizationId =\n token.managedBy?.resourceType === 'organization' ? token.managedBy.resourceId : undefined\n return [\n `${bin} tokens create`,\n quoteShellArg(label),\n ...(organizationId ? [`--organization ${organizationId}`] : []),\n ...(expiresAt ? [`--expires-at ${expiresAt}`] : []),\n ...grants.map((grant) => `--grant ${formatGrant(grant)}`),\n '--yes',\n ].join(' ')\n}\n"],"names":["Args","Flags","CLIError","exitCodes","SanityCommand","subdebug","getErrorMessage","isProjectRootNotFoundError","input","select","ClientError","MissingOrganizationError","resolveOrganizationId","expiryInDays","parseExpiryDate","DEFAULT_ROLE","findGrantConflict","formatGrant","getProjectTokenMembership","parseGrant","projectGrantKey","toMemberships","validateRole","promptForGrants","promptForProject","listProjects","createOrganizationToken","createToken","getOrganizationFlag","getProjectIdFlag","tokensCreateDebug","EXPIRY_PRESET_DAYS","ORGANIZATION_FORBIDDEN_MESSAGE","CreateTokenCommand","args","label","string","description","required","enableJsonFlag","examples","command","flags","semantics","helpValue","grant","multiple","role","yes","boolean","char","default","hiddenAliases","run","parse","givenLabel","undefined","promptForLabel","trim","error","exit","USAGE_ERROR","flagExpiresAt","parseExpiryFlag","getExpiry","promptForExpiry","flagGrants","map","value","parseGrantFlag","grantConflict","expiresAt","grants","organizationId","roleTitle","isUnattended","length","getFlagGrants","promptForAccess","token","createTokenForGrants","RUNTIME_ERROR","json","logJson","log","id","formatCreateCommand","config","bin","options","projectMembership","resourceId","projectId","roleNames","resolveOrganization","memberships","statusCode","Error","cause","projectIdFlag","resolveProjectId","projectKey","some","key","projectRole","output","roles","name","title","parsed","requestedProjectId","configProjectId","tryGetCliConfig","api","projects","onlyExplicitMembership","organizationOf","find","project","fallback","preferred","organizationProjects","filter","preselectedProjectId","choice","choices","days","slice","String","message","validate","Number","projectOrganizations","configuredOrganizationId","app","flagOrganizationId","organization","unattended","getProjectId","requiredPermissions","permission","quoteShellArg","test","replaceAll","raw","managedBy","resourceType","join"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAQC,QAAQ,QAAO,qBAAoB;AAC3C,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,EAAEC,0BAA0B,QAAO,0BAAyB;AACnF,SAAQC,KAAK,EAAEC,MAAM,QAAO,sBAAqB;AACjD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SACEC,wBAAwB,EACxBC,qBAAqB,QAChB,iDAAgD;AACvD,SAAQC,YAAY,EAAEC,eAAe,QAAO,iCAAgC;AAC5E,SACEC,YAAY,EACZC,iBAAiB,EACjBC,WAAW,EACXC,yBAAyB,EAEzBC,UAAU,EACVC,eAAe,EACfC,aAAa,QACR,iCAAgC;AAEvC,SAAQC,YAAY,QAAO,uCAAsC;AACjE,SAAQC,eAAe,QAAO,mCAAkC;AAChE,SAAQC,gBAAgB,QAAO,oCAAmC;AAClE,SAAQC,YAAY,QAAO,6BAA4B;AACvD,SAAQC,uBAAuB,EAAEC,WAAW,QAAO,2BAA0B;AAC7E,SAAQC,mBAAmB,EAAEC,gBAAgB,QAAO,4BAA2B;AAE/E,MAAMC,oBAAoBzB,SAAS;AAUnC,yDAAyD;AACzD,MAAM0B,qBAAqB;IAAC;IAAI;IAAI;CAAG;AAEvC,MAAMC,iCACJ;AAEF,OAAO,MAAMC,2BAA2B7B;IACtC,OAAgB8B,OAAO;QACrBC,OAAOnC,KAAKoC,MAAM,CAAC;YACjBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cACd,yEAAwE;IAE1E,OAAgBE,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SACE;YACFJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;KACD,CAAA;IAED,OAAgBK,QAAQ;QACtB,GAAGb,iBAAiB;YAClBQ,aAAa;YACbM,WAAW;QACb,EAAE;QACF,GAAGf,oBAAoB;YACrBS,aAAa;YACbM,WAAW;QACb,EAAE;QACF,cAAc1C,MAAMmC,MAAM,CAAC;YACzBC,aAAa;YACbO,WAAW;QACb;QACAC,OAAO5C,MAAMmC,MAAM,CAAC;YAClBC,aACE;YACFO,WAAW;YACXE,UAAU;QACZ;QACAC,MAAM9C,MAAMmC,MAAM,CAAC;YACjBC,aAAa;YACbO,WAAW;QACb;QACAI,KAAK/C,MAAMgD,OAAO,CAAC;YACjBC,MAAM;YACNC,SAAS;YACTd,aAAa;QACf;IACF,EAAC;IAED,OAAgBe,gBAA0B;QAAC;QAAc;QAAa;KAAe,CAAA;IAErF,MAAaC,MAAqB;QAChC,MAAM,EAACnB,IAAI,EAAEQ,KAAK,EAAC,GAAG,MAAM,IAAI,CAACY,KAAK,CAACrB;QACvC,MAAM,EAACE,OAAOoB,UAAU,EAAC,GAAGrB;QAE5B,MAAMC,QAAQoB,eAAeC,YAAY,MAAM,IAAI,CAACC,cAAc,KAAKF,WAAWG,IAAI;QACtF,IAAI,CAACvB,OAAO;YACV,IAAI,CAACwB,KAAK,CAAC,kFAAkF;gBAC3FC,MAAMzD,UAAU0D,WAAW;YAC7B;QACF;QAEA,MAAMC,gBAAgB,IAAI,CAACC,eAAe,CAACrB,KAAK,CAAC,aAAa;QAC9D,MAAMsB,YAAY,UAChBtB,KAAK,CAAC,aAAa,KAAKc,YAAY,IAAI,CAACS,eAAe,KAAKH;QAC/D,MAAMI,aAAa,AAACxB,CAAAA,MAAMG,KAAK,IAAI,EAAE,AAAD,EAAGsB,GAAG,CAAC,CAACC,QAAU,IAAI,CAACC,cAAc,CAACD;QAC1E,MAAME,gBAAgBtD,kBAAkBkD;QACxC,IAAII,eAAe;YACjB,IAAI,CAACX,KAAK,CAACW,eAAe;gBAACV,MAAMzD,UAAU0D,WAAW;YAAA;QACxD;QAEA,MAAM,EAACU,SAAS,EAAEC,MAAM,EAAEC,cAAc,EAAEC,SAAS,EAAC,GAClD,IAAI,CAACC,YAAY,MAAMT,WAAWU,MAAM,GAAG,KAAKlC,MAAMK,IAAI,KAAKS,YAC3D;YAAC,GAAI,MAAM,IAAI,CAACqB,aAAa,CAACX,WAAW;YAAGK,WAAW,MAAMP;QAAW,IACxE,MAAM,IAAI,CAACc,eAAe,CAACd;QAEjC,IAAIe;QACJ,IAAI;YACFA,QAAQ,MAAM,IAAI,CAACC,oBAAoB,CAAC;gBACtCT;gBACAC;gBACArC;gBACAsC;YACF;QACF,EAAE,OAAOd,OAAO;YACd,IAAIA,iBAAiBzD,UAAU,MAAMyD;YACrC7B,kBAAkB,wBAAwB6B;YAC1C,IAAI,CAACA,KAAK,CAAC,CAAC,wBAAwB,EAAErD,gBAAgBqD,QAAQ,EAAE;gBAC9DC,MAAMzD,UAAU8E,aAAa;YAC/B;QACF;QAEA,IAAIvC,MAAMwC,IAAI,EAAE;YACd,IAAI,CAACC,OAAO,CAACJ;YACb;QACF;QAEA,IAAI,CAACK,GAAG,CAAC;QACT,IAAI,CAACA,GAAG,CAAC,CAAC,OAAO,EAAEL,MAAM5C,KAAK,EAAE;QAChC,IAAI,CAACiD,GAAG,CAAC,CAAC,IAAI,EAAEL,MAAMM,EAAE,EAAE;QAC1B,IAAIX,WAAW;YACb,IAAI,CAACU,GAAG,CAAC,CAAC,MAAM,EAAEV,WAAW;QAC/B;QACA,IAAIK,MAAMR,SAAS,EAAE;YACnB,IAAI,CAACa,GAAG,CAAC,CAAC,SAAS,EAAEL,MAAMR,SAAS,EAAE;QACxC;QACA,IAAI,CAACa,GAAG,CAAC,CAAC,OAAO,EAAEL,MAAMA,KAAK,EAAE;QAChC,IAAI,CAACK,GAAG,CAAC;QACT,IAAI,CAACA,GAAG,CAAC;QAET,IAAI,CAAC,IAAI,CAACT,YAAY,IAAI;YACxB,IAAI,CAACS,GAAG,CAAC;YACT,IAAI,CAACA,GAAG,CAAC;YACT,IAAI,CAACA,GAAG,CAAC,CAAC,EAAE,EAAEE,oBAAoB,IAAI,CAACC,MAAM,CAACC,GAAG,EAAE;gBAACjB;gBAAWC;gBAAQrC;gBAAO4C;YAAK,IAAI;QACzF;IACF;IAEA,MAAcC,qBAAqBS,OAKlC,EAA2B;QAC1B,MAAM,EAAClB,SAAS,EAAEC,MAAM,EAAErC,KAAK,EAAC,GAAGsD;QACnC,MAAMC,oBAAoBxE,0BAA0BsD;QACpD,IAAIkB,mBAAmB;YACrB,MAAM,EAACC,YAAYC,SAAS,EAAEC,SAAS,EAAC,GAAGH;YAC3C,OAAO/D,YAAY;gBAAC4C;gBAAWpC;gBAAOyD;gBAAWC;YAAS;QAC5D;QAEA,MAAMpB,iBAAiBgB,QAAQhB,cAAc,IAAK,MAAM,IAAI,CAACqB,mBAAmB;QAChF,IAAI;YACF,OAAO,MAAMpE,wBAAwB;gBACnC6C;gBACApC;gBACA4D,aAAa1E,cAAcmD,QAAQC;gBACnCA;YACF;QACF,EAAE,OAAOd,OAAO;YACd,IAAIA,iBAAiBjD,eAAeiD,MAAMqC,UAAU,KAAK,KAAK;gBAC5D,MAAM,IAAIC,MAAMjE,gCAAgC;oBAACkE,OAAOvC;gBAAK;YAC/D;YACA,MAAMA;QACR;IACF;IAEA,MAAckB,cAAcL,MAAe,EAAkD;QAC3F,MAAM,EAAC,cAAc2B,aAAa,EAAEpD,IAAI,EAAC,GAAG,IAAI,CAACL,KAAK;QACtD,IAAI8B,OAAOI,MAAM,GAAG,KAAK,CAACuB,iBAAiB,CAACpD,MAAM;YAChD,OAAO;gBAACyB;YAAM;QAChB;QAEA,MAAMoB,YAAY,MAAM,IAAI,CAACQ,gBAAgB;QAC7C,MAAMC,aAAajF,gBAAgBwE;QACnC,IAAIpB,OAAO8B,IAAI,CAAC,CAACzD,QAAUA,MAAM0D,GAAG,KAAKF,aAAa;YACpD,IAAItD,MAAM;gBACR,IAAI,CAACY,KAAK,CACR,CAAC,yBAAyB,EAAEiC,UAAU,+BAA+B,EAAES,WAAW,kBAAkB,CAAC,EACrG;oBAACzC,MAAMzD,UAAU0D,WAAW;gBAAA;YAEhC;YACA,OAAO;gBAACW;YAAM;QAChB;QAEA,MAAMgC,cAAczD,OAAO,MAAMzB,aAAayB,MAAM6C,WAAW,IAAI,CAACa,MAAM,IAAI1F;QAE9E,OAAO;YACLyD,QAAQ;mBAAIA;gBAAQ;oBAAC+B,KAAKF;oBAAYK,OAAO;wBAACF,YAAYG,IAAI;qBAAC;gBAAA;aAAE;YACjEjC,WAAWF,OAAOI,MAAM,KAAK,IAAI4B,YAAYI,KAAK,GAAGpD;QACvD;IACF;IAEQO,gBAAgBK,KAAyB,EAAsB;QACrE,IAAIA,UAAUZ,WAAW;YACvB,OAAOA;QACT;QAEA,MAAMqD,SAAS/F,gBAAgBsD;QAC/B,IAAI,WAAWyC,QAAQ;YACrB,IAAI,CAAClD,KAAK,CAACkD,OAAOlD,KAAK,EAAE;gBAACC,MAAMzD,UAAU0D,WAAW;YAAA;QACvD;QAEA,OAAOgD,OAAOtC,SAAS;IACzB;IAEQF,eAAeD,KAAa,EAAS;QAC3C,MAAMyC,SAAS1F,WAAWiD,MAAMV,IAAI;QACpC,IAAI,WAAWmD,QAAQ;YACrB,IAAI,CAAClD,KAAK,CAACkD,OAAOlD,KAAK,EAAE;gBAACC,MAAMzD,UAAU0D,WAAW;YAAA;QACvD;QAEA,OAAOgD,OAAOhE,KAAK;IACrB;IAEA,MAAciC,gBAAgBd,SAA4C,EAAmB;QAC3F,MAAM8C,qBAAqB,IAAI,CAACpE,KAAK,CAAC,aAAa;QACnD,MAAMqE,kBAAkB,AAAC,CAAA,MAAM,IAAI,CAACC,eAAe,EAAC,EAAGC,GAAG,EAAErB;QAC5D,MAAMsB,WAAW,MAAMzF,aAAa;YAAC0F,wBAAwB;QAAK;QAClE,MAAMC,iBAAiB,CAACxB,YACtBsB,SAASG,IAAI,CAAC,CAACC,UAAYA,QAAQjC,EAAE,KAAKO,YAAYnB,kBAAkBjB;QAC1E,MAAMiB,iBAAiB,MAAM,IAAI,CAACqB,mBAAmB,CAAC;YACpDyB,UAAUH,eAAeL;YACzBS,WAAWJ,eAAeN;QAC5B;QACA,MAAMW,uBAAuBP,SAASQ,MAAM,CAC1C,CAACJ,UAAYA,QAAQ7C,cAAc,KAAKA;QAE1C,IAAIqC,sBAAsB,CAACW,qBAAqBnB,IAAI,CAAC,CAAC,EAACjB,EAAE,EAAC,GAAKA,OAAOyB,qBAAqB;YACzF,IAAI,CAACnD,KAAK,CACR,CAAC,QAAQ,EAAEmD,mBAAmB,uBAAuB,EAAErC,eAAe,iCAAiC,CAAC,EACxG;gBAACb,MAAMzD,UAAU0D,WAAW;YAAA;QAEhC;QAEA,MAAMU,YAAY,MAAMP;QACxB,MAAMQ,SAAS,MAAMjD,gBAAgB;YACnCoG,sBAAsBb;YACtBI,UAAUO;QACZ;QACA,OAAO;YAAClD;YAAWC;YAAQC;QAAc;IAC3C;IAEA,MAAcR,kBAA+C;QAC3D,IAAI,IAAI,CAACU,YAAY,IAAI;YACvB,OAAOnB,UAAU,iCAAiC;;QACpD;QAEA,MAAMoE,SAAS,MAAMnH,OAAO;YAC1BoH,SAAS;gBACP;oBAAClB,MAAM;oBAASvC,OAAO;gBAAO;mBAC3BrC,mBAAmBoC,GAAG,CAAC,CAAC2D,OAAU,CAAA;wBACnCnB,MAAM,GAAGmB,KAAK,OAAO,EAAEjH,aAAaiH,MAAMC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;wBACzD3D,OAAO4D,OAAOF;oBAChB,CAAA;gBACA;oBAACnB,MAAM;oBAAevC,OAAO;gBAAQ;aACtC;YACDjB,SAAS;YACT8E,SAAS;QACX;QAEA,IAAIL,WAAW,SAAS;YACtB,OAAOpE;QACT;QAEA,IAAIoE,WAAW,UAAU;YACvB,MAAMxD,QAAQ,MAAM5D,MAAM;gBACxByH,SAAS;gBACTC,UAAU,CAAC1H;oBACT,MAAMqG,SAAS/F,gBAAgBN,MAAMkD,IAAI;oBACzC,OAAO,WAAWmD,SAASA,OAAOlD,KAAK,GAAG;gBAC5C;YACF;YACA,MAAMkD,SAAS/F,gBAAgBsD,MAAMV,IAAI;YACzC,OAAO,WAAWmD,SAASrD,YAAYqD,OAAOtC,SAAS;QACzD;QAEA,OAAO1D,aAAasH,OAAOP;IAC7B;IAEA,MAAcnE,iBAAkC;QAC9C,IAAI,IAAI,CAACkB,YAAY,IAAI;YACvB,IAAI,CAAChB,KAAK,CAAC,+DAA+D;gBACxEC,MAAMzD,UAAU0D,WAAW;YAC7B;QACF;QAEA,MAAM1B,QAAQ,MAAM3B,MAAM;YACxByH,SAAS;YACTC,UAAU,CAAC9D;gBACT,IAAI,CAACA,SAAS,CAACA,MAAMV,IAAI,IAAI;oBAC3B,OAAO;gBACT;gBACA,OAAO;YACT;QACF;QAEA,OAAOvB,MAAMuB,IAAI;IACnB;IAEA,MAAcoC,oBACZsC,uBAAgE,CAAC,CAAC,EACjD;QACjB,MAAM,EAACb,QAAQ,EAAEC,SAAS,EAAC,GAAGY;QAC9B,IAAI;YACF,OAAO,MAAMxH,sBAAsB;gBACjCyH,0BACEb,aAAa,AAAC,CAAA,MAAM,IAAI,CAACR,eAAe,EAAC,EAAGsB,GAAG,EAAE7D,kBAAkB8C;gBACrEgB,oBAAoB,IAAI,CAAC7F,KAAK,CAAC8F,YAAY;gBAC3CC,YAAY,IAAI,CAAC9D,YAAY;YAC/B;QACF,EAAE,OAAOhB,OAAO;YACd7B,kBAAkB,gCAAgC6B;YAClD,IAAI,CAACA,KAAK,CAACrD,gBAAgBqD,QAAQ;gBACjCC,MACED,iBAAiBhD,2BACbR,UAAU0D,WAAW,GACrB1D,UAAU8E,aAAa;YAC/B;QACF;IACF;IAEA,MAAcmB,mBAAoC;QAChD,IAAI,CAAC,IAAI,CAACzB,YAAY,IAAI;YACxB,OAAO,IAAI,CAAC+D,YAAY,CAAC;gBACvBnB,UAAU,IACR/F,iBAAiB;wBACfmH,qBAAqB;4BACnB;gCAAC9F,OAAO;gCAAQ+F,YAAY;4BAAsB;4BAClD;gCAAC/F,OAAO;gCAAU+F,YAAY;4BAAuB;yBACtD;oBACH;YACJ;QACF;QAEA,IAAI;YACF,OAAO,MAAM,IAAI,CAACF,YAAY;QAChC,EAAE,OAAO/E,OAAO;YACd,IAAI,CAACpD,2BAA2BoD,QAAQ,MAAMA;YAC9C,IAAI,CAACA,KAAK,CACR,uGACA;gBAACC,MAAMzD,UAAU0D,WAAW;YAAA;QAEhC;IACF;AACF;AAEA,SAASgF,cAAczE,KAAa;IAClC,OAAO,iBAAiB0E,IAAI,CAAC1E,SAASA,QAAQ,CAAC,CAAC,EAAEA,MAAM2E,UAAU,CAAC,KAAKf,OAAOgB,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC9F;AAEA,SAAS1D,oBACPE,GAAW,EACX,EACEjB,SAAS,EACTC,MAAM,EACNrC,KAAK,EACL4C,KAAK,EAMN;IAED,MAAMN,iBACJM,MAAMkE,SAAS,EAAEC,iBAAiB,iBAAiBnE,MAAMkE,SAAS,CAACtD,UAAU,GAAGnC;IAClF,OAAO;QACL,GAAGgC,IAAI,cAAc,CAAC;QACtBqD,cAAc1G;WACVsC,iBAAiB;YAAC,CAAC,eAAe,EAAEA,gBAAgB;SAAC,GAAG,EAAE;WAC1DF,YAAY;YAAC,CAAC,aAAa,EAAEA,WAAW;SAAC,GAAG,EAAE;WAC/CC,OAAOL,GAAG,CAAC,CAACtB,QAAU,CAAC,QAAQ,EAAE5B,YAAY4B,QAAQ;QACxD;KACD,CAACsG,IAAI,CAAC;AACT"}
|