@sanity/cli 8.20.0 → 8.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -47
- package/codemods/dashboard.js +111 -0
- package/dist/actions/build/buildApp.js +1 -1
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStudio.js +1 -1
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/codemods/dashboard.js +113 -0
- package/dist/actions/codemods/dashboard.js.map +1 -0
- package/dist/actions/codemods/index.js +2 -0
- package/dist/actions/codemods/index.js.map +1 -1
- package/dist/actions/codemods/types.js.map +1 -1
- package/dist/actions/deploy/deployApp.js +13 -6
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployChecks.js +12 -7
- package/dist/actions/deploy/deployChecks.js.map +1 -1
- package/dist/actions/deploy/deployRunner.js +14 -8
- package/dist/actions/deploy/deployRunner.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +39 -4
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/resolveDeployTarget.js +7 -6
- package/dist/actions/deploy/resolveDeployTarget.js.map +1 -1
- package/dist/actions/init/project/promptForAppTemplateSetup.js +22 -0
- package/dist/actions/init/project/promptForAppTemplateSetup.js.map +1 -1
- package/dist/actions/schema/listSchemas.js +2 -3
- package/dist/actions/schema/listSchemas.js.map +1 -1
- package/dist/actions/tokens/formatTokenAccess.js +18 -0
- package/dist/actions/tokens/formatTokenAccess.js.map +1 -0
- package/dist/actions/tokens/grants.js +12 -0
- package/dist/actions/tokens/grants.js.map +1 -1
- package/dist/actions/tokens/types.js.map +1 -1
- package/dist/actions/typegen/generateResourceTypes.js +11 -8
- package/dist/actions/typegen/generateResourceTypes.js.map +1 -1
- package/dist/actions/typegen/watchResourceTypes.js +208 -0
- package/dist/actions/typegen/watchResourceTypes.js.map +1 -0
- package/dist/actions/undeploy/runUndeploy.js +14 -8
- package/dist/actions/undeploy/runUndeploy.js.map +1 -1
- package/dist/commands/codemod.js +15 -4
- package/dist/commands/codemod.js.map +1 -1
- package/dist/commands/context/get.js +3 -8
- package/dist/commands/context/get.js.map +1 -1
- package/dist/commands/context/imports/download.js +3 -8
- package/dist/commands/context/imports/download.js.map +1 -1
- package/dist/commands/context/imports/get.js +3 -8
- package/dist/commands/context/imports/get.js.map +1 -1
- package/dist/commands/context/imports/list.js +3 -8
- package/dist/commands/context/imports/list.js.map +1 -1
- package/dist/commands/context/jobs/get.js +8 -8
- package/dist/commands/context/jobs/get.js.map +1 -1
- package/dist/commands/context/list.js +2 -6
- package/dist/commands/context/list.js.map +1 -1
- package/dist/commands/deploy.js +1 -0
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/doctor.js +2 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/openapi/list.js +2 -4
- package/dist/commands/openapi/list.js.map +1 -1
- package/dist/commands/projects/create.js +3 -6
- package/dist/commands/projects/create.js.map +1 -1
- package/dist/commands/schemas/list.js +1 -3
- package/dist/commands/schemas/list.js.map +1 -1
- package/dist/commands/tokens/create.js +2 -5
- package/dist/commands/tokens/create.js.map +1 -1
- package/dist/commands/tokens/delete.js +38 -30
- package/dist/commands/tokens/delete.js.map +1 -1
- package/dist/commands/tokens/list.js +27 -25
- package/dist/commands/tokens/list.js.map +1 -1
- package/dist/commands/tokens/rotate.js +2 -5
- package/dist/commands/tokens/rotate.js.map +1 -1
- package/dist/commands/typegen/generate.js +83 -45
- package/dist/commands/typegen/generate.js.map +1 -1
- package/dist/commands/undeploy.js +1 -0
- package/dist/commands/undeploy.js.map +1 -1
- package/dist/commands/whoami.js +5 -11
- package/dist/commands/whoami.js.map +1 -1
- package/dist/exports/invokeSanityCli/index.js +26 -6
- package/dist/exports/invokeSanityCli/index.js.map +1 -1
- package/dist/generated/apiRoutes.js +11 -26
- package/dist/generated/apiRoutes.js.map +1 -1
- package/dist/services/tokens.js +32 -22
- package/dist/services/tokens.js.map +1 -1
- package/dist/telemetry/init.telemetry.js.map +1 -1
- package/dist/util/resolveTokenScope.js +24 -0
- package/dist/util/resolveTokenScope.js.map +1 -0
- package/oclif.manifest.json +2027 -1964
- package/package.json +6 -5
package/dist/commands/whoami.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Flags } from '@oclif/core';
|
|
2
1
|
import { exitCodes, getCliTokenInfo, SanityCommand } from '@sanity/cli-core';
|
|
3
2
|
import { isHttpError } from '@sanity/client';
|
|
4
3
|
import { getProviderName } from '../actions/auth/getProviderName.js';
|
|
@@ -7,6 +6,7 @@ import { getSamlProviderId, resolveSSOProvider } from '../actions/whoami/resolve
|
|
|
7
6
|
import { getCliUser } from '../services/user.js';
|
|
8
7
|
export class WhoamiCommand extends SanityCommand {
|
|
9
8
|
static description = 'Show the user or API token the CLI is authenticated as';
|
|
9
|
+
static enableJsonFlag = true;
|
|
10
10
|
static examples = [
|
|
11
11
|
{
|
|
12
12
|
command: '<%= config.bin %> <%= command.id %>',
|
|
@@ -17,14 +17,8 @@ export class WhoamiCommand extends SanityCommand {
|
|
|
17
17
|
description: 'Output the current user as JSON, for scripts and agents'
|
|
18
18
|
}
|
|
19
19
|
];
|
|
20
|
-
static flags = {
|
|
21
|
-
json: Flags.boolean({
|
|
22
|
-
default: false,
|
|
23
|
-
description: 'Output as JSON'
|
|
24
|
-
})
|
|
25
|
-
};
|
|
26
20
|
async run() {
|
|
27
|
-
const {
|
|
21
|
+
const { json } = this.flags;
|
|
28
22
|
const tokenInfo = await getCliTokenInfo();
|
|
29
23
|
if (!tokenInfo?.token) {
|
|
30
24
|
this.error('Not logged in. Run `sanity login` to authenticate.', {
|
|
@@ -42,8 +36,8 @@ export class WhoamiCommand extends SanityCommand {
|
|
|
42
36
|
});
|
|
43
37
|
const samlProviderId = getSamlProviderId(user.provider);
|
|
44
38
|
const sso = samlProviderId ? await resolveSSOProvider(samlProviderId) : undefined;
|
|
45
|
-
if (
|
|
46
|
-
this.
|
|
39
|
+
if (json) {
|
|
40
|
+
this.logJson({
|
|
47
41
|
email: user.email ?? null,
|
|
48
42
|
id: user.id,
|
|
49
43
|
name: user.name,
|
|
@@ -52,7 +46,7 @@ export class WhoamiCommand extends SanityCommand {
|
|
|
52
46
|
sso: sso ?? null
|
|
53
47
|
} : {},
|
|
54
48
|
tokenSource: tokenInfo.source
|
|
55
|
-
}
|
|
49
|
+
});
|
|
56
50
|
return;
|
|
57
51
|
}
|
|
58
52
|
const padTo = 8 // "Provider" is the longest key
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/whoami.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/commands/whoami.ts"],"sourcesContent":["import {exitCodes, getCliTokenInfo, SanityCommand} from '@sanity/cli-core'\nimport {isHttpError} from '@sanity/client'\n\nimport {getProviderName} from '../actions/auth/getProviderName.js'\nimport {formatKeyValue} from '../actions/debug/output.js'\nimport {\n getSamlProviderId,\n resolveSSOProvider,\n type SSOProviderInfo,\n} from '../actions/whoami/resolveSSOProvider.js'\nimport {getCliUser} from '../services/user.js'\n\nexport class WhoamiCommand extends SanityCommand<typeof WhoamiCommand> {\n static override description = 'Show the user or API token the CLI is authenticated as'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Show the currently authenticated user',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --json',\n description: 'Output the current user as JSON, for scripts and agents',\n },\n ]\n\n public async run(): Promise<void> {\n const {json} = this.flags\n\n const tokenInfo = await getCliTokenInfo()\n if (!tokenInfo?.token) {\n this.error('Not logged in. Run `sanity login` to authenticate.', {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n const user = await getCliUser().catch((err: unknown) => {\n // A stale SANITY_AUTH_TOKEN overrides a valid saved login, so \"run sanity login\" won't help\n if (tokenInfo.source === ENV_TOKEN_SOURCE && isRejectedToken(err)) {\n this.error(\n 'Authentication failed using SANITY_AUTH_TOKEN.\\nUnset it to use your saved login, or replace it with a valid token.',\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n throw err\n })\n const samlProviderId = getSamlProviderId(user.provider)\n const sso = samlProviderId ? await resolveSSOProvider(samlProviderId) : undefined\n\n if (json) {\n this.logJson({\n email: user.email ?? null,\n id: user.id,\n name: user.name,\n provider: user.provider,\n ...(samlProviderId ? {sso: sso ?? null} : {}),\n tokenSource: tokenInfo.source,\n })\n return\n }\n\n const padTo = 8 // \"Provider\" is the longest key\n this.log(formatKeyValue('Name', user.name, {indent: 0, padTo}))\n if (user.email) {\n this.log(formatKeyValue('Email', user.email, {indent: 0, padTo}))\n }\n this.log(formatKeyValue('ID', user.id, {indent: 0, padTo}))\n this.log(\n formatKeyValue('Provider', formatProvider(user.provider, samlProviderId, sso), {\n indent: 0,\n padTo,\n }),\n )\n if (sso) {\n this.log(formatKeyValue('Org', formatOrganization(sso), {indent: 0, padTo}))\n }\n this.log(formatKeyValue('Token', tokenInfo.source, {indent: 0, padTo}))\n }\n}\n\nconst ENV_TOKEN_SOURCE = 'SANITY_AUTH_TOKEN environment variable'\n\nfunction isRejectedToken(err: unknown): boolean {\n return isHttpError(err) && (err.statusCode === 401 || err.statusCode === 403)\n}\n\nfunction formatProvider(\n provider: string,\n samlProviderId: string | undefined,\n sso: SSOProviderInfo | undefined,\n): string {\n if (provider === 'sanity-token') return 'API token'\n if (samlProviderId) return formatSamlProvider(sso)\n return getProviderName(provider)\n}\n\nfunction formatOrganization(sso: SSOProviderInfo): string {\n if (!sso.organizationSlug) return sso.organizationName\n return `${sso.organizationName} (sanity login --sso ${sso.organizationSlug})`\n}\n\nfunction formatSamlProvider(sso: SSOProviderInfo | undefined): string {\n // Provider names like \"saml\" or \"SSO\" repeat the label without adding anything\n const name = sso?.providerName.trim()\n if (!name || /^(saml|sso|saml sso)$/i.test(name)) return 'SAML SSO'\n return `SAML SSO (${name})`\n}\n"],"names":["exitCodes","getCliTokenInfo","SanityCommand","isHttpError","getProviderName","formatKeyValue","getSamlProviderId","resolveSSOProvider","getCliUser","WhoamiCommand","description","enableJsonFlag","examples","command","run","json","flags","tokenInfo","token","error","exit","RUNTIME_ERROR","user","catch","err","source","ENV_TOKEN_SOURCE","isRejectedToken","samlProviderId","provider","sso","undefined","logJson","email","id","name","tokenSource","padTo","log","indent","formatProvider","formatOrganization","statusCode","formatSamlProvider","organizationSlug","organizationName","providerName","trim","test"],"mappings":"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"}
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* (or `help`) renders root help listing the invokable topics, and a subject
|
|
23
23
|
* (`cors --help`, `cors list --help`) renders topic or command help.
|
|
24
24
|
*/ import { fileURLToPath } from 'node:url';
|
|
25
|
-
import { Config, Parser, settings } from '@oclif/core';
|
|
25
|
+
import { Config, Flags, Parser, settings } from '@oclif/core';
|
|
26
26
|
import { getHelpFlagAdditions, normalizeArgv } from '@oclif/core/help';
|
|
27
27
|
import { exitCodes } from '@sanity/cli-core';
|
|
28
28
|
import { deny, isConditionalInvocationPolicy } from '@sanity/cli-core/commandPolicy';
|
|
@@ -74,6 +74,12 @@ import { prettyPrintError } from './prettyPrintError.js';
|
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
76
|
let cachedConfig;
|
|
77
|
+
function withoutJsonFlag(argv) {
|
|
78
|
+
// Anything after `--` belongs to the command, not to us.
|
|
79
|
+
const passThrough = argv.indexOf('--');
|
|
80
|
+
const limit = passThrough === -1 ? argv.length : passThrough;
|
|
81
|
+
return argv.filter((token, index)=>index >= limit || token !== '--json');
|
|
82
|
+
}
|
|
77
83
|
function unknownCommandResult(argv, policySet) {
|
|
78
84
|
const available = Object.entries(policySet).filter(([, policy])=>policy.kind !== 'deny').map(([id])=>id.replaceAll(':', ' ')).toSorted();
|
|
79
85
|
return {
|
|
@@ -161,7 +167,8 @@ async function invokeSanityCliInContext({ args, source }, resolvedConfig, output
|
|
|
161
167
|
// space-separated topics, accepting colon-separated ids as-is), then apply
|
|
162
168
|
// the policy. Denied and uncategorized ids fail closed, indistinguishable
|
|
163
169
|
// from commands that don't exist.
|
|
164
|
-
const [commandId = '', ...
|
|
170
|
+
const [commandId = '', ...requestedArgv] = normalizeArgv(resolvedConfig, argv);
|
|
171
|
+
const commandArgv = withoutJsonFlag(requestedArgv);
|
|
165
172
|
const policy = policySet[commandId] ?? deny;
|
|
166
173
|
const commandDefinition = policy.kind === 'deny' ? undefined : resolvedConfig.findCommand(commandId);
|
|
167
174
|
if (!commandDefinition) return unknownCommandResult(argv, policySet);
|
|
@@ -176,9 +183,13 @@ async function invokeSanityCliInContext({ args, source }, resolvedConfig, output
|
|
|
176
183
|
try {
|
|
177
184
|
const parsed = await Parser.parse(commandArgv, {
|
|
178
185
|
args: CommandClass.args,
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
186
|
+
flags: {
|
|
187
|
+
...CommandClass.enableJsonFlag ? {
|
|
188
|
+
json: Flags.boolean()
|
|
189
|
+
} : {},
|
|
190
|
+
...CommandClass.baseFlags,
|
|
191
|
+
...CommandClass.flags
|
|
192
|
+
},
|
|
182
193
|
strict: CommandClass.strict
|
|
183
194
|
});
|
|
184
195
|
invocation = {
|
|
@@ -207,8 +218,17 @@ async function invokeSanityCliInContext({ args, source }, resolvedConfig, output
|
|
|
207
218
|
output
|
|
208
219
|
};
|
|
209
220
|
}
|
|
221
|
+
let command;
|
|
222
|
+
try {
|
|
223
|
+
command = instantiateCommand(CommandClass, commandArgv, resolvedConfig);
|
|
224
|
+
} catch (err) {
|
|
225
|
+
return {
|
|
226
|
+
commandId,
|
|
227
|
+
exitCode: err.oclif?.exit ?? exitCodes.RUNTIME_ERROR,
|
|
228
|
+
output: prettyPrintError(err) || String(err)
|
|
229
|
+
};
|
|
230
|
+
}
|
|
210
231
|
try {
|
|
211
|
-
const command = instantiateCommand(CommandClass, commandArgv, resolvedConfig);
|
|
212
232
|
await command.runInExecutionContext();
|
|
213
233
|
return {
|
|
214
234
|
commandId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/exports/invokeSanityCli/index.ts"],"sourcesContent":["/**\n * Programmatic (in-process) invocation of CLI commands, e.g. from an MCP\n * server. The invokable surface is governed by a per-source command policy\n * (see ./commandPolicies): every CLI command is explicitly allowed, denied,\n * or allowed conditionally on the parsed invocation. Commands contributed by\n * plugins are covered by the policies those plugins declare, and are denied\n * unless they declare one.\n *\n * {@link invokeSanityCli} handles arg parsing, policy enforcement, command\n * dispatch, per-invocation auth, and output capture.\n * ```ts\n * import {invokeSanityCli} from '@sanity/cli/invokeSanityCli'\n *\n * const {exitCode, output} = await invokeSanityCli({\n * args: 'cors list --project-id abc123',\n * source: 'mcp',\n * token: extra.authInfo.token,\n * })\n * ```\n *\n * Help works like the regular CLI, scoped to the source's policy: `--help`\n * (or `help`) renders root help listing the invokable topics, and a subject\n * (`cors --help`, `cors list --help`) renders topic or command help.\n */\nimport {fileURLToPath} from 'node:url'\n\nimport {Command, Config, Parser, settings} from '@oclif/core'\nimport {getHelpFlagAdditions, normalizeArgv} from '@oclif/core/help'\nimport {exitCodes} from '@sanity/cli-core'\nimport {\n type CommandPolicySet,\n deny,\n type InvocationSource,\n isConditionalInvocationPolicy,\n} from '@sanity/cli-core/commandPolicy'\nimport {runWithCliExecutionContext, type SanityEnvironment} from '@sanity/cli-core/executionContext'\nimport {type SanityCommand} from '@sanity/cli-core/SanityCommand'\nimport {type FetchFunction} from 'get-it'\nimport {parseArgsStringToArgv} from 'string-argv'\n\nimport {resolveTopicAliasInArgv} from '../../topicAliases.js'\nimport {resolveCommandPolicies} from './commandPolicies/index.js'\nimport {isHelpRequest, renderInvokableHelp} from './help.js'\nimport {prettyPrintError} from './prettyPrintError.js'\n\ntype InvokableCommand = Pick<SanityCommand<typeof Command>, 'runInExecutionContext'>\n\n/**\n * Whether a command can run in isolation, which in practice means it extends\n * `SanityCommand`: only that base class routes output, token resolution,\n * interactivity, and project discovery through the CLI execution context.\n *\n * This is a capability check, not a policy check. A plugin can declare a\n * policy for a command that still extends oclif's `Command` directly, and\n * such a command must not run here — the policy says the invocation is safe,\n * but nothing would hold it to the isolation guarantees that assessment\n * assumes.\n */\nfunction supportsIsolatedExecution(CommandClass: Command.Class): boolean {\n const prototype = CommandClass.prototype as Partial<InvokableCommand> | undefined\n return typeof prototype?.runInExecutionContext === 'function'\n}\n\n/**\n * Instantiate a policy-approved command for isolated execution.\n *\n * `runInExecutionContext()` runs the instance without oclif's static\n * `Command.run()` — the static runner re-enters `Config.load()` (filesystem\n * reads and a process-global config cache write) on every call. The manifest\n * types command classes as the abstract oclif `Command`, hence the\n * constructor cast.\n */\nfunction instantiateCommand(\n CommandClass: Command.Class,\n argv: string[],\n config: Config,\n): InvokableCommand {\n const ConcreteCommand = CommandClass as unknown as new (argv: string[], config: Config) => Command\n return new ConcreteCommand(argv, config) as unknown as InvokableCommand\n}\n\n/**\n * Load the oclif `Config` for this package, needed to resolve, load, and run\n * commands. Loading it once and reusing it across invocations avoids\n * re-reading the command manifest per call. It only reads this package's own\n * installed files — process-lifetime initialization, not per-invocation host\n * state — so it happens outside any execution context.\n *\n * `userPlugins: false` keeps this surface to the plugins this package ships\n * with. oclif otherwise loads whatever `<dataDir>/package.json` lists.\n */\nfunction loadCliCommandConfig(): Promise<Config> {\n return Config.load({root: fileURLToPath(import.meta.url), userPlugins: false})\n}\n\nlet cachedConfig: Promise<Config> | undefined\n\nfunction unknownCommandResult(argv: string[], policySet: CommandPolicySet): InvokeSanityCliResult {\n const available = Object.entries(policySet)\n .filter(([, policy]) => policy.kind !== 'deny')\n .map(([id]) => id.replaceAll(':', ' '))\n .toSorted()\n return {\n exitCode: exitCodes.USAGE_ERROR,\n output: [\n `Unknown or unsupported command: ${argv.slice(0, 2).join(' ') || '(none)'}`,\n `Available commands: ${available.join(', ')}`,\n ].join('\\n'),\n }\n}\n\n/**\n * @internal\n */\nexport interface InvokeSanityCliOptions {\n /**\n * Arguments after `sanity` (a leading `sanity` token is tolerated), either\n * as a single string — shell-style quoting is supported, but no shell is\n * ever executed — or as a pre-split argv array.\n */\n args: string | string[]\n\n /**\n * Where this invocation originates. Selects the command policy to enforce:\n * which commands are invokable and which invocations of them are permitted.\n */\n source: InvocationSource\n\n /**\n * Auth token for this invocation. Scoped to this call via the CLI execution\n * context: it never touches process env or the process-wide token cache, so\n * concurrent invocations with different tokens are fully isolated.\n */\n token: string\n\n /**\n * Optional oclif config override (mainly for tests). Defaults to this\n * package's config, loaded once and cached across invocations.\n */\n config?: Config\n\n /**\n * Optional fetch implementation for API requests made by this invocation.\n * Scoped to this call via the CLI execution context; defaults to the CLI's\n * own transport. The execution context's transport hygiene (such as\n * stripping the embedding process's lineage header) is applied on top.\n */\n fetch?: FetchFunction\n\n /**\n * Sanity deployment environment for this invocation. Scoped to this call\n * via the CLI execution context and defaults to production. The embedding\n * process's `SANITY_INTERNAL_ENV` is never consulted.\n */\n sanityEnv?: SanityEnvironment\n}\n\n/**\n * @internal\n */\nexport interface InvokeSanityCliResult {\n /** `0` on success, the command's exit code otherwise. */\n exitCode: number\n\n /** Combined stdout and stderr output, in emission order. */\n output: string\n\n /**\n * Canonical oclif command id when the invocation resolved to a command\n * exposed by the selected policy (for example, `datasets:create`).\n */\n commandId?: string\n}\n\n/**\n * Unlike a shell, string-argv keeps quotes that are glued to unquoted text:\n * `--name=\"my project\"` tokenizes with the quotes intact. Strip a matching\n * wrapping quote pair from the value side of `--flag=`-shaped tokens so the\n * common shell-style form yields the value the caller intended.\n */\nfunction stripFlagQuotes(rawToken: string): string {\n const match = /^(-{1,2}[^\\s=]+=)(['\"])([\\s\\S]*)\\2$/.exec(rawToken)\n return match ? match[1] + match[3] : rawToken\n}\n\n/**\n * Run a policy-permitted CLI command in-process and capture its result.\n *\n * Command-level failures (unknown command, bad flags, API errors) are\n * reported through `exitCode`/`output` rather than thrown, so callers can\n * relay them verbatim.\n *\n * @internal\n */\nexport async function invokeSanityCli(\n options: InvokeSanityCliOptions,\n): Promise<InvokeSanityCliResult> {\n // Always load compiled command modules. Oclif's dev-mode source resolution\n // otherwise probes tsconfigs (reading the filesystem and process.cwd) on\n // every command load, and may register ts-node process-wide.\n settings.enableAutoTranspile = false\n\n const resolvedConfig = options.config ?? (await (cachedConfig ??= loadCliCommandConfig()))\n const output: string[] = []\n const sink = (line: string) => output.push(line)\n const {fetch, sanityEnv, token} = options\n\n // Establish the isolation boundary before rendering help, loading command\n // modules, parsing, or executing. Any code reached by an external\n // invocation can therefore fail closed on context.\n return runWithCliExecutionContext({fetch, sanityEnv, stderr: sink, stdout: sink, token}, () =>\n invokeSanityCliInContext(options, resolvedConfig, output),\n )\n}\n\nasync function invokeSanityCliInContext(\n {args, source}: InvokeSanityCliOptions,\n resolvedConfig: Config,\n output: string[],\n): Promise<InvokeSanityCliResult> {\n // Combines this package's own policies with those each plugin declares for\n // the commands it contributes. Resolved once per config, not per call.\n const policySet = await resolveCommandPolicies(resolvedConfig, source)\n\n // Pre-split argv arrays are taken verbatim; only string input goes through\n // shell-style tokenization and quote normalization.\n let argv =\n typeof args === 'string'\n ? parseArgsStringToArgv(args).map((t) => stripFlagQuotes(t))\n : [...args]\n if (argv[0] === 'sanity') argv = argv.slice(1)\n argv = resolveTopicAliasInArgv(argv)\n\n // Help requests are routed through oclif's help system, scoped to the\n // source's policy: root help for a bare request, topic/command help when a\n // subject is given. Denied subjects get the standard unknown-command\n // response (identical to a truly unknown command, so hosts can't probe the\n // full CLI surface through help), and a help request never executes a\n // command.\n if (isHelpRequest(argv, resolvedConfig)) {\n try {\n // Drop a leading `help` so the rest is the subject, mirroring how\n // oclif's dispatch consumes the token before the help command sees argv\n const helpArgv = argv[0] === 'help' ? argv.slice(1) : argv\n const result = await renderInvokableHelp(resolvedConfig, helpArgv, policySet)\n if (result) return {...result, exitCode: exitCodes.SUCCESS}\n const helpFlags = getHelpFlagAdditions(resolvedConfig)\n return unknownCommandResult(\n helpArgv.filter((token) => !helpFlags.includes(token)),\n policySet,\n )\n } catch (err) {\n return {\n exitCode: exitCodes.RUNTIME_ERROR,\n output: err instanceof Error ? err.message : String(err),\n }\n }\n }\n\n // Resolve the command id the same way oclif's dispatch would (collating\n // space-separated topics, accepting colon-separated ids as-is), then apply\n // the policy. Denied and uncategorized ids fail closed, indistinguishable\n // from commands that don't exist.\n const [commandId = '', ...commandArgv] = normalizeArgv(resolvedConfig, argv)\n const policy = policySet[commandId] ?? deny\n const commandDefinition =\n policy.kind === 'deny' ? undefined : resolvedConfig.findCommand(commandId)\n if (!commandDefinition) return unknownCommandResult(argv, policySet)\n\n const CommandClass = await commandDefinition.load()\n\n // A policy can only speak to whether an invocation is safe; it cannot make\n // a command isolatable. One that isn't is treated as if it did not exist,\n // like every other fail-closed path here.\n if (!supportsIsolatedExecution(CommandClass)) return unknownCommandResult(argv, policySet)\n\n // Parse with the command's real definitions (without executing anything) so\n // conditional policies are evaluated against typed args/flags, not tokens.\n let invocation: {args: Record<string, unknown>; flags: Record<string, unknown>}\n try {\n const parsed = await Parser.parse(commandArgv, {\n args: CommandClass.args,\n baseFlags: CommandClass.baseFlags,\n enableJsonFlag: CommandClass.enableJsonFlag,\n flags: CommandClass.flags,\n strict: CommandClass.strict,\n })\n invocation = {\n args: parsed.args as Record<string, unknown>,\n flags: parsed.flags as Record<string, unknown>,\n }\n } catch (err) {\n return {\n commandId,\n exitCode: exitCodes.USAGE_ERROR,\n output: err instanceof Error ? err.message : String(err),\n }\n }\n\n if (!policy.validate(invocation)) {\n const displayId = commandId.replaceAll(':', ' ')\n let output = `This invocation of \\`${displayId}\\` is not supported here`\n\n if (isConditionalInvocationPolicy(policy)) {\n const usedDeniedFlags = policy.deniedFlags.filter(\n (name) => invocation.flags[name] !== undefined && invocation.flags[name] !== false,\n )\n if (usedDeniedFlags.length > 0) {\n output = `\\nThe ${usedDeniedFlags.map((name) => `--${name}`).join(', ')} flag is not supported here for \\`${displayId}\\``\n }\n }\n\n return {\n commandId,\n exitCode: exitCodes.USAGE_ERROR,\n output,\n }\n }\n\n try {\n const command = instantiateCommand(CommandClass, commandArgv, resolvedConfig)\n await command.runInExecutionContext()\n return {commandId, exitCode: exitCodes.SUCCESS, output: output.join('\\n')}\n } catch (err) {\n const exit = err.oclif?.exit\n\n // `this.exit(0)` throws an ExitError but is a successful outcome\n if (exit === exitCodes.SUCCESS) {\n return {commandId, exitCode: exitCodes.SUCCESS, output: output.join('\\n')}\n }\n\n const message = prettyPrintError(err) || String(err)\n if (message) output.push(message)\n return {\n commandId,\n exitCode: typeof exit === 'number' ? exit : exitCodes.RUNTIME_ERROR,\n output: output.join('\\n'),\n }\n }\n}\n"],"names":["fileURLToPath","Config","Parser","settings","getHelpFlagAdditions","normalizeArgv","exitCodes","deny","isConditionalInvocationPolicy","runWithCliExecutionContext","parseArgsStringToArgv","resolveTopicAliasInArgv","resolveCommandPolicies","isHelpRequest","renderInvokableHelp","prettyPrintError","supportsIsolatedExecution","CommandClass","prototype","runInExecutionContext","instantiateCommand","argv","config","ConcreteCommand","loadCliCommandConfig","load","root","url","userPlugins","cachedConfig","unknownCommandResult","policySet","available","Object","entries","filter","policy","kind","map","id","replaceAll","toSorted","exitCode","USAGE_ERROR","output","slice","join","stripFlagQuotes","rawToken","match","exec","invokeSanityCli","options","enableAutoTranspile","resolvedConfig","sink","line","push","fetch","sanityEnv","token","stderr","stdout","invokeSanityCliInContext","args","source","t","helpArgv","result","SUCCESS","helpFlags","includes","err","RUNTIME_ERROR","Error","message","String","commandId","commandArgv","commandDefinition","undefined","findCommand","invocation","parsed","parse","baseFlags","enableJsonFlag","flags","strict","validate","displayId","usedDeniedFlags","deniedFlags","name","length","command","exit","oclif"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;CAuBC,GACD,SAAQA,aAAa,QAAO,WAAU;AAEtC,SAAiBC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,QAAO,cAAa;AAC7D,SAAQC,oBAAoB,EAAEC,aAAa,QAAO,mBAAkB;AACpE,SAAQC,SAAS,QAAO,mBAAkB;AAC1C,SAEEC,IAAI,EAEJC,6BAA6B,QACxB,iCAAgC;AACvC,SAAQC,0BAA0B,QAA+B,oCAAmC;AAGpG,SAAQC,qBAAqB,QAAO,cAAa;AAEjD,SAAQC,uBAAuB,QAAO,wBAAuB;AAC7D,SAAQC,sBAAsB,QAAO,6BAA4B;AACjE,SAAQC,aAAa,EAAEC,mBAAmB,QAAO,YAAW;AAC5D,SAAQC,gBAAgB,QAAO,wBAAuB;AAItD;;;;;;;;;;CAUC,GACD,SAASC,0BAA0BC,YAA2B;IAC5D,MAAMC,YAAYD,aAAaC,SAAS;IACxC,OAAO,OAAOA,WAAWC,0BAA0B;AACrD;AAEA;;;;;;;;CAQC,GACD,SAASC,mBACPH,YAA2B,EAC3BI,IAAc,EACdC,MAAc;IAEd,MAAMC,kBAAkBN;IACxB,OAAO,IAAIM,gBAAgBF,MAAMC;AACnC;AAEA;;;;;;;;;CASC,GACD,SAASE;IACP,OAAOvB,OAAOwB,IAAI,CAAC;QAACC,MAAM1B,cAAc,YAAY2B,GAAG;QAAGC,aAAa;IAAK;AAC9E;AAEA,IAAIC;AAEJ,SAASC,qBAAqBT,IAAc,EAAEU,SAA2B;IACvE,MAAMC,YAAYC,OAAOC,OAAO,CAACH,WAC9BI,MAAM,CAAC,CAAC,GAAGC,OAAO,GAAKA,OAAOC,IAAI,KAAK,QACvCC,GAAG,CAAC,CAAC,CAACC,GAAG,GAAKA,GAAGC,UAAU,CAAC,KAAK,MACjCC,QAAQ;IACX,OAAO;QACLC,UAAUpC,UAAUqC,WAAW;QAC/BC,QAAQ;YACN,CAAC,gCAAgC,EAAEvB,KAAKwB,KAAK,CAAC,GAAG,GAAGC,IAAI,CAAC,QAAQ,UAAU;YAC3E,CAAC,oBAAoB,EAAEd,UAAUc,IAAI,CAAC,OAAO;SAC9C,CAACA,IAAI,CAAC;IACT;AACF;AAiEA;;;;;CAKC,GACD,SAASC,gBAAgBC,QAAgB;IACvC,MAAMC,QAAQ,sCAAsCC,IAAI,CAACF;IACzD,OAAOC,QAAQA,KAAK,CAAC,EAAE,GAAGA,KAAK,CAAC,EAAE,GAAGD;AACvC;AAEA;;;;;;;;CAQC,GACD,OAAO,eAAeG,gBACpBC,OAA+B;IAE/B,2EAA2E;IAC3E,yEAAyE;IACzE,6DAA6D;IAC7DjD,SAASkD,mBAAmB,GAAG;IAE/B,MAAMC,iBAAiBF,QAAQ9B,MAAM,IAAK,MAAOO,CAAAA,iBAAiBL,sBAAqB;IACvF,MAAMoB,SAAmB,EAAE;IAC3B,MAAMW,OAAO,CAACC,OAAiBZ,OAAOa,IAAI,CAACD;IAC3C,MAAM,EAACE,KAAK,EAAEC,SAAS,EAAEC,KAAK,EAAC,GAAGR;IAElC,0EAA0E;IAC1E,kEAAkE;IAClE,mDAAmD;IACnD,OAAO3C,2BAA2B;QAACiD;QAAOC;QAAWE,QAAQN;QAAMO,QAAQP;QAAMK;IAAK,GAAG,IACvFG,yBAAyBX,SAASE,gBAAgBV;AAEtD;AAEA,eAAemB,yBACb,EAACC,IAAI,EAAEC,MAAM,EAAyB,EACtCX,cAAsB,EACtBV,MAAgB;IAEhB,2EAA2E;IAC3E,uEAAuE;IACvE,MAAMb,YAAY,MAAMnB,uBAAuB0C,gBAAgBW;IAE/D,2EAA2E;IAC3E,oDAAoD;IACpD,IAAI5C,OACF,OAAO2C,SAAS,WACZtD,sBAAsBsD,MAAM1B,GAAG,CAAC,CAAC4B,IAAMnB,gBAAgBmB,MACvD;WAAIF;KAAK;IACf,IAAI3C,IAAI,CAAC,EAAE,KAAK,UAAUA,OAAOA,KAAKwB,KAAK,CAAC;IAC5CxB,OAAOV,wBAAwBU;IAE/B,sEAAsE;IACtE,2EAA2E;IAC3E,qEAAqE;IACrE,2EAA2E;IAC3E,sEAAsE;IACtE,WAAW;IACX,IAAIR,cAAcQ,MAAMiC,iBAAiB;QACvC,IAAI;YACF,kEAAkE;YAClE,wEAAwE;YACxE,MAAMa,WAAW9C,IAAI,CAAC,EAAE,KAAK,SAASA,KAAKwB,KAAK,CAAC,KAAKxB;YACtD,MAAM+C,SAAS,MAAMtD,oBAAoBwC,gBAAgBa,UAAUpC;YACnE,IAAIqC,QAAQ,OAAO;gBAAC,GAAGA,MAAM;gBAAE1B,UAAUpC,UAAU+D,OAAO;YAAA;YAC1D,MAAMC,YAAYlE,qBAAqBkD;YACvC,OAAOxB,qBACLqC,SAAShC,MAAM,CAAC,CAACyB,QAAU,CAACU,UAAUC,QAAQ,CAACX,SAC/C7B;QAEJ,EAAE,OAAOyC,KAAK;YACZ,OAAO;gBACL9B,UAAUpC,UAAUmE,aAAa;gBACjC7B,QAAQ4B,eAAeE,QAAQF,IAAIG,OAAO,GAAGC,OAAOJ;YACtD;QACF;IACF;IAEA,wEAAwE;IACxE,2EAA2E;IAC3E,0EAA0E;IAC1E,kCAAkC;IAClC,MAAM,CAACK,YAAY,EAAE,EAAE,GAAGC,YAAY,GAAGzE,cAAciD,gBAAgBjC;IACvE,MAAMe,SAASL,SAAS,CAAC8C,UAAU,IAAItE;IACvC,MAAMwE,oBACJ3C,OAAOC,IAAI,KAAK,SAAS2C,YAAY1B,eAAe2B,WAAW,CAACJ;IAClE,IAAI,CAACE,mBAAmB,OAAOjD,qBAAqBT,MAAMU;IAE1D,MAAMd,eAAe,MAAM8D,kBAAkBtD,IAAI;IAEjD,2EAA2E;IAC3E,0EAA0E;IAC1E,0CAA0C;IAC1C,IAAI,CAACT,0BAA0BC,eAAe,OAAOa,qBAAqBT,MAAMU;IAEhF,4EAA4E;IAC5E,2EAA2E;IAC3E,IAAImD;IACJ,IAAI;QACF,MAAMC,SAAS,MAAMjF,OAAOkF,KAAK,CAACN,aAAa;YAC7Cd,MAAM/C,aAAa+C,IAAI;YACvBqB,WAAWpE,aAAaoE,SAAS;YACjCC,gBAAgBrE,aAAaqE,cAAc;YAC3CC,OAAOtE,aAAasE,KAAK;YACzBC,QAAQvE,aAAauE,MAAM;QAC7B;QACAN,aAAa;YACXlB,MAAMmB,OAAOnB,IAAI;YACjBuB,OAAOJ,OAAOI,KAAK;QACrB;IACF,EAAE,OAAOf,KAAK;QACZ,OAAO;YACLK;YACAnC,UAAUpC,UAAUqC,WAAW;YAC/BC,QAAQ4B,eAAeE,QAAQF,IAAIG,OAAO,GAAGC,OAAOJ;QACtD;IACF;IAEA,IAAI,CAACpC,OAAOqD,QAAQ,CAACP,aAAa;QAChC,MAAMQ,YAAYb,UAAUrC,UAAU,CAAC,KAAK;QAC5C,IAAII,SAAS,CAAC,qBAAqB,EAAE8C,UAAU,wBAAwB,CAAC;QAExE,IAAIlF,8BAA8B4B,SAAS;YACzC,MAAMuD,kBAAkBvD,OAAOwD,WAAW,CAACzD,MAAM,CAC/C,CAAC0D,OAASX,WAAWK,KAAK,CAACM,KAAK,KAAKb,aAAaE,WAAWK,KAAK,CAACM,KAAK,KAAK;YAE/E,IAAIF,gBAAgBG,MAAM,GAAG,GAAG;gBAC9BlD,SAAS,CAAC,MAAM,EAAE+C,gBAAgBrD,GAAG,CAAC,CAACuD,OAAS,CAAC,EAAE,EAAEA,MAAM,EAAE/C,IAAI,CAAC,MAAM,kCAAkC,EAAE4C,UAAU,EAAE,CAAC;YAC3H;QACF;QAEA,OAAO;YACLb;YACAnC,UAAUpC,UAAUqC,WAAW;YAC/BC;QACF;IACF;IAEA,IAAI;QACF,MAAMmD,UAAU3E,mBAAmBH,cAAc6D,aAAaxB;QAC9D,MAAMyC,QAAQ5E,qBAAqB;QACnC,OAAO;YAAC0D;YAAWnC,UAAUpC,UAAU+D,OAAO;YAAEzB,QAAQA,OAAOE,IAAI,CAAC;QAAK;IAC3E,EAAE,OAAO0B,KAAK;QACZ,MAAMwB,OAAOxB,IAAIyB,KAAK,EAAED;QAExB,iEAAiE;QACjE,IAAIA,SAAS1F,UAAU+D,OAAO,EAAE;YAC9B,OAAO;gBAACQ;gBAAWnC,UAAUpC,UAAU+D,OAAO;gBAAEzB,QAAQA,OAAOE,IAAI,CAAC;YAAK;QAC3E;QAEA,MAAM6B,UAAU5D,iBAAiByD,QAAQI,OAAOJ;QAChD,IAAIG,SAAS/B,OAAOa,IAAI,CAACkB;QACzB,OAAO;YACLE;YACAnC,UAAU,OAAOsD,SAAS,WAAWA,OAAO1F,UAAUmE,aAAa;YACnE7B,QAAQA,OAAOE,IAAI,CAAC;QACtB;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../src/exports/invokeSanityCli/index.ts"],"sourcesContent":["/**\n * Programmatic (in-process) invocation of CLI commands, e.g. from an MCP\n * server. The invokable surface is governed by a per-source command policy\n * (see ./commandPolicies): every CLI command is explicitly allowed, denied,\n * or allowed conditionally on the parsed invocation. Commands contributed by\n * plugins are covered by the policies those plugins declare, and are denied\n * unless they declare one.\n *\n * {@link invokeSanityCli} handles arg parsing, policy enforcement, command\n * dispatch, per-invocation auth, and output capture.\n * ```ts\n * import {invokeSanityCli} from '@sanity/cli/invokeSanityCli'\n *\n * const {exitCode, output} = await invokeSanityCli({\n * args: 'cors list --project-id abc123',\n * source: 'mcp',\n * token: extra.authInfo.token,\n * })\n * ```\n *\n * Help works like the regular CLI, scoped to the source's policy: `--help`\n * (or `help`) renders root help listing the invokable topics, and a subject\n * (`cors --help`, `cors list --help`) renders topic or command help.\n */\nimport {fileURLToPath} from 'node:url'\n\nimport {Command, Config, Flags, Parser, settings} from '@oclif/core'\nimport {getHelpFlagAdditions, normalizeArgv} from '@oclif/core/help'\nimport {exitCodes} from '@sanity/cli-core'\nimport {\n type CommandPolicySet,\n deny,\n type InvocationSource,\n isConditionalInvocationPolicy,\n} from '@sanity/cli-core/commandPolicy'\nimport {runWithCliExecutionContext, type SanityEnvironment} from '@sanity/cli-core/executionContext'\nimport {type SanityCommand} from '@sanity/cli-core/SanityCommand'\nimport {type FetchFunction} from 'get-it'\nimport {parseArgsStringToArgv} from 'string-argv'\n\nimport {resolveTopicAliasInArgv} from '../../topicAliases.js'\nimport {resolveCommandPolicies} from './commandPolicies/index.js'\nimport {isHelpRequest, renderInvokableHelp} from './help.js'\nimport {prettyPrintError} from './prettyPrintError.js'\n\ntype InvokableCommand = Pick<SanityCommand<typeof Command>, 'runInExecutionContext'>\n\n/**\n * Whether a command can run in isolation, which in practice means it extends\n * `SanityCommand`: only that base class routes output, token resolution,\n * interactivity, and project discovery through the CLI execution context.\n *\n * This is a capability check, not a policy check. A plugin can declare a\n * policy for a command that still extends oclif's `Command` directly, and\n * such a command must not run here — the policy says the invocation is safe,\n * but nothing would hold it to the isolation guarantees that assessment\n * assumes.\n */\nfunction supportsIsolatedExecution(CommandClass: Command.Class): boolean {\n const prototype = CommandClass.prototype as Partial<InvokableCommand> | undefined\n return typeof prototype?.runInExecutionContext === 'function'\n}\n\n/**\n * Instantiate a policy-approved command for isolated execution.\n *\n * `runInExecutionContext()` runs the instance without oclif's static\n * `Command.run()` — the static runner re-enters `Config.load()` (filesystem\n * reads and a process-global config cache write) on every call. The manifest\n * types command classes as the abstract oclif `Command`, hence the\n * constructor cast.\n */\nfunction instantiateCommand(\n CommandClass: Command.Class,\n argv: string[],\n config: Config,\n): InvokableCommand {\n const ConcreteCommand = CommandClass as unknown as new (argv: string[], config: Config) => Command\n return new ConcreteCommand(argv, config) as unknown as InvokableCommand\n}\n\n/**\n * Load the oclif `Config` for this package, needed to resolve, load, and run\n * commands. Loading it once and reusing it across invocations avoids\n * re-reading the command manifest per call. It only reads this package's own\n * installed files — process-lifetime initialization, not per-invocation host\n * state — so it happens outside any execution context.\n *\n * `userPlugins: false` keeps this surface to the plugins this package ships\n * with. oclif otherwise loads whatever `<dataDir>/package.json` lists.\n */\nfunction loadCliCommandConfig(): Promise<Config> {\n return Config.load({root: fileURLToPath(import.meta.url), userPlugins: false})\n}\n\nlet cachedConfig: Promise<Config> | undefined\n\nfunction withoutJsonFlag(argv: string[]): string[] {\n // Anything after `--` belongs to the command, not to us.\n const passThrough = argv.indexOf('--')\n const limit = passThrough === -1 ? argv.length : passThrough\n return argv.filter((token, index) => index >= limit || token !== '--json')\n}\n\nfunction unknownCommandResult(argv: string[], policySet: CommandPolicySet): InvokeSanityCliResult {\n const available = Object.entries(policySet)\n .filter(([, policy]) => policy.kind !== 'deny')\n .map(([id]) => id.replaceAll(':', ' '))\n .toSorted()\n return {\n exitCode: exitCodes.USAGE_ERROR,\n output: [\n `Unknown or unsupported command: ${argv.slice(0, 2).join(' ') || '(none)'}`,\n `Available commands: ${available.join(', ')}`,\n ].join('\\n'),\n }\n}\n\n/**\n * @internal\n */\nexport interface InvokeSanityCliOptions {\n /**\n * Arguments after `sanity` (a leading `sanity` token is tolerated), either\n * as a single string — shell-style quoting is supported, but no shell is\n * ever executed — or as a pre-split argv array.\n */\n args: string | string[]\n\n /**\n * Where this invocation originates. Selects the command policy to enforce:\n * which commands are invokable and which invocations of them are permitted.\n */\n source: InvocationSource\n\n /**\n * Auth token for this invocation. Scoped to this call via the CLI execution\n * context: it never touches process env or the process-wide token cache, so\n * concurrent invocations with different tokens are fully isolated.\n */\n token: string\n\n /**\n * Optional oclif config override (mainly for tests). Defaults to this\n * package's config, loaded once and cached across invocations.\n */\n config?: Config\n\n /**\n * Optional fetch implementation for API requests made by this invocation.\n * Scoped to this call via the CLI execution context; defaults to the CLI's\n * own transport. The execution context's transport hygiene (such as\n * stripping the embedding process's lineage header) is applied on top.\n */\n fetch?: FetchFunction\n\n /**\n * Sanity deployment environment for this invocation. Scoped to this call\n * via the CLI execution context and defaults to production. The embedding\n * process's `SANITY_INTERNAL_ENV` is never consulted.\n */\n sanityEnv?: SanityEnvironment\n}\n\n/**\n * @internal\n */\nexport interface InvokeSanityCliResult {\n /** `0` on success, the command's exit code otherwise. */\n exitCode: number\n\n /** Combined stdout and stderr output, in emission order. */\n output: string\n\n /**\n * Canonical oclif command id when the invocation resolved to a command\n * exposed by the selected policy (for example, `datasets:create`).\n */\n commandId?: string\n}\n\n/**\n * Unlike a shell, string-argv keeps quotes that are glued to unquoted text:\n * `--name=\"my project\"` tokenizes with the quotes intact. Strip a matching\n * wrapping quote pair from the value side of `--flag=`-shaped tokens so the\n * common shell-style form yields the value the caller intended.\n */\nfunction stripFlagQuotes(rawToken: string): string {\n const match = /^(-{1,2}[^\\s=]+=)(['\"])([\\s\\S]*)\\2$/.exec(rawToken)\n return match ? match[1] + match[3] : rawToken\n}\n\n/**\n * Run a policy-permitted CLI command in-process and capture its result.\n *\n * Command-level failures (unknown command, bad flags, API errors) are\n * reported through `exitCode`/`output` rather than thrown, so callers can\n * relay them verbatim.\n *\n * @internal\n */\nexport async function invokeSanityCli(\n options: InvokeSanityCliOptions,\n): Promise<InvokeSanityCliResult> {\n // Always load compiled command modules. Oclif's dev-mode source resolution\n // otherwise probes tsconfigs (reading the filesystem and process.cwd) on\n // every command load, and may register ts-node process-wide.\n settings.enableAutoTranspile = false\n\n const resolvedConfig = options.config ?? (await (cachedConfig ??= loadCliCommandConfig()))\n const output: string[] = []\n const sink = (line: string) => output.push(line)\n const {fetch, sanityEnv, token} = options\n\n // Establish the isolation boundary before rendering help, loading command\n // modules, parsing, or executing. Any code reached by an external\n // invocation can therefore fail closed on context.\n return runWithCliExecutionContext({fetch, sanityEnv, stderr: sink, stdout: sink, token}, () =>\n invokeSanityCliInContext(options, resolvedConfig, output),\n )\n}\n\nasync function invokeSanityCliInContext(\n {args, source}: InvokeSanityCliOptions,\n resolvedConfig: Config,\n output: string[],\n): Promise<InvokeSanityCliResult> {\n // Combines this package's own policies with those each plugin declares for\n // the commands it contributes. Resolved once per config, not per call.\n const policySet = await resolveCommandPolicies(resolvedConfig, source)\n\n // Pre-split argv arrays are taken verbatim; only string input goes through\n // shell-style tokenization and quote normalization.\n let argv =\n typeof args === 'string'\n ? parseArgsStringToArgv(args).map((t) => stripFlagQuotes(t))\n : [...args]\n if (argv[0] === 'sanity') argv = argv.slice(1)\n argv = resolveTopicAliasInArgv(argv)\n\n // Help requests are routed through oclif's help system, scoped to the\n // source's policy: root help for a bare request, topic/command help when a\n // subject is given. Denied subjects get the standard unknown-command\n // response (identical to a truly unknown command, so hosts can't probe the\n // full CLI surface through help), and a help request never executes a\n // command.\n if (isHelpRequest(argv, resolvedConfig)) {\n try {\n // Drop a leading `help` so the rest is the subject, mirroring how\n // oclif's dispatch consumes the token before the help command sees argv\n const helpArgv = argv[0] === 'help' ? argv.slice(1) : argv\n const result = await renderInvokableHelp(resolvedConfig, helpArgv, policySet)\n if (result) return {...result, exitCode: exitCodes.SUCCESS}\n const helpFlags = getHelpFlagAdditions(resolvedConfig)\n return unknownCommandResult(\n helpArgv.filter((token) => !helpFlags.includes(token)),\n policySet,\n )\n } catch (err) {\n return {\n exitCode: exitCodes.RUNTIME_ERROR,\n output: err instanceof Error ? err.message : String(err),\n }\n }\n }\n\n // Resolve the command id the same way oclif's dispatch would (collating\n // space-separated topics, accepting colon-separated ids as-is), then apply\n // the policy. Denied and uncategorized ids fail closed, indistinguishable\n // from commands that don't exist.\n const [commandId = '', ...requestedArgv] = normalizeArgv(resolvedConfig, argv)\n const commandArgv = withoutJsonFlag(requestedArgv)\n const policy = policySet[commandId] ?? deny\n const commandDefinition =\n policy.kind === 'deny' ? undefined : resolvedConfig.findCommand(commandId)\n if (!commandDefinition) return unknownCommandResult(argv, policySet)\n\n const CommandClass = await commandDefinition.load()\n\n // A policy can only speak to whether an invocation is safe; it cannot make\n // a command isolatable. One that isn't is treated as if it did not exist,\n // like every other fail-closed path here.\n if (!supportsIsolatedExecution(CommandClass)) return unknownCommandResult(argv, policySet)\n\n // Parse with the command's real definitions (without executing anything) so\n // conditional policies are evaluated against typed args/flags, not tokens.\n let invocation: {args: Record<string, unknown>; flags: Record<string, unknown>}\n try {\n const parsed = await Parser.parse(commandArgv, {\n args: CommandClass.args,\n flags: {\n ...(CommandClass.enableJsonFlag ? {json: Flags.boolean()} : {}),\n ...CommandClass.baseFlags,\n ...CommandClass.flags,\n },\n strict: CommandClass.strict,\n })\n invocation = {\n args: parsed.args as Record<string, unknown>,\n flags: parsed.flags as Record<string, unknown>,\n }\n } catch (err) {\n return {\n commandId,\n exitCode: exitCodes.USAGE_ERROR,\n output: err instanceof Error ? err.message : String(err),\n }\n }\n\n if (!policy.validate(invocation)) {\n const displayId = commandId.replaceAll(':', ' ')\n let output = `This invocation of \\`${displayId}\\` is not supported here`\n\n if (isConditionalInvocationPolicy(policy)) {\n const usedDeniedFlags = policy.deniedFlags.filter(\n (name) => invocation.flags[name] !== undefined && invocation.flags[name] !== false,\n )\n if (usedDeniedFlags.length > 0) {\n output = `\\nThe ${usedDeniedFlags.map((name) => `--${name}`).join(', ')} flag is not supported here for \\`${displayId}\\``\n }\n }\n\n return {\n commandId,\n exitCode: exitCodes.USAGE_ERROR,\n output,\n }\n }\n\n let command: InvokableCommand\n try {\n command = instantiateCommand(CommandClass, commandArgv, resolvedConfig)\n } catch (err) {\n return {\n commandId,\n exitCode: err.oclif?.exit ?? exitCodes.RUNTIME_ERROR,\n output: prettyPrintError(err) || String(err),\n }\n }\n\n try {\n await command.runInExecutionContext()\n return {commandId, exitCode: exitCodes.SUCCESS, output: output.join('\\n')}\n } catch (err) {\n const exit = err.oclif?.exit\n\n // `this.exit(0)` throws an ExitError but is a successful outcome\n if (exit === exitCodes.SUCCESS) {\n return {commandId, exitCode: exitCodes.SUCCESS, output: output.join('\\n')}\n }\n\n const message = prettyPrintError(err) || String(err)\n if (message) output.push(message)\n\n return {\n commandId,\n exitCode: typeof exit === 'number' ? exit : exitCodes.RUNTIME_ERROR,\n output: output.join('\\n'),\n }\n }\n}\n"],"names":["fileURLToPath","Config","Flags","Parser","settings","getHelpFlagAdditions","normalizeArgv","exitCodes","deny","isConditionalInvocationPolicy","runWithCliExecutionContext","parseArgsStringToArgv","resolveTopicAliasInArgv","resolveCommandPolicies","isHelpRequest","renderInvokableHelp","prettyPrintError","supportsIsolatedExecution","CommandClass","prototype","runInExecutionContext","instantiateCommand","argv","config","ConcreteCommand","loadCliCommandConfig","load","root","url","userPlugins","cachedConfig","withoutJsonFlag","passThrough","indexOf","limit","length","filter","token","index","unknownCommandResult","policySet","available","Object","entries","policy","kind","map","id","replaceAll","toSorted","exitCode","USAGE_ERROR","output","slice","join","stripFlagQuotes","rawToken","match","exec","invokeSanityCli","options","enableAutoTranspile","resolvedConfig","sink","line","push","fetch","sanityEnv","stderr","stdout","invokeSanityCliInContext","args","source","t","helpArgv","result","SUCCESS","helpFlags","includes","err","RUNTIME_ERROR","Error","message","String","commandId","requestedArgv","commandArgv","commandDefinition","undefined","findCommand","invocation","parsed","parse","flags","enableJsonFlag","json","boolean","baseFlags","strict","validate","displayId","usedDeniedFlags","deniedFlags","name","command","oclif","exit"],"mappings":"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"}
|
|
@@ -205,6 +205,7 @@
|
|
|
205
205
|
defaultApiVersion: 'v2025-02-19',
|
|
206
206
|
host: 'global',
|
|
207
207
|
pathPatterns: [
|
|
208
|
+
'projects/{projectId}/datasets/copy',
|
|
208
209
|
'projects/{projectId}/datasets/{dataset}/copy'
|
|
209
210
|
],
|
|
210
211
|
slug: 'copy',
|
|
@@ -231,7 +232,7 @@
|
|
|
231
232
|
title: 'Embeddings Index API reference (deprecated)'
|
|
232
233
|
},
|
|
233
234
|
{
|
|
234
|
-
defaultApiVersion: '
|
|
235
|
+
defaultApiVersion: 'v2025-02-19',
|
|
235
236
|
host: 'project',
|
|
236
237
|
pathPatterns: [
|
|
237
238
|
'data/export/{dataset}'
|
|
@@ -314,28 +315,6 @@
|
|
|
314
315
|
slug: 'media-library',
|
|
315
316
|
title: 'Media Library API reference'
|
|
316
317
|
},
|
|
317
|
-
{
|
|
318
|
-
defaultApiVersion: 'v2025-02-19',
|
|
319
|
-
host: 'project',
|
|
320
|
-
pathPatterns: [
|
|
321
|
-
'media-libraries/{libraryId}/from-url',
|
|
322
|
-
'media-libraries/{libraryId}/mutate',
|
|
323
|
-
'media-libraries/{libraryId}/query',
|
|
324
|
-
'media-libraries/{libraryId}/references/documents/{assetId}/to',
|
|
325
|
-
'media-libraries/{libraryId}/refsearch',
|
|
326
|
-
'media-libraries/{libraryId}/signing-keys',
|
|
327
|
-
'media-libraries/{libraryId}/signing-keys/{keyId}',
|
|
328
|
-
'media-libraries/{libraryId}/upload',
|
|
329
|
-
'media-libraries/{libraryId}/video/{videoId}/playback-info',
|
|
330
|
-
'media-libraries/{libraryId}/video/{videoId}/playback/{type}',
|
|
331
|
-
'media-libraries/{libraryId}/video/{videoId}/renditions/{name}',
|
|
332
|
-
'media-libraries/{libraryId}/video/{videoId}/subtitles',
|
|
333
|
-
'media-libraries/{libraryId}/video/{videoId}/subtitles/upload',
|
|
334
|
-
'media-libraries/{libraryId}/video/{videoId}/subtitles/{subtitleId}'
|
|
335
|
-
],
|
|
336
|
-
slug: 'media-library',
|
|
337
|
-
title: 'Media Library API reference'
|
|
338
|
-
},
|
|
339
318
|
{
|
|
340
319
|
defaultApiVersion: 'v2025-02-19',
|
|
341
320
|
host: 'project',
|
|
@@ -354,6 +333,7 @@
|
|
|
354
333
|
'projects/{projectId}/cors',
|
|
355
334
|
'projects/{projectId}/cors/{id}',
|
|
356
335
|
'projects/{projectId}/datasets',
|
|
336
|
+
'projects/{projectId}/datasets/copy',
|
|
357
337
|
'projects/{projectId}/datasets/{datasetName}/tags/{tagIdentifier}',
|
|
358
338
|
'projects/{projectId}/datasets/{name}',
|
|
359
339
|
'projects/{projectId}/datasets/{name}/copy',
|
|
@@ -383,16 +363,19 @@
|
|
|
383
363
|
defaultApiVersion: 'v2021-10-04',
|
|
384
364
|
host: 'global',
|
|
385
365
|
pathPatterns: [
|
|
366
|
+
'auth/organizations/{organizationId}/providers/{providerId}/projects/{projectId}/role-mappings',
|
|
386
367
|
'organizations/{organizationId}/acl',
|
|
387
368
|
'organizations/{organizationId}/acl/{sanityUserId}',
|
|
388
369
|
'organizations/{organizationId}/grants',
|
|
389
|
-
'organizations/{organizationId}/providers/{providerId}/projects/{projectId}/role-mappings',
|
|
390
370
|
'projects/{projectId}/acl',
|
|
391
|
-
'projects/{projectId}/acl/{
|
|
371
|
+
'projects/{projectId}/acl/{projectUserId}',
|
|
392
372
|
'projects/{projectId}/datasets/{datasetName}/acl',
|
|
393
373
|
'projects/{projectId}/datasets/{datasetName}/grants',
|
|
394
374
|
'projects/{projectId}/grants',
|
|
375
|
+
'projects/{projectId}/grants/{projectUserId}',
|
|
395
376
|
'projects/{projectId}/permissionResourceSchemas',
|
|
377
|
+
'projects/{projectId}/permissionResources',
|
|
378
|
+
'projects/{projectId}/permissionResources/{resourceId}',
|
|
396
379
|
'projects/{projectId}/roles',
|
|
397
380
|
'projects/{projectId}/roles/{roleName}'
|
|
398
381
|
],
|
|
@@ -429,9 +412,11 @@
|
|
|
429
412
|
host: 'project',
|
|
430
413
|
pathPatterns: [
|
|
431
414
|
'hooks/projects/{projectId}',
|
|
415
|
+
'hooks/projects/{projectId}/attempts/{attemptId}',
|
|
432
416
|
'hooks/projects/{projectId}/{id}',
|
|
433
417
|
'hooks/projects/{projectId}/{id}/attempts',
|
|
434
|
-
'hooks/{id}/messages'
|
|
418
|
+
'hooks/projects/{projectId}/{id}/messages',
|
|
419
|
+
'hooks/projects/{projectId}/{id}/messages/{messageId}/attempts'
|
|
435
420
|
],
|
|
436
421
|
slug: 'webhooks',
|
|
437
422
|
title: 'Webhooks API reference'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/generated/apiRoutes.ts"],"sourcesContent":["/**\n * GENERATED FILE - DO NOT EDIT\n *\n * Routing manifest for `sanity api`, distilled from the published OpenAPI\n * specifications at https://www.sanity.io/docs/api/openapi\n *\n * Regenerate with: pnpm generate:api-routes\n */\nimport {type ApiRouteEntry} from '../actions/api/types.js'\n\nexport const apiRoutes: ApiRouteEntry[] = [\n {\n defaultApiVersion: 'v2025-07-11',\n host: 'global',\n pathPatterns: [\n 'access/invites/me',\n 'access/organization/{resourceId}/users/roles/default',\n 'access/requests/me',\n 'access/robots/me',\n 'access/robots/me/rotate',\n 'access/{resourceType}/{resourceId}/invites',\n 'access/{resourceType}/{resourceId}/invites/token/{inviteToken}',\n 'access/{resourceType}/{resourceId}/invites/token/{inviteToken}/accept',\n 'access/{resourceType}/{resourceId}/invites/token/{inviteToken}/eligibility',\n 'access/{resourceType}/{resourceId}/invites/{inviteId}',\n 'access/{resourceType}/{resourceId}/permissions',\n 'access/{resourceType}/{resourceId}/permissions/{permissionName}',\n 'access/{resourceType}/{resourceId}/requests',\n 'access/{resourceType}/{resourceId}/requests/state',\n 'access/{resourceType}/{resourceId}/requests/{requestId}/accept',\n 'access/{resourceType}/{resourceId}/requests/{requestId}/decline',\n 'access/{resourceType}/{resourceId}/robots',\n 'access/{resourceType}/{resourceId}/robots/{robotId}',\n 'access/{resourceType}/{resourceId}/roles',\n 'access/{resourceType}/{resourceId}/roles/{roleName}',\n 'access/{resourceType}/{resourceId}/user-permissions/me',\n 'access/{resourceType}/{resourceId}/user-permissions/me/check',\n 'access/{resourceType}/{resourceId}/users',\n 'access/{resourceType}/{resourceId}/users/me',\n 'access/{resourceType}/{resourceId}/users/{sanityUserId}',\n 'access/{resourceType}/{resourceId}/users/{sanityUserId}/roles',\n 'access/{resourceType}/{resourceId}/users/{sanityUserId}/roles/{roleName}'\n ],\n slug: 'access-api',\n title: 'Access API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/actions/{dataset}'\n ],\n slug: 'actions',\n title: 'Actions API reference'\n },\n {\n defaultApiVersion: 'v2021-02-01',\n host: 'global',\n pathPatterns: [\n 'activity',\n 'activity/export/csv'\n ],\n slug: 'activity-log',\n title: 'Activity Log API Reference'\n },\n {\n defaultApiVersion: 'vX',\n host: 'project',\n pathPatterns: [\n 'agent/action/generate/{dataset}',\n 'agent/action/patch/{dataset}',\n 'agent/action/prompt/{dataset}',\n 'agent/action/transform/{dataset}',\n 'agent/action/translate/{dataset}'\n ],\n slug: 'agent-actions',\n title: 'Agent Actions'\n },\n {\n host: 'global',\n pathPatterns: [\n 'applications',\n 'applications/{applicationId}',\n 'applications/{applicationId}/access',\n 'applications/{applicationId}/deployments',\n 'applications/{applicationId}/embeddable',\n 'applications/{applicationId}/installations',\n 'applications/{applicationId}/interfaces',\n 'applications/{applicationId}/workspaces',\n 'deploy',\n 'deploy/quickstart',\n 'installations',\n 'installations/ai-features',\n 'installations/catalog',\n 'installations/defaults',\n 'installations/{installationId}',\n 'installations/{installationId}/access',\n 'installations/{installationId}/configs',\n 'installations/{installationId}/configs/{configId}',\n 'installations/{installationId}/interfaces',\n 'organizations/{organizationId}/applications/{applicationId}',\n 'projects/{projectId}/user-applications',\n 'projects/{projectId}/user-applications/{userApplicationId}',\n 'projects/{projectId}/user-applications/{userApplicationId}/config/{configKey}',\n 'projects/{projectId}/user-applications/{userApplicationId}/deployments',\n 'studiohosts/{appHost}/availability',\n 'user-applications',\n 'user-applications/auto-update-version/{userApplicationId}',\n 'user-applications/resolve/application',\n 'user-applications/resolve/project',\n 'user-applications/workspaces',\n 'user-applications/{userApplicationId}',\n 'user-applications/{userApplicationId}/applicationData',\n 'user-applications/{userApplicationId}/config/{configKey}',\n 'user-applications/{userApplicationId}/deployments',\n 'user-applications/{userApplicationId}/workspaces'\n ],\n slug: 'applications-api',\n title: 'Applications API Reference'\n },\n {\n host: 'project',\n pathPatterns: [\n 'applications',\n 'applications/{applicationId}',\n 'applications/{applicationId}/access',\n 'applications/{applicationId}/deployments',\n 'applications/{applicationId}/embeddable',\n 'applications/{applicationId}/installations',\n 'applications/{applicationId}/interfaces',\n 'applications/{applicationId}/workspaces',\n 'deploy',\n 'deploy/quickstart',\n 'installations',\n 'installations/ai-features',\n 'installations/catalog',\n 'installations/defaults',\n 'installations/{installationId}',\n 'installations/{installationId}/access',\n 'installations/{installationId}/configs',\n 'installations/{installationId}/configs/{configId}',\n 'installations/{installationId}/interfaces',\n 'organizations/{organizationId}/applications/{applicationId}',\n 'projects/{projectId}/user-applications',\n 'projects/{projectId}/user-applications/{userApplicationId}',\n 'projects/{projectId}/user-applications/{userApplicationId}/config/{configKey}',\n 'projects/{projectId}/user-applications/{userApplicationId}/deployments',\n 'studiohosts/{appHost}/availability',\n 'user-applications',\n 'user-applications/auto-update-version/{userApplicationId}',\n 'user-applications/resolve/application',\n 'user-applications/resolve/project',\n 'user-applications/workspaces',\n 'user-applications/{userApplicationId}',\n 'user-applications/{userApplicationId}/applicationData',\n 'user-applications/{userApplicationId}/config/{configKey}',\n 'user-applications/{userApplicationId}/deployments',\n 'user-applications/{userApplicationId}/workspaces'\n ],\n slug: 'applications-api',\n title: 'Applications API Reference'\n },\n {\n defaultApiVersion: 'v2024-06-24',\n host: 'project',\n pathPatterns: [\n 'assets/files/{dataset}',\n 'assets/files/{dataset}/from-url',\n 'assets/images/{dataset}',\n 'assets/images/{dataset}/from-url',\n 'assets/media-library-link/{dataset}'\n ],\n slug: 'assets',\n title: 'Assets API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'global',\n pathPatterns: [\n 'projects/{projectId}/datasets/{datasetName}/backups',\n 'projects/{projectId}/datasets/{datasetName}/backups/{backupId}',\n 'projects/{projectId}/datasets/{datasetName}/settings/backups'\n ],\n slug: 'backups',\n title: 'Backups API reference'\n },\n {\n defaultApiVersion: 'v1',\n host: 'global',\n pathPatterns: [\n 'projects/{project_id}/datasets/{dataset_name}/assets/{asset_id}/purges',\n 'projects/{project_id}/datasets/{dataset_name}/purges'\n ],\n slug: 'cdn-cache-purge',\n title: 'CDN Cache Purge API Reference'\n },\n {\n defaultApiVersion: 'vX',\n host: 'global',\n pathPatterns: [\n 'agent/prompt',\n 'agent/{organizationId}/threads/{threadId}'\n ],\n slug: 'content-agent',\n title: 'Content Agent API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'global',\n pathPatterns: [\n 'projects/{projectId}/datasets/{dataset}/copy'\n ],\n slug: 'copy',\n title: 'Copy API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/doc/{dataset}/{documentId}'\n ],\n slug: 'doc',\n title: 'Doc API reference'\n },\n {\n defaultApiVersion: 'vX',\n host: 'project',\n pathPatterns: [\n 'embeddings-index/query/{dataset}/{indexName}',\n 'embeddings-index/{dataset}',\n 'embeddings-index/{dataset}/{indexName}'\n ],\n slug: 'embeddings-index',\n title: 'Embeddings Index API reference (deprecated)'\n },\n {\n defaultApiVersion: 'v2021-03-25',\n host: 'project',\n pathPatterns: [\n 'data/export/{dataset}'\n ],\n slug: 'export',\n title: 'Export API reference'\n },\n {\n host: 'global',\n pathPatterns: [\n 'functions',\n 'functions/{functionId}',\n 'functions/{functionId}/envvars',\n 'functions/{functionId}/envvars/{envVarKey}',\n 'functions/{functionId}/invoke',\n 'functions/{functionId}/logs',\n 'functions/{functionId}/logs/stream'\n ],\n slug: 'functions-api',\n title: 'Functions API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/history/{dataset}/documents/{documentId}',\n 'data/history/{dataset}/transactions',\n 'data/history/{dataset}/transactions/{documentIds}'\n ],\n slug: 'history',\n title: 'History API reference'\n },\n {\n defaultApiVersion: 'v2021-06-07',\n host: 'global',\n pathPatterns: [\n 'jobs/{jobId}',\n 'jobs/{jobId}/listen'\n ],\n slug: 'jobs',\n title: 'Jobs API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/listen/{dataset}'\n ],\n slug: 'listen',\n title: 'Listen API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/live/events/{dataset}'\n ],\n slug: 'live',\n title: 'Live Content API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'global',\n pathPatterns: [\n 'media-libraries/{libraryId}/from-url',\n 'media-libraries/{libraryId}/mutate',\n 'media-libraries/{libraryId}/query',\n 'media-libraries/{libraryId}/references/documents/{assetId}/to',\n 'media-libraries/{libraryId}/refsearch',\n 'media-libraries/{libraryId}/signing-keys',\n 'media-libraries/{libraryId}/signing-keys/{keyId}',\n 'media-libraries/{libraryId}/upload',\n 'media-libraries/{libraryId}/video/{videoId}/playback-info',\n 'media-libraries/{libraryId}/video/{videoId}/playback/{type}',\n 'media-libraries/{libraryId}/video/{videoId}/renditions/{name}',\n 'media-libraries/{libraryId}/video/{videoId}/subtitles',\n 'media-libraries/{libraryId}/video/{videoId}/subtitles/upload',\n 'media-libraries/{libraryId}/video/{videoId}/subtitles/{subtitleId}'\n ],\n slug: 'media-library',\n title: 'Media Library API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'media-libraries/{libraryId}/from-url',\n 'media-libraries/{libraryId}/mutate',\n 'media-libraries/{libraryId}/query',\n 'media-libraries/{libraryId}/references/documents/{assetId}/to',\n 'media-libraries/{libraryId}/refsearch',\n 'media-libraries/{libraryId}/signing-keys',\n 'media-libraries/{libraryId}/signing-keys/{keyId}',\n 'media-libraries/{libraryId}/upload',\n 'media-libraries/{libraryId}/video/{videoId}/playback-info',\n 'media-libraries/{libraryId}/video/{videoId}/playback/{type}',\n 'media-libraries/{libraryId}/video/{videoId}/renditions/{name}',\n 'media-libraries/{libraryId}/video/{videoId}/subtitles',\n 'media-libraries/{libraryId}/video/{videoId}/subtitles/upload',\n 'media-libraries/{libraryId}/video/{videoId}/subtitles/{subtitleId}'\n ],\n slug: 'media-library',\n title: 'Media Library API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/mutate/{dataset}'\n ],\n slug: 'mutation',\n title: 'Mutation API reference'\n },\n {\n defaultApiVersion: 'v2021-06-07',\n host: 'global',\n pathPatterns: [\n 'projects',\n 'projects/{projectId}',\n 'projects/{projectId}/cors',\n 'projects/{projectId}/cors/{id}',\n 'projects/{projectId}/datasets',\n 'projects/{projectId}/datasets/{datasetName}/tags/{tagIdentifier}',\n 'projects/{projectId}/datasets/{name}',\n 'projects/{projectId}/datasets/{name}/copy',\n 'projects/{projectId}/datasets/{name}/settings/embeddings',\n 'projects/{projectId}/datasets/{name}/tags',\n 'projects/{projectId}/features',\n 'projects/{projectId}/permissions',\n 'projects/{projectId}/tags',\n 'projects/{projectId}/tags/{tagIdentifier}',\n 'projects/{projectId}/tokens',\n 'projects/{projectId}/tokens/{tokenId}',\n 'projects/{projectId}/users/{userId}'\n ],\n slug: 'projects-api',\n title: 'Projects API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/query/{dataset}'\n ],\n slug: 'query',\n title: 'Query API reference'\n },\n {\n defaultApiVersion: 'v2021-10-04',\n host: 'global',\n pathPatterns: [\n 'organizations/{organizationId}/acl',\n 'organizations/{organizationId}/acl/{sanityUserId}',\n 'organizations/{organizationId}/grants',\n 'organizations/{organizationId}/providers/{providerId}/projects/{projectId}/role-mappings',\n 'projects/{projectId}/acl',\n 'projects/{projectId}/acl/{userId}',\n 'projects/{projectId}/datasets/{datasetName}/acl',\n 'projects/{projectId}/datasets/{datasetName}/grants',\n 'projects/{projectId}/grants',\n 'projects/{projectId}/permissionResourceSchemas',\n 'projects/{projectId}/roles',\n 'projects/{projectId}/roles/{roleName}'\n ],\n slug: 'roles',\n title: 'Roles API reference'\n },\n {\n defaultApiVersion: 'v2022-04-01',\n host: 'project',\n pathPatterns: [\n 'publish/{projectId}/{dataset}',\n 'schedules/{projectId}/{dataset}',\n 'schedules/{projectId}/{dataset}/{scheduleId}',\n 'schedules/{projectId}/{dataset}/{scheduleId}/publish',\n 'unpublish/{projectId}/{dataset}'\n ],\n slug: 'scheduling',\n title: 'Scheduling API reference'\n },\n {\n defaultApiVersion: 'v2026-04-27',\n host: 'global',\n pathPatterns: [\n 'organizations/{organizationId}/attribute-definitions',\n 'organizations/{organizationId}/attribute-definitions/{key}',\n 'organizations/{organizationId}/users/me/attributes',\n 'organizations/{organizationId}/users/{sanityUserId}/attributes'\n ],\n slug: 'user-attributes',\n title: 'User attributes API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'hooks/projects/{projectId}',\n 'hooks/projects/{projectId}/{id}',\n 'hooks/projects/{projectId}/{id}/attempts',\n 'hooks/{id}/messages'\n ],\n slug: 'webhooks',\n title: 'Webhooks API reference'\n }\n]\n"],"names":["apiRoutes","defaultApiVersion","host","pathPatterns","slug","title"],"mappings":"AAAA;;;;;;;CAOC,GAGD,OAAO,MAAMA,YAA6B;IACxC;QACEC,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEH,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEH,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEH,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;CACD,CAAA"}
|
|
1
|
+
{"version":3,"sources":["../../src/generated/apiRoutes.ts"],"sourcesContent":["/**\n * GENERATED FILE - DO NOT EDIT\n *\n * Routing manifest for `sanity api`, distilled from the published OpenAPI\n * specifications at https://www.sanity.io/docs/api/openapi\n *\n * Regenerate with: pnpm generate:api-routes\n */\nimport {type ApiRouteEntry} from '../actions/api/types.js'\n\nexport const apiRoutes: ApiRouteEntry[] = [\n {\n defaultApiVersion: 'v2025-07-11',\n host: 'global',\n pathPatterns: [\n 'access/invites/me',\n 'access/organization/{resourceId}/users/roles/default',\n 'access/requests/me',\n 'access/robots/me',\n 'access/robots/me/rotate',\n 'access/{resourceType}/{resourceId}/invites',\n 'access/{resourceType}/{resourceId}/invites/token/{inviteToken}',\n 'access/{resourceType}/{resourceId}/invites/token/{inviteToken}/accept',\n 'access/{resourceType}/{resourceId}/invites/token/{inviteToken}/eligibility',\n 'access/{resourceType}/{resourceId}/invites/{inviteId}',\n 'access/{resourceType}/{resourceId}/permissions',\n 'access/{resourceType}/{resourceId}/permissions/{permissionName}',\n 'access/{resourceType}/{resourceId}/requests',\n 'access/{resourceType}/{resourceId}/requests/state',\n 'access/{resourceType}/{resourceId}/requests/{requestId}/accept',\n 'access/{resourceType}/{resourceId}/requests/{requestId}/decline',\n 'access/{resourceType}/{resourceId}/robots',\n 'access/{resourceType}/{resourceId}/robots/{robotId}',\n 'access/{resourceType}/{resourceId}/roles',\n 'access/{resourceType}/{resourceId}/roles/{roleName}',\n 'access/{resourceType}/{resourceId}/user-permissions/me',\n 'access/{resourceType}/{resourceId}/user-permissions/me/check',\n 'access/{resourceType}/{resourceId}/users',\n 'access/{resourceType}/{resourceId}/users/me',\n 'access/{resourceType}/{resourceId}/users/{sanityUserId}',\n 'access/{resourceType}/{resourceId}/users/{sanityUserId}/roles',\n 'access/{resourceType}/{resourceId}/users/{sanityUserId}/roles/{roleName}'\n ],\n slug: 'access-api',\n title: 'Access API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/actions/{dataset}'\n ],\n slug: 'actions',\n title: 'Actions API reference'\n },\n {\n defaultApiVersion: 'v2021-02-01',\n host: 'global',\n pathPatterns: [\n 'activity',\n 'activity/export/csv'\n ],\n slug: 'activity-log',\n title: 'Activity Log API Reference'\n },\n {\n defaultApiVersion: 'vX',\n host: 'project',\n pathPatterns: [\n 'agent/action/generate/{dataset}',\n 'agent/action/patch/{dataset}',\n 'agent/action/prompt/{dataset}',\n 'agent/action/transform/{dataset}',\n 'agent/action/translate/{dataset}'\n ],\n slug: 'agent-actions',\n title: 'Agent Actions'\n },\n {\n host: 'global',\n pathPatterns: [\n 'applications',\n 'applications/{applicationId}',\n 'applications/{applicationId}/access',\n 'applications/{applicationId}/deployments',\n 'applications/{applicationId}/embeddable',\n 'applications/{applicationId}/installations',\n 'applications/{applicationId}/interfaces',\n 'applications/{applicationId}/workspaces',\n 'deploy',\n 'deploy/quickstart',\n 'installations',\n 'installations/ai-features',\n 'installations/catalog',\n 'installations/defaults',\n 'installations/{installationId}',\n 'installations/{installationId}/access',\n 'installations/{installationId}/configs',\n 'installations/{installationId}/configs/{configId}',\n 'installations/{installationId}/interfaces',\n 'organizations/{organizationId}/applications/{applicationId}',\n 'projects/{projectId}/user-applications',\n 'projects/{projectId}/user-applications/{userApplicationId}',\n 'projects/{projectId}/user-applications/{userApplicationId}/config/{configKey}',\n 'projects/{projectId}/user-applications/{userApplicationId}/deployments',\n 'studiohosts/{appHost}/availability',\n 'user-applications',\n 'user-applications/auto-update-version/{userApplicationId}',\n 'user-applications/resolve/application',\n 'user-applications/resolve/project',\n 'user-applications/workspaces',\n 'user-applications/{userApplicationId}',\n 'user-applications/{userApplicationId}/applicationData',\n 'user-applications/{userApplicationId}/config/{configKey}',\n 'user-applications/{userApplicationId}/deployments',\n 'user-applications/{userApplicationId}/workspaces'\n ],\n slug: 'applications-api',\n title: 'Applications API Reference'\n },\n {\n host: 'project',\n pathPatterns: [\n 'applications',\n 'applications/{applicationId}',\n 'applications/{applicationId}/access',\n 'applications/{applicationId}/deployments',\n 'applications/{applicationId}/embeddable',\n 'applications/{applicationId}/installations',\n 'applications/{applicationId}/interfaces',\n 'applications/{applicationId}/workspaces',\n 'deploy',\n 'deploy/quickstart',\n 'installations',\n 'installations/ai-features',\n 'installations/catalog',\n 'installations/defaults',\n 'installations/{installationId}',\n 'installations/{installationId}/access',\n 'installations/{installationId}/configs',\n 'installations/{installationId}/configs/{configId}',\n 'installations/{installationId}/interfaces',\n 'organizations/{organizationId}/applications/{applicationId}',\n 'projects/{projectId}/user-applications',\n 'projects/{projectId}/user-applications/{userApplicationId}',\n 'projects/{projectId}/user-applications/{userApplicationId}/config/{configKey}',\n 'projects/{projectId}/user-applications/{userApplicationId}/deployments',\n 'studiohosts/{appHost}/availability',\n 'user-applications',\n 'user-applications/auto-update-version/{userApplicationId}',\n 'user-applications/resolve/application',\n 'user-applications/resolve/project',\n 'user-applications/workspaces',\n 'user-applications/{userApplicationId}',\n 'user-applications/{userApplicationId}/applicationData',\n 'user-applications/{userApplicationId}/config/{configKey}',\n 'user-applications/{userApplicationId}/deployments',\n 'user-applications/{userApplicationId}/workspaces'\n ],\n slug: 'applications-api',\n title: 'Applications API Reference'\n },\n {\n defaultApiVersion: 'v2024-06-24',\n host: 'project',\n pathPatterns: [\n 'assets/files/{dataset}',\n 'assets/files/{dataset}/from-url',\n 'assets/images/{dataset}',\n 'assets/images/{dataset}/from-url',\n 'assets/media-library-link/{dataset}'\n ],\n slug: 'assets',\n title: 'Assets API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'global',\n pathPatterns: [\n 'projects/{projectId}/datasets/{datasetName}/backups',\n 'projects/{projectId}/datasets/{datasetName}/backups/{backupId}',\n 'projects/{projectId}/datasets/{datasetName}/settings/backups'\n ],\n slug: 'backups',\n title: 'Backups API reference'\n },\n {\n defaultApiVersion: 'v1',\n host: 'global',\n pathPatterns: [\n 'projects/{project_id}/datasets/{dataset_name}/assets/{asset_id}/purges',\n 'projects/{project_id}/datasets/{dataset_name}/purges'\n ],\n slug: 'cdn-cache-purge',\n title: 'CDN Cache Purge API Reference'\n },\n {\n defaultApiVersion: 'vX',\n host: 'global',\n pathPatterns: [\n 'agent/prompt',\n 'agent/{organizationId}/threads/{threadId}'\n ],\n slug: 'content-agent',\n title: 'Content Agent API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'global',\n pathPatterns: [\n 'projects/{projectId}/datasets/copy',\n 'projects/{projectId}/datasets/{dataset}/copy'\n ],\n slug: 'copy',\n title: 'Copy API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/doc/{dataset}/{documentId}'\n ],\n slug: 'doc',\n title: 'Doc API reference'\n },\n {\n defaultApiVersion: 'vX',\n host: 'project',\n pathPatterns: [\n 'embeddings-index/query/{dataset}/{indexName}',\n 'embeddings-index/{dataset}',\n 'embeddings-index/{dataset}/{indexName}'\n ],\n slug: 'embeddings-index',\n title: 'Embeddings Index API reference (deprecated)'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/export/{dataset}'\n ],\n slug: 'export',\n title: 'Export API reference'\n },\n {\n host: 'global',\n pathPatterns: [\n 'functions',\n 'functions/{functionId}',\n 'functions/{functionId}/envvars',\n 'functions/{functionId}/envvars/{envVarKey}',\n 'functions/{functionId}/invoke',\n 'functions/{functionId}/logs',\n 'functions/{functionId}/logs/stream'\n ],\n slug: 'functions-api',\n title: 'Functions API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/history/{dataset}/documents/{documentId}',\n 'data/history/{dataset}/transactions',\n 'data/history/{dataset}/transactions/{documentIds}'\n ],\n slug: 'history',\n title: 'History API reference'\n },\n {\n defaultApiVersion: 'v2021-06-07',\n host: 'global',\n pathPatterns: [\n 'jobs/{jobId}',\n 'jobs/{jobId}/listen'\n ],\n slug: 'jobs',\n title: 'Jobs API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/listen/{dataset}'\n ],\n slug: 'listen',\n title: 'Listen API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/live/events/{dataset}'\n ],\n slug: 'live',\n title: 'Live Content API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'global',\n pathPatterns: [\n 'media-libraries/{libraryId}/from-url',\n 'media-libraries/{libraryId}/mutate',\n 'media-libraries/{libraryId}/query',\n 'media-libraries/{libraryId}/references/documents/{assetId}/to',\n 'media-libraries/{libraryId}/refsearch',\n 'media-libraries/{libraryId}/signing-keys',\n 'media-libraries/{libraryId}/signing-keys/{keyId}',\n 'media-libraries/{libraryId}/upload',\n 'media-libraries/{libraryId}/video/{videoId}/playback-info',\n 'media-libraries/{libraryId}/video/{videoId}/playback/{type}',\n 'media-libraries/{libraryId}/video/{videoId}/renditions/{name}',\n 'media-libraries/{libraryId}/video/{videoId}/subtitles',\n 'media-libraries/{libraryId}/video/{videoId}/subtitles/upload',\n 'media-libraries/{libraryId}/video/{videoId}/subtitles/{subtitleId}'\n ],\n slug: 'media-library',\n title: 'Media Library API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/mutate/{dataset}'\n ],\n slug: 'mutation',\n title: 'Mutation API reference'\n },\n {\n defaultApiVersion: 'v2021-06-07',\n host: 'global',\n pathPatterns: [\n 'projects',\n 'projects/{projectId}',\n 'projects/{projectId}/cors',\n 'projects/{projectId}/cors/{id}',\n 'projects/{projectId}/datasets',\n 'projects/{projectId}/datasets/copy',\n 'projects/{projectId}/datasets/{datasetName}/tags/{tagIdentifier}',\n 'projects/{projectId}/datasets/{name}',\n 'projects/{projectId}/datasets/{name}/copy',\n 'projects/{projectId}/datasets/{name}/settings/embeddings',\n 'projects/{projectId}/datasets/{name}/tags',\n 'projects/{projectId}/features',\n 'projects/{projectId}/permissions',\n 'projects/{projectId}/tags',\n 'projects/{projectId}/tags/{tagIdentifier}',\n 'projects/{projectId}/tokens',\n 'projects/{projectId}/tokens/{tokenId}',\n 'projects/{projectId}/users/{userId}'\n ],\n slug: 'projects-api',\n title: 'Projects API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'data/query/{dataset}'\n ],\n slug: 'query',\n title: 'Query API reference'\n },\n {\n defaultApiVersion: 'v2021-10-04',\n host: 'global',\n pathPatterns: [\n 'auth/organizations/{organizationId}/providers/{providerId}/projects/{projectId}/role-mappings',\n 'organizations/{organizationId}/acl',\n 'organizations/{organizationId}/acl/{sanityUserId}',\n 'organizations/{organizationId}/grants',\n 'projects/{projectId}/acl',\n 'projects/{projectId}/acl/{projectUserId}',\n 'projects/{projectId}/datasets/{datasetName}/acl',\n 'projects/{projectId}/datasets/{datasetName}/grants',\n 'projects/{projectId}/grants',\n 'projects/{projectId}/grants/{projectUserId}',\n 'projects/{projectId}/permissionResourceSchemas',\n 'projects/{projectId}/permissionResources',\n 'projects/{projectId}/permissionResources/{resourceId}',\n 'projects/{projectId}/roles',\n 'projects/{projectId}/roles/{roleName}'\n ],\n slug: 'roles',\n title: 'Roles API reference'\n },\n {\n defaultApiVersion: 'v2022-04-01',\n host: 'project',\n pathPatterns: [\n 'publish/{projectId}/{dataset}',\n 'schedules/{projectId}/{dataset}',\n 'schedules/{projectId}/{dataset}/{scheduleId}',\n 'schedules/{projectId}/{dataset}/{scheduleId}/publish',\n 'unpublish/{projectId}/{dataset}'\n ],\n slug: 'scheduling',\n title: 'Scheduling API reference'\n },\n {\n defaultApiVersion: 'v2026-04-27',\n host: 'global',\n pathPatterns: [\n 'organizations/{organizationId}/attribute-definitions',\n 'organizations/{organizationId}/attribute-definitions/{key}',\n 'organizations/{organizationId}/users/me/attributes',\n 'organizations/{organizationId}/users/{sanityUserId}/attributes'\n ],\n slug: 'user-attributes',\n title: 'User attributes API reference'\n },\n {\n defaultApiVersion: 'v2025-02-19',\n host: 'project',\n pathPatterns: [\n 'hooks/projects/{projectId}',\n 'hooks/projects/{projectId}/attempts/{attemptId}',\n 'hooks/projects/{projectId}/{id}',\n 'hooks/projects/{projectId}/{id}/attempts',\n 'hooks/projects/{projectId}/{id}/messages',\n 'hooks/projects/{projectId}/{id}/messages/{messageId}/attempts'\n ],\n slug: 'webhooks',\n title: 'Webhooks API reference'\n }\n]\n"],"names":["apiRoutes","defaultApiVersion","host","pathPatterns","slug","title"],"mappings":"AAAA;;;;;;;CAOC,GAGD,OAAO,MAAMA,YAA6B;IACxC;QACEC,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEH,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEH,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEH,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;IACA;QACEJ,mBAAmB;QACnBC,MAAM;QACNC,cAAc;YACZ;YACA;YACA;YACA;YACA;YACA;SACD;QACDC,MAAM;QACNC,OAAO;IACT;CACD,CAAA"}
|
package/dist/services/tokens.js
CHANGED
|
@@ -9,13 +9,16 @@ function getClient(token) {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
|
-
async function fetchAllPages(client, url) {
|
|
12
|
+
async function fetchAllPages(client, url, query = {}) {
|
|
13
13
|
const items = [];
|
|
14
14
|
let cursor = null;
|
|
15
15
|
do {
|
|
16
16
|
const response = await client.request({
|
|
17
|
-
query:
|
|
18
|
-
|
|
17
|
+
query: {
|
|
18
|
+
...query,
|
|
19
|
+
...cursor === null ? {} : {
|
|
20
|
+
nextCursor: cursor
|
|
21
|
+
}
|
|
19
22
|
},
|
|
20
23
|
url
|
|
21
24
|
});
|
|
@@ -80,19 +83,26 @@ async function postRobot(url, { expiresAt, ...body }, query = {}) {
|
|
|
80
83
|
const { organizationId, ...body } = options;
|
|
81
84
|
return postRobot(`/access/organization/${organizationId}/robots`, body);
|
|
82
85
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
*/ export async function deleteToken(options) {
|
|
91
|
-
const { projectId, tokenId } = options;
|
|
86
|
+
function robotsUrl({ resourceId, resourceType }) {
|
|
87
|
+
return `/access/${resourceType}/${resourceId}/robots`;
|
|
88
|
+
}
|
|
89
|
+
function isManagedByOrganization(robot, organizationId) {
|
|
90
|
+
return robot.managedBy?.resourceType === 'organization' && robot.managedBy.resourceId === organizationId;
|
|
91
|
+
}
|
|
92
|
+
/** Delete a token from the requested scope. @internal */ export async function deleteToken(scope, tokenId) {
|
|
92
93
|
const client = await getClient();
|
|
94
|
+
const url = `${robotsUrl(scope)}/${tokenId}`;
|
|
95
|
+
if (scope.resourceType === 'organization') {
|
|
96
|
+
const robot = await client.request({
|
|
97
|
+
url
|
|
98
|
+
});
|
|
99
|
+
if (!isManagedByOrganization(robot, scope.resourceId)) {
|
|
100
|
+
throw new Error(`Token "${tokenId}" is not managed by organization "${scope.resourceId}". Use tokens list --organization ${scope.resourceId} to find tokens managed by this organization.`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
93
103
|
return client.request({
|
|
94
104
|
method: 'DELETE',
|
|
95
|
-
url
|
|
105
|
+
url
|
|
96
106
|
});
|
|
97
107
|
}
|
|
98
108
|
/**
|
|
@@ -110,16 +120,16 @@ async function postRobot(url, { expiresAt, ...body }, query = {}) {
|
|
|
110
120
|
url: '/access/robots/me/rotate'
|
|
111
121
|
});
|
|
112
122
|
}
|
|
113
|
-
/**
|
|
114
|
-
* Get all tokens for a project. Tokens managed by an organization are
|
|
115
|
-
* excluded: they cannot be managed at the project scope.
|
|
116
|
-
* @param projectId - The project ID
|
|
117
|
-
* @returns A promise that resolves to an array of robots
|
|
118
|
-
*
|
|
119
|
-
* @internal
|
|
120
|
-
*/ export async function getTokens(projectId) {
|
|
123
|
+
/** List tokens managed at the requested scope. @internal */ export async function getTokens(scope) {
|
|
121
124
|
const client = await getClient();
|
|
122
|
-
const
|
|
125
|
+
const query = scope.resourceType === 'organization' ? {
|
|
126
|
+
includeChildren: 'true',
|
|
127
|
+
limit: '500'
|
|
128
|
+
} : {};
|
|
129
|
+
const robots = await fetchAllPages(client, robotsUrl(scope), query);
|
|
130
|
+
if (scope.resourceType === 'organization') {
|
|
131
|
+
return robots.filter((robot)=>isManagedByOrganization(robot, scope.resourceId));
|
|
132
|
+
}
|
|
123
133
|
return robots.filter((robot)=>robot.managedBy?.resourceType !== 'organization');
|
|
124
134
|
}
|
|
125
135
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/tokens.ts"],"sourcesContent":["import {getGlobalCliClient} from '@sanity/cli-core'\nimport {type SanityClient} from '@sanity/client'\n\nimport {TOKENS_API_VERSION} from '../actions/tokens/constants.js'\nimport {\n type Membership,\n type Robot,\n type RobotWithToken,\n type Role,\n} from '../actions/tokens/types.js'\n\ninterface PaginatedResponse<T> {\n data: T[]\n nextCursor: string | null\n}\n\nfunction getClient(token?: string): Promise<SanityClient> {\n return getGlobalCliClient({\n apiVersion: TOKENS_API_VERSION,\n requireUser: true,\n ...(token === undefined ? {} : {token}),\n })\n}\n\nasync function fetchAllPages<T>(client: SanityClient
|
|
1
|
+
{"version":3,"sources":["../../src/services/tokens.ts"],"sourcesContent":["import {getGlobalCliClient} from '@sanity/cli-core'\nimport {type SanityClient} from '@sanity/client'\n\nimport {TOKENS_API_VERSION} from '../actions/tokens/constants.js'\nimport {\n type Membership,\n type Robot,\n type RobotWithToken,\n type Role,\n type TokenScope,\n} from '../actions/tokens/types.js'\n\ninterface PaginatedResponse<T> {\n data: T[]\n nextCursor: string | null\n}\n\nfunction getClient(token?: string): Promise<SanityClient> {\n return getGlobalCliClient({\n apiVersion: TOKENS_API_VERSION,\n requireUser: true,\n ...(token === undefined ? {} : {token}),\n })\n}\n\nasync function fetchAllPages<T>(\n client: SanityClient,\n url: string,\n query: Record<string, string> = {},\n): Promise<T[]> {\n const items: T[] = []\n let cursor: string | null = null\n\n do {\n const response: PaginatedResponse<T> = await client.request<PaginatedResponse<T>>({\n query: {...query, ...(cursor === null ? {} : {nextCursor: cursor})},\n url,\n })\n items.push(...response.data)\n cursor = response.nextCursor\n } while (cursor !== null)\n\n return items\n}\n\n/**\n * Get the membership granting a robot access to the given project\n * @param robot - The robot to inspect\n * @param projectId - The project ID\n * @returns The project membership, if any\n *\n * @internal\n */\nexport function getProjectMembership(robot: Robot, projectId: string): Membership | undefined {\n return robot.memberships.find(\n (membership) => membership.resourceType === 'project' && membership.resourceId === projectId,\n )\n}\n\ninterface RobotBody {\n label: string\n memberships: Membership[]\n\n expiresAt?: string\n}\n\nasync function postRobot(\n url: string,\n {expiresAt, ...body}: RobotBody,\n query: Record<string, string> = {},\n): Promise<RobotWithToken> {\n const client = await getClient()\n\n return client.request<RobotWithToken>({\n body: {...body, ...(expiresAt === undefined ? {} : {expiresAt})},\n method: 'POST',\n query,\n url,\n })\n}\n\ninterface CreateTokenOptions {\n label: string\n projectId: string\n roleNames: string[]\n\n expiresAt?: string\n sendNotification?: boolean\n}\n\n/**\n * Add a token to a project\n * @param options - The options for adding a token to a project\n * @returns A promise that resolves to the created robot, including its secret token\n *\n * @internal\n */\nexport async function createToken(options: CreateTokenOptions): Promise<RobotWithToken> {\n const {expiresAt, label, projectId, roleNames, sendNotification} = options\n\n return postRobot(\n `/access/project/${projectId}/robots`,\n {\n expiresAt,\n label,\n memberships: [{resourceId: projectId, resourceType: 'project', roleNames}],\n },\n sendNotification === false ? {sendNotification: 'false'} : {},\n )\n}\n\ninterface CreateOrganizationTokenOptions extends RobotBody {\n organizationId: string\n}\n\n/**\n * Create an organization token, which can hold organization permissions and roles on several projects\n * @param options - The options for the organization token\n * @returns A promise that resolves to the created robot, including its secret token\n *\n * @internal\n */\nexport async function createOrganizationToken(\n options: CreateOrganizationTokenOptions,\n): Promise<RobotWithToken> {\n const {organizationId, ...body} = options\n\n return postRobot(`/access/organization/${organizationId}/robots`, body)\n}\n\nfunction robotsUrl({resourceId, resourceType}: TokenScope): string {\n return `/access/${resourceType}/${resourceId}/robots`\n}\n\nfunction isManagedByOrganization(robot: Robot, organizationId: string): boolean {\n return (\n robot.managedBy?.resourceType === 'organization' &&\n robot.managedBy.resourceId === organizationId\n )\n}\n\n/** Delete a token from the requested scope. @internal */\nexport async function deleteToken(scope: TokenScope, tokenId: string): Promise<void> {\n const client = await getClient()\n const url = `${robotsUrl(scope)}/${tokenId}`\n\n if (scope.resourceType === 'organization') {\n const robot = await client.request<Robot>({url})\n if (!isManagedByOrganization(robot, scope.resourceId)) {\n throw new Error(\n `Token \"${tokenId}\" is not managed by organization \"${scope.resourceId}\". Use tokens list --organization ${scope.resourceId} to find tokens managed by this organization.`,\n )\n }\n }\n\n return client.request({method: 'DELETE', url})\n}\n\n/**\n * Rotate a robot token, replacing its secret while preserving the robot,\n * its roles, and the token's expiry. The request authenticates as the robot\n * itself; the previous secret is revoked immediately.\n * @param token - The current robot token secret\n * @returns A promise that resolves to the robot with its new secret token\n *\n * @internal\n */\nexport async function rotateToken(token: string): Promise<RobotWithToken> {\n const client = await getClient(token)\n\n return client.request<RobotWithToken>({\n method: 'POST',\n url: '/access/robots/me/rotate',\n })\n}\n\n/** List tokens managed at the requested scope. @internal */\nexport async function getTokens(scope: TokenScope): Promise<Robot[]> {\n const client = await getClient()\n const query: Record<string, string> =\n scope.resourceType === 'organization' ? {includeChildren: 'true', limit: '500'} : {}\n const robots = await fetchAllPages<Robot>(client, robotsUrl(scope), query)\n\n if (scope.resourceType === 'organization') {\n return robots.filter((robot) => isManagedByOrganization(robot, scope.resourceId))\n }\n\n return robots.filter((robot) => robot.managedBy?.resourceType !== 'organization')\n}\n\n/**\n * Get all roles for a project\n * @param projectId - The project ID\n * @returns A promise that resolves to an array of project roles\n *\n * @internal\n */\nexport async function getTokenRoles(projectId: string): Promise<Role[]> {\n const client = await getClient()\n\n return fetchAllPages<Role>(client, `/access/project/${projectId}/roles`)\n}\n"],"names":["getGlobalCliClient","TOKENS_API_VERSION","getClient","token","apiVersion","requireUser","undefined","fetchAllPages","client","url","query","items","cursor","response","request","nextCursor","push","data","getProjectMembership","robot","projectId","memberships","find","membership","resourceType","resourceId","postRobot","expiresAt","body","method","createToken","options","label","roleNames","sendNotification","createOrganizationToken","organizationId","robotsUrl","isManagedByOrganization","managedBy","deleteToken","scope","tokenId","Error","rotateToken","getTokens","includeChildren","limit","robots","filter","getTokenRoles"],"mappings":"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"}
|