@sanity/cli 8.3.0 → 8.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/build/buildApp.js +14 -7
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStudio.js +3 -3
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/deploy/deployApp.js +32 -25
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +2 -1
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js +2 -4
- package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js.map +1 -1
- package/dist/actions/deploy/deploymentPlan.js.map +1 -1
- package/dist/actions/dev/devAction.js +2 -2
- package/dist/actions/dev/devAction.js.map +1 -1
- package/dist/actions/dev/servers/getDevServerConfig.js +13 -6
- package/dist/actions/dev/servers/getDevServerConfig.js.map +1 -1
- package/dist/actions/dev/servers/startAppDevServer.js +4 -2
- package/dist/actions/dev/servers/startAppDevServer.js.map +1 -1
- package/dist/actions/graphql/gen1/generateTypeFilters.js +1 -2
- package/dist/actions/graphql/gen1/generateTypeFilters.js.map +1 -1
- package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js +5 -2
- package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js.map +1 -1
- package/dist/actions/init/templates/shopify.js +2 -1
- package/dist/actions/init/templates/shopify.js.map +1 -1
- package/dist/actions/manifest/extractManifest.js +5 -37
- package/dist/actions/manifest/extractManifest.js.map +1 -1
- package/dist/actions/manifest/extractStudioManifest.js +1 -1
- package/dist/actions/manifest/extractStudioManifest.js.map +1 -1
- package/dist/actions/preview/previewAction.js +1 -1
- package/dist/actions/preview/previewAction.js.map +1 -1
- package/dist/actions/schema/deleteSchemaAction.js +1 -1
- package/dist/actions/schema/deleteSchemaAction.js.map +1 -1
- package/dist/actions/schema/deploySchemas.js.map +1 -1
- package/dist/actions/schema/extractSanityWorkspace.worker.js +1 -1
- package/dist/actions/schema/extractSanityWorkspace.worker.js.map +1 -1
- package/dist/actions/schema/listSchemas.js +1 -1
- package/dist/actions/schema/listSchemas.js.map +1 -1
- package/dist/actions/schema/schemaTypeHelpers.js +5 -0
- package/dist/actions/schema/schemaTypeHelpers.js.map +1 -0
- package/dist/actions/schema/updateWorkspaceSchema.js +1 -1
- package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -1
- package/dist/actions/schema/utils/schemaStoreValidation.js +2 -2
- package/dist/actions/schema/utils/schemaStoreValidation.js.map +1 -1
- package/dist/actions/schema/utils/workspaceSchemaId.js +1 -1
- package/dist/actions/schema/utils/workspaceSchemaId.js.map +1 -1
- package/dist/actions/versions/getFormatters.js +1 -2
- package/dist/actions/versions/getFormatters.js.map +1 -1
- package/dist/commands/documents/create.js +4 -4
- package/dist/commands/documents/create.js.map +1 -1
- package/dist/commands/hooks/logs.js +1 -2
- package/dist/commands/hooks/logs.js.map +1 -1
- package/dist/commands/projects/list.js +3 -5
- package/dist/commands/projects/list.js.map +1 -1
- package/dist/commands/undeploy.js +7 -5
- package/dist/commands/undeploy.js.map +1 -1
- package/dist/commands/users/list.js +3 -5
- package/dist/commands/users/list.js.map +1 -1
- package/dist/commands/versions.js +1 -2
- package/dist/commands/versions.js.map +1 -1
- package/dist/exports/_internal.d.ts +1 -67
- package/dist/exports/_internal.js +1 -1
- package/dist/exports/_internal.js.map +1 -1
- package/dist/exports/index.d.ts +2 -2
- package/dist/exports/index.js +2 -1
- package/dist/exports/index.js.map +1 -1
- package/dist/exports/runtime.d.ts +2 -2
- package/dist/exports/runtime.js +1 -1
- package/dist/exports/runtime.js.map +1 -1
- package/dist/generated/apiRoutes.js +4 -0
- package/dist/generated/apiRoutes.js.map +1 -1
- package/dist/prompts/selectMediaLibrary.js +2 -3
- package/dist/prompts/selectMediaLibrary.js.map +1 -1
- package/dist/services/mintProject.js +27 -14
- package/dist/services/mintProject.js.map +1 -1
- package/dist/services/schemas.js.map +1 -1
- package/dist/services/userApplications.js.map +1 -1
- package/dist/util/determineIsApp.js +1 -1
- package/dist/util/determineIsApp.js.map +1 -1
- package/dist/util/sortRowsByColumn.js +23 -0
- package/dist/util/sortRowsByColumn.js.map +1 -0
- package/oclif.manifest.json +253 -253
- package/package.json +6 -9
- package/dist/actions/manifest/blockTypeTransformer.js +0 -67
- package/dist/actions/manifest/blockTypeTransformer.js.map +0 -1
- package/dist/actions/manifest/extractCoreAppManifest.js +0 -111
- package/dist/actions/manifest/extractCoreAppManifest.js.map +0 -1
- package/dist/actions/manifest/extractManifest.worker.js +0 -30
- package/dist/actions/manifest/extractManifest.worker.js.map +0 -1
- package/dist/actions/manifest/extractWorkspaceManifest.js +0 -72
- package/dist/actions/manifest/extractWorkspaceManifest.js.map +0 -1
- package/dist/actions/manifest/iconResolver.js +0 -36
- package/dist/actions/manifest/iconResolver.js.map +0 -1
- package/dist/actions/manifest/purifyConfig.js +0 -307
- package/dist/actions/manifest/purifyConfig.js.map +0 -1
- package/dist/actions/manifest/referenceTransformer.js +0 -51
- package/dist/actions/manifest/referenceTransformer.js.map +0 -1
- package/dist/actions/manifest/resolveSchemaIcon.js +0 -43
- package/dist/actions/manifest/resolveSchemaIcon.js.map +0 -1
- package/dist/actions/manifest/sanitizeIcon.js +0 -13
- package/dist/actions/manifest/sanitizeIcon.js.map +0 -1
- package/dist/actions/manifest/schemaTypeHelpers.js +0 -110
- package/dist/actions/manifest/schemaTypeHelpers.js.map +0 -1
- package/dist/actions/manifest/schemaTypeTransformer.js +0 -169
- package/dist/actions/manifest/schemaTypeTransformer.js.map +0 -1
- package/dist/actions/manifest/transformerUtils.js +0 -40
- package/dist/actions/manifest/transformerUtils.js.map +0 -1
- package/dist/actions/manifest/types.js +0 -13
- package/dist/actions/manifest/types.js.map +0 -1
- package/dist/actions/manifest/validationTransformer.js +0 -84
- package/dist/actions/manifest/validationTransformer.js.map +0 -1
- package/dist/actions/manifest/writeManifestFile.js +0 -29
- package/dist/actions/manifest/writeManifestFile.js.map +0 -1
- package/dist/actions/manifest/writeWorkspaceFiles.js +0 -30
- package/dist/actions/manifest/writeWorkspaceFiles.js.map +0 -1
- package/dist/actions/schema/uploadSchemaToLexicon.js +0 -91
- package/dist/actions/schema/uploadSchemaToLexicon.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/prompts/selectMediaLibrary.ts"],"sourcesContent":["import {subdebug} from '@sanity/cli-core'\nimport {select, Separator, spinner} from '@sanity/cli-core/ux'\
|
|
1
|
+
{"version":3,"sources":["../../src/prompts/selectMediaLibrary.ts"],"sourcesContent":["import {subdebug} from '@sanity/cli-core'\nimport {select, Separator, spinner} from '@sanity/cli-core/ux'\n\nimport {getMediaLibraries} from '../services/mediaLibraries.js'\n\nconst debug = subdebug('media:determine-target-library')\n\n/**\n * Fetch a list of available media libraries and present them to the user in a list prompt. The items\n * in the list prompt are grouped by organization id.\n */\nexport async function selectMediaLibrary(projectId: string): Promise<string> {\n debug('Fetching available media libraries')\n const spin = spinner('Fetching available media libraries').start()\n\n try {\n const activeLibraries = await getMediaLibraries(projectId)\n\n const byOrg = Object.groupBy(activeLibraries, (library) => library.organizationId)\n\n spin.succeed()\n\n // Create flat choices array with separators\n const choices: Array<Separator | {name: string; value: string}> = []\n for (const [orgId, libs] of Object.entries(byOrg)) {\n choices.push(\n new Separator(`Organization: ${orgId}`),\n ...(libs ?? []).map((lib) => ({name: lib.id, value: lib.id})),\n )\n }\n\n return select({\n choices,\n message: 'Select media library',\n })\n } catch (error) {\n spin.fail('Failed to fetch media libraries')\n throw error\n }\n}\n"],"names":["subdebug","select","Separator","spinner","getMediaLibraries","debug","selectMediaLibrary","projectId","spin","start","activeLibraries","byOrg","Object","groupBy","library","organizationId","succeed","choices","orgId","libs","entries","push","map","lib","name","id","value","message","error","fail"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,MAAM,EAAEC,SAAS,EAAEC,OAAO,QAAO,sBAAqB;AAE9D,SAAQC,iBAAiB,QAAO,gCAA+B;AAE/D,MAAMC,QAAQL,SAAS;AAEvB;;;CAGC,GACD,OAAO,eAAeM,mBAAmBC,SAAiB;IACxDF,MAAM;IACN,MAAMG,OAAOL,QAAQ,sCAAsCM,KAAK;IAEhE,IAAI;QACF,MAAMC,kBAAkB,MAAMN,kBAAkBG;QAEhD,MAAMI,QAAQC,OAAOC,OAAO,CAACH,iBAAiB,CAACI,UAAYA,QAAQC,cAAc;QAEjFP,KAAKQ,OAAO;QAEZ,4CAA4C;QAC5C,MAAMC,UAA4D,EAAE;QACpE,KAAK,MAAM,CAACC,OAAOC,KAAK,IAAIP,OAAOQ,OAAO,CAACT,OAAQ;YACjDM,QAAQI,IAAI,CACV,IAAInB,UAAU,CAAC,cAAc,EAAEgB,OAAO,MACnC,AAACC,CAAAA,QAAQ,EAAE,AAAD,EAAGG,GAAG,CAAC,CAACC,MAAS,CAAA;oBAACC,MAAMD,IAAIE,EAAE;oBAAEC,OAAOH,IAAIE,EAAE;gBAAA,CAAA;QAE9D;QAEA,OAAOxB,OAAO;YACZgB;YACAU,SAAS;QACX;IACF,EAAE,OAAOC,OAAO;QACdpB,KAAKqB,IAAI,CAAC;QACV,MAAMD;IACR;AACF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getCliToken } from '@sanity/cli-core/config';
|
|
1
2
|
import { subdebug } from '@sanity/cli-core/debug';
|
|
2
3
|
import { createRequester } from '@sanity/cli-core/request';
|
|
3
4
|
import { isStaging } from '@sanity/cli-core/util';
|
|
@@ -6,9 +7,9 @@ const debug = subdebug('new:provision');
|
|
|
6
7
|
/** Provision API version for minting unclaimed projects. */ export const PROVISION_API_VERSION = 'v2026-06-23';
|
|
7
8
|
/**
|
|
8
9
|
* Request tag identifying the caller to the provisioning funnel, using the same `?tag=` convention
|
|
9
|
-
* as every other Sanity API request. `sanity new` is deliberately usable without an account, so
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* as every other Sanity API request. `sanity new` is deliberately usable without an account, so a
|
|
11
|
+
* mint often has no user to attribute — the tag names the tool instead, and is how synthetic
|
|
12
|
+
* callers are kept out of mint-to-claim conversion.
|
|
12
13
|
*/ export const MINT_REQUEST_TAG = 'sanity.cli';
|
|
13
14
|
/**
|
|
14
15
|
* Overrides {@link MINT_REQUEST_TAG}. Internal plumbing for the scheduled smoke test, which mints
|
|
@@ -76,6 +77,9 @@ function parseProvisionResponse(body) {
|
|
|
76
77
|
}
|
|
77
78
|
/**
|
|
78
79
|
* Mint an unclaimed Sanity project through the public provision endpoint.
|
|
80
|
+
*
|
|
81
|
+
* Works logged out. Credentials, when there are any, are sent only so the mint can be attributed
|
|
82
|
+
* and are dropped on rejection, so being logged in changes reporting and nothing else.
|
|
79
83
|
*/ export async function mintUnclaimedProject(options) {
|
|
80
84
|
const displayName = options.displayName.trim();
|
|
81
85
|
if (!displayName || displayName.length > 80) {
|
|
@@ -84,17 +88,26 @@ function parseProvisionResponse(body) {
|
|
|
84
88
|
const url = new URL(`${PROVISION_API_VERSION}/provision`, getProvisionApiBase());
|
|
85
89
|
url.searchParams.set('tag', getRequestTag());
|
|
86
90
|
debug('minting unclaimed project at %s', url.toString());
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
const mint = (token)=>request({
|
|
92
|
+
body: JSON.stringify({
|
|
93
|
+
displayName,
|
|
94
|
+
resourceType: 'project'
|
|
95
|
+
}),
|
|
96
|
+
headers: {
|
|
97
|
+
'Content-Type': 'application/json',
|
|
98
|
+
...token ? {
|
|
99
|
+
Authorization: `Bearer ${token}`
|
|
100
|
+
} : {}
|
|
101
|
+
},
|
|
102
|
+
method: 'POST',
|
|
103
|
+
url: url.toString()
|
|
104
|
+
});
|
|
105
|
+
const token = await getCliToken();
|
|
106
|
+
let response = await mint(token);
|
|
107
|
+
if (token && (response.status === 401 || response.status === 403)) {
|
|
108
|
+
debug('stored credentials rejected (HTTP %d), minting anonymously', response.status);
|
|
109
|
+
response = await mint();
|
|
110
|
+
}
|
|
98
111
|
if (response.status === 404) {
|
|
99
112
|
throw new Error('Creating projects without an account is currently unavailable. Try again later, or run `sanity login` and `sanity init`.');
|
|
100
113
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/mintProject.ts"],"sourcesContent":["import {subdebug} from '@sanity/cli-core/debug'\nimport {createRequester} from '@sanity/cli-core/request'\nimport {isStaging} from '@sanity/cli-core/util'\n\nimport {\n TERMS_OF_SERVICE_FALLBACK_NOTICE,\n TERMS_OF_SERVICE_FALLBACK_URL,\n} from '../util/mintProjectConstants.js'\n\nconst debug = subdebug('new:provision')\n\n/** Provision API version for minting unclaimed projects. */\nexport const PROVISION_API_VERSION = 'v2026-06-23'\n\n/**\n * Request tag identifying the caller to the provisioning funnel, using the same `?tag=` convention\n * as every other Sanity API request. `sanity new` is deliberately usable without an account, so\n * most mints have no user to attribute — this is what tells reporting who made them, and is how\n * synthetic callers are kept out of mint-to-claim conversion.\n */\nexport const MINT_REQUEST_TAG = 'sanity.cli'\n\n/**\n * Overrides {@link MINT_REQUEST_TAG}. Internal plumbing for the scheduled smoke test, which mints\n * against production several times an hour and never claims; it sets `sanity.cli.smoketest` so\n * those mints can be excluded from reporting.\n */\nconst MINT_TAG_ENV_VAR = 'SANITY_CLI_MINT_TAG'\n\n/** Mirrors `@sanity/client`'s `requestTag` rule, which is what the API accepts. */\nconst TAG_PATTERN = /^[a-z0-9._-]{1,75}$/i\n\nfunction getRequestTag(): string {\n const override = process.env[MINT_TAG_ENV_VAR]\n if (!override) return MINT_REQUEST_TAG\n if (!TAG_PATTERN.test(override)) {\n // A malformed override would be dropped by the API anyway; fall back rather than mint\n // untagged, so the request is still attributable.\n debug('ignoring malformed %s value %j', MINT_TAG_ENV_VAR, override)\n return MINT_REQUEST_TAG\n }\n return override\n}\n\nconst request = createRequester({httpErrors: false})\n\nexport interface MintedProject {\n apiHost: string\n claimApiUrl: string\n claimToken: string\n claimUrl: string\n datasetName: string\n expiresAt: string\n resourceId: string\n /** Terms of Service accepted by using the project. Falls back to the bundled constants. */\n termsNotice: string\n termsUrl: string\n token: string\n}\n\nfunction getProvisionApiBase(): string {\n const override = process.env.SANITY_API_HOST\n if (override) return override.replace(/\\/$/u, '')\n return isStaging() ? 'https://api.sanity.work' : 'https://api.sanity.io'\n}\n\nfunction parseJsonBody(body: unknown): unknown {\n if (typeof body !== 'string') return body\n\n try {\n return JSON.parse(body)\n } catch {\n return undefined\n }\n}\n\nfunction getString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction parseProvisionResponse(body: unknown): MintedProject {\n const data = parseJsonBody(body)\n const response =\n data && typeof data === 'object' && !Array.isArray(data)\n ? (data as Record<string, unknown>)\n : {}\n const links =\n response.links && typeof response.links === 'object' && !Array.isArray(response.links)\n ? (response.links as Record<string, unknown>)\n : {}\n const terms =\n response.terms && typeof response.terms === 'object' && !Array.isArray(response.terms)\n ? (response.terms as Record<string, unknown>)\n : {}\n\n const minted = {\n apiHost: getString(response.apiHost),\n claimApiUrl: getString(links.claimApiUrl),\n claimToken: getString(response.claimToken),\n claimUrl: getString(links.claimUrl),\n datasetName: getString(response.datasetName),\n expiresAt: getString(response.expiresAt),\n resourceId: getString(response.resourceId),\n token: getString(response.token),\n }\n const missing = Object.entries(minted)\n .filter(([, value]) => value === undefined)\n .map(([key]) => key)\n\n if (response.resourceType !== 'project') {\n missing.push('resourceType')\n }\n if (missing.length > 0) {\n throw new Error(`Project creation response is missing or invalid: ${missing.join(', ')}`)\n }\n\n return {\n ...(minted as Omit<MintedProject, 'termsNotice' | 'termsUrl'>),\n termsNotice: getString(terms.notice) ?? TERMS_OF_SERVICE_FALLBACK_NOTICE,\n termsUrl: getString(terms.url) ?? TERMS_OF_SERVICE_FALLBACK_URL,\n }\n}\n\n/**\n * Mint an unclaimed Sanity project through the public provision endpoint.\n */\nexport async function mintUnclaimedProject(options: {displayName: string}): Promise<MintedProject> {\n const displayName = options.displayName.trim()\n if (!displayName || displayName.length > 80) {\n throw new Error('Project name must be 1-80 characters.')\n }\n\n const url = new URL(`${PROVISION_API_VERSION}/provision`, getProvisionApiBase())\n url.searchParams.set('tag', getRequestTag())\n debug('minting unclaimed project at %s', url.toString())\n\n const response = await request({\n body: JSON.stringify({displayName, resourceType: 'project'}),\n headers: {'Content-Type': 'application/json'},\n method: 'POST',\n url: url.toString(),\n })\n\n if (response.status === 404) {\n throw new Error(\n 'Creating projects without an account is currently unavailable. Try again later, or run `sanity login` and `sanity init`.',\n )\n }\n if (response.status === 429) {\n throw new Error('Project creation rate limit reached for this machine. Try again later.')\n }\n if (response.status < 200 || response.status >= 300) {\n throw new Error(`Project creation failed (HTTP ${response.status}). Try again later.`)\n }\n\n return parseProvisionResponse(response.text())\n}\n"],"names":["subdebug","createRequester","isStaging","TERMS_OF_SERVICE_FALLBACK_NOTICE","TERMS_OF_SERVICE_FALLBACK_URL","debug","PROVISION_API_VERSION","MINT_REQUEST_TAG","MINT_TAG_ENV_VAR","TAG_PATTERN","getRequestTag","override","process","env","test","request","httpErrors","getProvisionApiBase","SANITY_API_HOST","replace","parseJsonBody","body","JSON","parse","undefined","getString","value","length","parseProvisionResponse","data","response","Array","isArray","links","terms","minted","apiHost","claimApiUrl","claimToken","claimUrl","datasetName","expiresAt","resourceId","token","missing","Object","entries","filter","map","key","resourceType","push","Error","join","termsNotice","notice","termsUrl","url","mintUnclaimedProject","options","displayName","trim","URL","searchParams","set","toString","stringify","headers","method","status","text"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/services/mintProject.ts"],"sourcesContent":["import {getCliToken} from '@sanity/cli-core/config'\nimport {subdebug} from '@sanity/cli-core/debug'\nimport {createRequester} from '@sanity/cli-core/request'\nimport {isStaging} from '@sanity/cli-core/util'\n\nimport {\n TERMS_OF_SERVICE_FALLBACK_NOTICE,\n TERMS_OF_SERVICE_FALLBACK_URL,\n} from '../util/mintProjectConstants.js'\n\nconst debug = subdebug('new:provision')\n\n/** Provision API version for minting unclaimed projects. */\nexport const PROVISION_API_VERSION = 'v2026-06-23'\n\n/**\n * Request tag identifying the caller to the provisioning funnel, using the same `?tag=` convention\n * as every other Sanity API request. `sanity new` is deliberately usable without an account, so a\n * mint often has no user to attribute — the tag names the tool instead, and is how synthetic\n * callers are kept out of mint-to-claim conversion.\n */\nexport const MINT_REQUEST_TAG = 'sanity.cli'\n\n/**\n * Overrides {@link MINT_REQUEST_TAG}. Internal plumbing for the scheduled smoke test, which mints\n * against production several times an hour and never claims; it sets `sanity.cli.smoketest` so\n * those mints can be excluded from reporting.\n */\nconst MINT_TAG_ENV_VAR = 'SANITY_CLI_MINT_TAG'\n\n/** Mirrors `@sanity/client`'s `requestTag` rule, which is what the API accepts. */\nconst TAG_PATTERN = /^[a-z0-9._-]{1,75}$/i\n\nfunction getRequestTag(): string {\n const override = process.env[MINT_TAG_ENV_VAR]\n if (!override) return MINT_REQUEST_TAG\n if (!TAG_PATTERN.test(override)) {\n // A malformed override would be dropped by the API anyway; fall back rather than mint\n // untagged, so the request is still attributable.\n debug('ignoring malformed %s value %j', MINT_TAG_ENV_VAR, override)\n return MINT_REQUEST_TAG\n }\n return override\n}\n\nconst request = createRequester({httpErrors: false})\n\nexport interface MintedProject {\n apiHost: string\n claimApiUrl: string\n claimToken: string\n claimUrl: string\n datasetName: string\n expiresAt: string\n resourceId: string\n /** Terms of Service accepted by using the project. Falls back to the bundled constants. */\n termsNotice: string\n termsUrl: string\n token: string\n}\n\nfunction getProvisionApiBase(): string {\n const override = process.env.SANITY_API_HOST\n if (override) return override.replace(/\\/$/u, '')\n return isStaging() ? 'https://api.sanity.work' : 'https://api.sanity.io'\n}\n\nfunction parseJsonBody(body: unknown): unknown {\n if (typeof body !== 'string') return body\n\n try {\n return JSON.parse(body)\n } catch {\n return undefined\n }\n}\n\nfunction getString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction parseProvisionResponse(body: unknown): MintedProject {\n const data = parseJsonBody(body)\n const response =\n data && typeof data === 'object' && !Array.isArray(data)\n ? (data as Record<string, unknown>)\n : {}\n const links =\n response.links && typeof response.links === 'object' && !Array.isArray(response.links)\n ? (response.links as Record<string, unknown>)\n : {}\n const terms =\n response.terms && typeof response.terms === 'object' && !Array.isArray(response.terms)\n ? (response.terms as Record<string, unknown>)\n : {}\n\n const minted = {\n apiHost: getString(response.apiHost),\n claimApiUrl: getString(links.claimApiUrl),\n claimToken: getString(response.claimToken),\n claimUrl: getString(links.claimUrl),\n datasetName: getString(response.datasetName),\n expiresAt: getString(response.expiresAt),\n resourceId: getString(response.resourceId),\n token: getString(response.token),\n }\n const missing = Object.entries(minted)\n .filter(([, value]) => value === undefined)\n .map(([key]) => key)\n\n if (response.resourceType !== 'project') {\n missing.push('resourceType')\n }\n if (missing.length > 0) {\n throw new Error(`Project creation response is missing or invalid: ${missing.join(', ')}`)\n }\n\n return {\n ...(minted as Omit<MintedProject, 'termsNotice' | 'termsUrl'>),\n termsNotice: getString(terms.notice) ?? TERMS_OF_SERVICE_FALLBACK_NOTICE,\n termsUrl: getString(terms.url) ?? TERMS_OF_SERVICE_FALLBACK_URL,\n }\n}\n\n/**\n * Mint an unclaimed Sanity project through the public provision endpoint.\n *\n * Works logged out. Credentials, when there are any, are sent only so the mint can be attributed\n * and are dropped on rejection, so being logged in changes reporting and nothing else.\n */\nexport async function mintUnclaimedProject(options: {displayName: string}): Promise<MintedProject> {\n const displayName = options.displayName.trim()\n if (!displayName || displayName.length > 80) {\n throw new Error('Project name must be 1-80 characters.')\n }\n\n const url = new URL(`${PROVISION_API_VERSION}/provision`, getProvisionApiBase())\n url.searchParams.set('tag', getRequestTag())\n debug('minting unclaimed project at %s', url.toString())\n\n const mint = (token?: string) =>\n request({\n body: JSON.stringify({displayName, resourceType: 'project'}),\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? {Authorization: `Bearer ${token}`} : {}),\n },\n method: 'POST',\n url: url.toString(),\n })\n\n const token = await getCliToken()\n let response = await mint(token)\n\n if (token && (response.status === 401 || response.status === 403)) {\n debug('stored credentials rejected (HTTP %d), minting anonymously', response.status)\n response = await mint()\n }\n\n if (response.status === 404) {\n throw new Error(\n 'Creating projects without an account is currently unavailable. Try again later, or run `sanity login` and `sanity init`.',\n )\n }\n if (response.status === 429) {\n throw new Error('Project creation rate limit reached for this machine. Try again later.')\n }\n if (response.status < 200 || response.status >= 300) {\n throw new Error(`Project creation failed (HTTP ${response.status}). Try again later.`)\n }\n\n return parseProvisionResponse(response.text())\n}\n"],"names":["getCliToken","subdebug","createRequester","isStaging","TERMS_OF_SERVICE_FALLBACK_NOTICE","TERMS_OF_SERVICE_FALLBACK_URL","debug","PROVISION_API_VERSION","MINT_REQUEST_TAG","MINT_TAG_ENV_VAR","TAG_PATTERN","getRequestTag","override","process","env","test","request","httpErrors","getProvisionApiBase","SANITY_API_HOST","replace","parseJsonBody","body","JSON","parse","undefined","getString","value","length","parseProvisionResponse","data","response","Array","isArray","links","terms","minted","apiHost","claimApiUrl","claimToken","claimUrl","datasetName","expiresAt","resourceId","token","missing","Object","entries","filter","map","key","resourceType","push","Error","join","termsNotice","notice","termsUrl","url","mintUnclaimedProject","options","displayName","trim","URL","searchParams","set","toString","mint","stringify","headers","Authorization","method","status","text"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/schemas.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/services/schemas.ts"],"sourcesContent":["import {type StoredWorkspaceSchema} from '@sanity/cli-build/_internal/manifest'\nimport {getGlobalCliClient} from '@sanity/cli-core'\n\nexport const SCHEMA_API_VERSION = 'v2025-03-01'\n\nasync function getSchemaClient() {\n return await getGlobalCliClient({\n apiVersion: SCHEMA_API_VERSION,\n requireUser: true,\n })\n}\n\nexport async function getSchemas(dataset: string, projectId: string, id?: string) {\n const client = await getSchemaClient()\n\n return client.request<StoredWorkspaceSchema[]>({\n method: 'GET',\n url: `/projects/${projectId}/datasets/${dataset}/schemas${id ? `/${id}` : ''}`,\n })\n}\n\nexport async function deleteSchema(dataset: string, projectId: string, id: string) {\n const exists = await getSchemas(dataset, projectId, id)\n\n if (exists?.length === 0) {\n return {\n deleted: false,\n }\n }\n\n const client = await getSchemaClient()\n\n return client.request({\n method: 'DELETE',\n url: `/projects/${projectId}/datasets/${dataset}/schemas/${id}`,\n })\n}\n\nexport async function updateSchemas<T>(dataset: string, projectId: string, schemas: T) {\n const client = await getSchemaClient()\n\n return client.request({\n body: {\n schemas,\n },\n method: 'PUT',\n url: `/projects/${projectId}/datasets/${dataset}/schemas`,\n })\n}\n"],"names":["getGlobalCliClient","SCHEMA_API_VERSION","getSchemaClient","apiVersion","requireUser","getSchemas","dataset","projectId","id","client","request","method","url","deleteSchema","exists","length","deleted","updateSchemas","schemas","body"],"mappings":"AACA,SAAQA,kBAAkB,QAAO,mBAAkB;AAEnD,OAAO,MAAMC,qBAAqB,cAAa;AAE/C,eAAeC;IACb,OAAO,MAAMF,mBAAmB;QAC9BG,YAAYF;QACZG,aAAa;IACf;AACF;AAEA,OAAO,eAAeC,WAAWC,OAAe,EAAEC,SAAiB,EAAEC,EAAW;IAC9E,MAAMC,SAAS,MAAMP;IAErB,OAAOO,OAAOC,OAAO,CAA0B;QAC7CC,QAAQ;QACRC,KAAK,CAAC,UAAU,EAAEL,UAAU,UAAU,EAAED,QAAQ,QAAQ,EAAEE,KAAK,CAAC,CAAC,EAAEA,IAAI,GAAG,IAAI;IAChF;AACF;AAEA,OAAO,eAAeK,aAAaP,OAAe,EAAEC,SAAiB,EAAEC,EAAU;IAC/E,MAAMM,SAAS,MAAMT,WAAWC,SAASC,WAAWC;IAEpD,IAAIM,QAAQC,WAAW,GAAG;QACxB,OAAO;YACLC,SAAS;QACX;IACF;IAEA,MAAMP,SAAS,MAAMP;IAErB,OAAOO,OAAOC,OAAO,CAAC;QACpBC,QAAQ;QACRC,KAAK,CAAC,UAAU,EAAEL,UAAU,UAAU,EAAED,QAAQ,SAAS,EAAEE,IAAI;IACjE;AACF;AAEA,OAAO,eAAeS,cAAiBX,OAAe,EAAEC,SAAiB,EAAEW,OAAU;IACnF,MAAMT,SAAS,MAAMP;IAErB,OAAOO,OAAOC,OAAO,CAAC;QACpBS,MAAM;YACJD;QACF;QACAP,QAAQ;QACRC,KAAK,CAAC,UAAU,EAAEL,UAAU,UAAU,EAAED,QAAQ,QAAQ,CAAC;IAC3D;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/userApplications.ts"],"sourcesContent":["import {PassThrough} from 'node:stream'\nimport {type Gzip} from 'node:zlib'\n\nimport {type AppVisibility, debug, getGlobalCliClient} from '@sanity/cli-core'\nimport FormData from 'form-data'\nimport {type StudioManifest} from 'sanity'\n\nimport {type CoreAppManifest} from '../actions/manifest/types.js'\n\nexport const USER_APPLICATIONS_API_VERSION = 'v2024-08-01'\n\ninterface ActiveDeployment {\n createdAt: string\n deployedAt: string\n deployedBy: string\n isActiveDeployment: boolean\n isAutoUpdating: boolean | null\n size: string | null\n updatedAt: string\n version: string\n}\n\nexport interface UserApplication {\n appHost: string\n createdAt: string\n id: string\n organizationId: string | null\n projectId: string | null\n title: string | null\n type: 'coreApp' | 'studio'\n updatedAt: string\n urlType: 'external' | 'internal'\n\n activeDeployment?: ActiveDeployment | null\n /** Dashboard visibility. Defaults to `default` server-side when unset. */\n dashboardStatus?: AppVisibility\n}\n\n/** A core app always belongs to an organization. */\nexport interface UserApplicationResolved extends UserApplication {\n organizationId: string\n type: 'coreApp'\n}\n\ntype GetUserApplicationOptions =\n | {appHost?: never; appId: string; isSdkApp: true; projectId?: never}\n | {appHost?: string; appId?: string; isSdkApp: false; projectId: string}\n\nexport async function getUserApplication(options: {\n appHost?: never\n appId: string\n isSdkApp: true\n projectId?: never\n}): Promise<UserApplicationResolved | null>\nexport async function getUserApplication(options: {\n appHost?: string\n appId?: string\n isSdkApp: false\n projectId: string\n}): Promise<UserApplication | null>\nexport async function getUserApplication({\n appHost,\n appId,\n isSdkApp,\n projectId,\n}: GetUserApplicationOptions): Promise<UserApplication | null> {\n let query: Record<string, string | string[]> | undefined\n let url: string\n\n // set the url\n if (isSdkApp) {\n url = appId ? `/user-applications/${appId}` : '/user-applications'\n } else {\n url = appId\n ? `/projects/${projectId}/user-applications/${appId}`\n : `/projects/${projectId}/user-applications`\n }\n\n // set the query\n if (isSdkApp) {\n query = {appType: 'coreApp'}\n } else if (!appId) {\n // In practice, this function isn't called if we don't have at least one of appHost or appId,\n // so the default case won't be called. But leaving this ternary in for now (from old CLI code) just in case.\n query = appHost ? {appHost, appType: 'studio'} : {default: 'true'}\n }\n\n const client = await getGlobalCliClient({\n apiVersion: USER_APPLICATIONS_API_VERSION,\n requireUser: true,\n })\n\n try {\n const options = query ? {query, url} : {url}\n return await client.request(options)\n } catch (err) {\n if (err?.statusCode === 404) {\n return null\n }\n\n debug('Error getting user application', err)\n throw err\n }\n}\n\ninterface DeleteUserApplicationOptions {\n applicationId: string\n appType: 'coreApp' | 'studio'\n}\n\nexport async function deleteUserApplication({\n applicationId,\n appType,\n}: DeleteUserApplicationOptions): Promise<void> {\n const client = await getGlobalCliClient({\n apiVersion: USER_APPLICATIONS_API_VERSION,\n requireUser: true,\n })\n\n await client.request({\n method: 'DELETE',\n query: {appType},\n url: `/user-applications/${applicationId}`,\n })\n}\n\ninterface UpdateUserApplicationBody {\n dashboardStatus?: AppVisibility\n title?: string\n}\n\ninterface UpdateUserApplicationOptions {\n applicationId: string\n // Updating studio properties requires further UX thought\n // (because of workspaces et al.)\n appType: 'coreApp'\n body: UpdateUserApplicationBody\n}\n\nexport async function updateUserApplication({\n applicationId,\n appType,\n body,\n}: UpdateUserApplicationOptions): Promise<UserApplicationResolved> {\n const client = await getGlobalCliClient({\n apiVersion: USER_APPLICATIONS_API_VERSION,\n requireUser: true,\n })\n\n return client.request({\n body,\n method: 'PATCH',\n query: {appType},\n url: `/user-applications/${applicationId}`,\n })\n}\n\nexport async function getUserApplications(options: {\n appType: 'studio'\n projectId: string\n}): Promise<UserApplication[]>\nexport async function getUserApplications(options: {\n appType: 'coreApp'\n organizationId: string\n}): Promise<UserApplicationResolved[]>\nexport async function getUserApplications(\n options:\n | {\n appType: 'coreApp'\n organizationId?: string\n }\n | {\n appType: 'studio'\n projectId?: string\n },\n): Promise<UserApplication[] | null> {\n const {appType} = options\n const client = await getGlobalCliClient({\n apiVersion: USER_APPLICATIONS_API_VERSION,\n requireUser: true,\n })\n\n if (appType === 'studio') {\n const {projectId} = options as {appType: 'studio'; projectId?: string}\n return await client.request({\n query: {appType: 'studio'},\n url: `/projects/${projectId}/user-applications`,\n })\n }\n\n const {organizationId} = options as {appType: 'coreApp'; organizationId?: string}\n\n try {\n return await client.request({\n query: {appType: 'coreApp', organizationId: organizationId!},\n url: `/user-applications`,\n })\n } catch (error) {\n // User doesn't have permission to view applications for the org,\n // or the organization ID doesn’t exist\n if (error?.statusCode === 403) {\n throw error\n }\n\n debug('Error finding user applications', error)\n return null\n }\n}\n\nexport async function createUserApplication(options: {\n appType: 'coreApp'\n body: Pick<UserApplication, 'appHost' | 'type' | 'urlType'> & {\n dashboardStatus?: AppVisibility\n title?: string\n }\n organizationId?: string\n}): Promise<UserApplicationResolved>\nexport async function createUserApplication(options: {\n appType: 'studio'\n body: Pick<UserApplication, 'appHost' | 'type' | 'urlType'> & {\n dashboardStatus?: AppVisibility\n title?: string\n }\n projectId: string\n}): Promise<UserApplication>\nexport async function createUserApplication(options: {\n appType: 'coreApp' | 'studio'\n body: Pick<UserApplication, 'appHost' | 'type' | 'urlType'> & {\n dashboardStatus?: AppVisibility\n title?: string\n }\n organizationId?: string\n projectId?: string\n}): Promise<UserApplication> {\n const {appType, body} = options\n\n const client = await getGlobalCliClient({\n apiVersion: USER_APPLICATIONS_API_VERSION,\n requireUser: true,\n })\n\n let url\n let query\n\n // If we have an organizationId, we're creating a core app\n if (appType === 'coreApp') {\n const {organizationId} = options as {appType: 'coreApp'; organizationId?: string}\n url = '/user-applications'\n query = {appType: 'coreApp', organizationId: organizationId!}\n } else {\n const {projectId} = options as {appType: 'studio'; projectId?: string}\n url = `/projects/${projectId}/user-applications`\n query = {appType: 'studio'}\n }\n\n return client.request({body, method: 'POST', query, url})\n}\n\ninterface CreateDeploymentOptions {\n applicationId: string\n isAutoUpdating: boolean\n version: string\n\n isApp?: boolean\n\n manifest?: CoreAppManifest | StudioManifest | null\n\n projectId?: string\n\n tarball?: Gzip\n}\n\nexport async function createDeployment({\n applicationId,\n isApp,\n isAutoUpdating,\n manifest,\n projectId,\n tarball,\n version,\n}: CreateDeploymentOptions): Promise<{location: string}> {\n const client = await getGlobalCliClient({\n apiVersion: USER_APPLICATIONS_API_VERSION,\n requireUser: true,\n })\n\n const formData = new FormData()\n formData.append('isAutoUpdating', isAutoUpdating.toString())\n formData.append('version', version)\n if (manifest) {\n formData.append('manifest', JSON.stringify(manifest))\n }\n\n if (tarball) {\n formData.append('tarball', tarball, {contentType: 'application/gzip', filename: 'app.tar.gz'})\n }\n\n let url\n let query\n\n if (isApp) {\n url = `/user-applications/${applicationId}/deployments`\n query = {appType: 'coreApp'}\n } else {\n url = `/projects/${projectId}/user-applications/${applicationId}/deployments`\n query = {appType: 'studio'}\n }\n\n return client.request({\n body: formData.pipe(new PassThrough()),\n headers: formData.getHeaders(),\n method: 'POST',\n query,\n url,\n })\n}\n"],"names":["PassThrough","debug","getGlobalCliClient","FormData","USER_APPLICATIONS_API_VERSION","getUserApplication","appHost","appId","isSdkApp","projectId","query","url","appType","default","client","apiVersion","requireUser","options","request","err","statusCode","deleteUserApplication","applicationId","method","updateUserApplication","body","getUserApplications","organizationId","error","createUserApplication","createDeployment","isApp","isAutoUpdating","manifest","tarball","version","formData","append","toString","JSON","stringify","contentType","filename","pipe","headers","getHeaders"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/services/userApplications.ts"],"sourcesContent":["import {PassThrough} from 'node:stream'\nimport {type Gzip} from 'node:zlib'\n\nimport {type CoreAppManifest} from '@sanity/cli-build/_internal/manifest'\nimport {type AppVisibility, debug, getGlobalCliClient} from '@sanity/cli-core'\nimport FormData from 'form-data'\nimport {type StudioManifest} from 'sanity'\n\nexport const USER_APPLICATIONS_API_VERSION = 'v2024-08-01'\n\ninterface ActiveDeployment {\n createdAt: string\n deployedAt: string\n deployedBy: string\n isActiveDeployment: boolean\n isAutoUpdating: boolean | null\n size: string | null\n updatedAt: string\n version: string\n}\n\nexport interface UserApplication {\n appHost: string\n createdAt: string\n id: string\n organizationId: string | null\n projectId: string | null\n title: string | null\n type: 'coreApp' | 'studio'\n updatedAt: string\n urlType: 'external' | 'internal'\n\n activeDeployment?: ActiveDeployment | null\n /** Dashboard visibility. Defaults to `default` server-side when unset. */\n dashboardStatus?: AppVisibility\n}\n\n/** A core app always belongs to an organization. */\nexport interface UserApplicationResolved extends UserApplication {\n organizationId: string\n type: 'coreApp'\n}\n\ntype GetUserApplicationOptions =\n | {appHost?: never; appId: string; isSdkApp: true; projectId?: never}\n | {appHost?: string; appId?: string; isSdkApp: false; projectId: string}\n\nexport async function getUserApplication(options: {\n appHost?: never\n appId: string\n isSdkApp: true\n projectId?: never\n}): Promise<UserApplicationResolved | null>\nexport async function getUserApplication(options: {\n appHost?: string\n appId?: string\n isSdkApp: false\n projectId: string\n}): Promise<UserApplication | null>\nexport async function getUserApplication({\n appHost,\n appId,\n isSdkApp,\n projectId,\n}: GetUserApplicationOptions): Promise<UserApplication | null> {\n let query: Record<string, string | string[]> | undefined\n let url: string\n\n // set the url\n if (isSdkApp) {\n url = appId ? `/user-applications/${appId}` : '/user-applications'\n } else {\n url = appId\n ? `/projects/${projectId}/user-applications/${appId}`\n : `/projects/${projectId}/user-applications`\n }\n\n // set the query\n if (isSdkApp) {\n query = {appType: 'coreApp'}\n } else if (!appId) {\n // In practice, this function isn't called if we don't have at least one of appHost or appId,\n // so the default case won't be called. But leaving this ternary in for now (from old CLI code) just in case.\n query = appHost ? {appHost, appType: 'studio'} : {default: 'true'}\n }\n\n const client = await getGlobalCliClient({\n apiVersion: USER_APPLICATIONS_API_VERSION,\n requireUser: true,\n })\n\n try {\n const options = query ? {query, url} : {url}\n return await client.request(options)\n } catch (err) {\n if (err?.statusCode === 404) {\n return null\n }\n\n debug('Error getting user application', err)\n throw err\n }\n}\n\ninterface DeleteUserApplicationOptions {\n applicationId: string\n appType: 'coreApp' | 'studio'\n}\n\nexport async function deleteUserApplication({\n applicationId,\n appType,\n}: DeleteUserApplicationOptions): Promise<void> {\n const client = await getGlobalCliClient({\n apiVersion: USER_APPLICATIONS_API_VERSION,\n requireUser: true,\n })\n\n await client.request({\n method: 'DELETE',\n query: {appType},\n url: `/user-applications/${applicationId}`,\n })\n}\n\ninterface UpdateUserApplicationBody {\n dashboardStatus?: AppVisibility\n title?: string\n}\n\ninterface UpdateUserApplicationOptions {\n applicationId: string\n // Updating studio properties requires further UX thought\n // (because of workspaces et al.)\n appType: 'coreApp'\n body: UpdateUserApplicationBody\n}\n\nexport async function updateUserApplication({\n applicationId,\n appType,\n body,\n}: UpdateUserApplicationOptions): Promise<UserApplicationResolved> {\n const client = await getGlobalCliClient({\n apiVersion: USER_APPLICATIONS_API_VERSION,\n requireUser: true,\n })\n\n return client.request({\n body,\n method: 'PATCH',\n query: {appType},\n url: `/user-applications/${applicationId}`,\n })\n}\n\nexport async function getUserApplications(options: {\n appType: 'studio'\n projectId: string\n}): Promise<UserApplication[]>\nexport async function getUserApplications(options: {\n appType: 'coreApp'\n organizationId: string\n}): Promise<UserApplicationResolved[]>\nexport async function getUserApplications(\n options:\n | {\n appType: 'coreApp'\n organizationId?: string\n }\n | {\n appType: 'studio'\n projectId?: string\n },\n): Promise<UserApplication[] | null> {\n const {appType} = options\n const client = await getGlobalCliClient({\n apiVersion: USER_APPLICATIONS_API_VERSION,\n requireUser: true,\n })\n\n if (appType === 'studio') {\n const {projectId} = options as {appType: 'studio'; projectId?: string}\n return await client.request({\n query: {appType: 'studio'},\n url: `/projects/${projectId}/user-applications`,\n })\n }\n\n const {organizationId} = options as {appType: 'coreApp'; organizationId?: string}\n\n try {\n return await client.request({\n query: {appType: 'coreApp', organizationId: organizationId!},\n url: `/user-applications`,\n })\n } catch (error) {\n // User doesn't have permission to view applications for the org,\n // or the organization ID doesn’t exist\n if (error?.statusCode === 403) {\n throw error\n }\n\n debug('Error finding user applications', error)\n return null\n }\n}\n\nexport async function createUserApplication(options: {\n appType: 'coreApp'\n body: Pick<UserApplication, 'appHost' | 'type' | 'urlType'> & {\n dashboardStatus?: AppVisibility\n title?: string\n }\n organizationId?: string\n}): Promise<UserApplicationResolved>\nexport async function createUserApplication(options: {\n appType: 'studio'\n body: Pick<UserApplication, 'appHost' | 'type' | 'urlType'> & {\n dashboardStatus?: AppVisibility\n title?: string\n }\n projectId: string\n}): Promise<UserApplication>\nexport async function createUserApplication(options: {\n appType: 'coreApp' | 'studio'\n body: Pick<UserApplication, 'appHost' | 'type' | 'urlType'> & {\n dashboardStatus?: AppVisibility\n title?: string\n }\n organizationId?: string\n projectId?: string\n}): Promise<UserApplication> {\n const {appType, body} = options\n\n const client = await getGlobalCliClient({\n apiVersion: USER_APPLICATIONS_API_VERSION,\n requireUser: true,\n })\n\n let url\n let query\n\n // If we have an organizationId, we're creating a core app\n if (appType === 'coreApp') {\n const {organizationId} = options as {appType: 'coreApp'; organizationId?: string}\n url = '/user-applications'\n query = {appType: 'coreApp', organizationId: organizationId!}\n } else {\n const {projectId} = options as {appType: 'studio'; projectId?: string}\n url = `/projects/${projectId}/user-applications`\n query = {appType: 'studio'}\n }\n\n return client.request({body, method: 'POST', query, url})\n}\n\ninterface CreateDeploymentOptions {\n applicationId: string\n isAutoUpdating: boolean\n version: string\n\n isApp?: boolean\n\n manifest?: CoreAppManifest | StudioManifest | null\n\n projectId?: string\n\n tarball?: Gzip\n}\n\nexport async function createDeployment({\n applicationId,\n isApp,\n isAutoUpdating,\n manifest,\n projectId,\n tarball,\n version,\n}: CreateDeploymentOptions): Promise<{location: string}> {\n const client = await getGlobalCliClient({\n apiVersion: USER_APPLICATIONS_API_VERSION,\n requireUser: true,\n })\n\n const formData = new FormData()\n formData.append('isAutoUpdating', isAutoUpdating.toString())\n formData.append('version', version)\n if (manifest) {\n formData.append('manifest', JSON.stringify(manifest))\n }\n\n if (tarball) {\n formData.append('tarball', tarball, {contentType: 'application/gzip', filename: 'app.tar.gz'})\n }\n\n let url\n let query\n\n if (isApp) {\n url = `/user-applications/${applicationId}/deployments`\n query = {appType: 'coreApp'}\n } else {\n url = `/projects/${projectId}/user-applications/${applicationId}/deployments`\n query = {appType: 'studio'}\n }\n\n return client.request({\n body: formData.pipe(new PassThrough()),\n headers: formData.getHeaders(),\n method: 'POST',\n query,\n url,\n })\n}\n"],"names":["PassThrough","debug","getGlobalCliClient","FormData","USER_APPLICATIONS_API_VERSION","getUserApplication","appHost","appId","isSdkApp","projectId","query","url","appType","default","client","apiVersion","requireUser","options","request","err","statusCode","deleteUserApplication","applicationId","method","updateUserApplication","body","getUserApplications","organizationId","error","createUserApplication","createDeployment","isApp","isAutoUpdating","manifest","tarball","version","formData","append","toString","JSON","stringify","contentType","filename","pipe","headers","getHeaders"],"mappings":"AAAA,SAAQA,WAAW,QAAO,cAAa;AAIvC,SAA4BC,KAAK,EAAEC,kBAAkB,QAAO,mBAAkB;AAC9E,OAAOC,cAAc,YAAW;AAGhC,OAAO,MAAMC,gCAAgC,cAAa;AAmD1D,OAAO,eAAeC,mBAAmB,EACvCC,OAAO,EACPC,KAAK,EACLC,QAAQ,EACRC,SAAS,EACiB;IAC1B,IAAIC;IACJ,IAAIC;IAEJ,cAAc;IACd,IAAIH,UAAU;QACZG,MAAMJ,QAAQ,CAAC,mBAAmB,EAAEA,OAAO,GAAG;IAChD,OAAO;QACLI,MAAMJ,QACF,CAAC,UAAU,EAAEE,UAAU,mBAAmB,EAAEF,OAAO,GACnD,CAAC,UAAU,EAAEE,UAAU,kBAAkB,CAAC;IAChD;IAEA,gBAAgB;IAChB,IAAID,UAAU;QACZE,QAAQ;YAACE,SAAS;QAAS;IAC7B,OAAO,IAAI,CAACL,OAAO;QACjB,6FAA6F;QAC7F,6GAA6G;QAC7GG,QAAQJ,UAAU;YAACA;YAASM,SAAS;QAAQ,IAAI;YAACC,SAAS;QAAM;IACnE;IAEA,MAAMC,SAAS,MAAMZ,mBAAmB;QACtCa,YAAYX;QACZY,aAAa;IACf;IAEA,IAAI;QACF,MAAMC,UAAUP,QAAQ;YAACA;YAAOC;QAAG,IAAI;YAACA;QAAG;QAC3C,OAAO,MAAMG,OAAOI,OAAO,CAACD;IAC9B,EAAE,OAAOE,KAAK;QACZ,IAAIA,KAAKC,eAAe,KAAK;YAC3B,OAAO;QACT;QAEAnB,MAAM,kCAAkCkB;QACxC,MAAMA;IACR;AACF;AAOA,OAAO,eAAeE,sBAAsB,EAC1CC,aAAa,EACbV,OAAO,EACsB;IAC7B,MAAME,SAAS,MAAMZ,mBAAmB;QACtCa,YAAYX;QACZY,aAAa;IACf;IAEA,MAAMF,OAAOI,OAAO,CAAC;QACnBK,QAAQ;QACRb,OAAO;YAACE;QAAO;QACfD,KAAK,CAAC,mBAAmB,EAAEW,eAAe;IAC5C;AACF;AAeA,OAAO,eAAeE,sBAAsB,EAC1CF,aAAa,EACbV,OAAO,EACPa,IAAI,EACyB;IAC7B,MAAMX,SAAS,MAAMZ,mBAAmB;QACtCa,YAAYX;QACZY,aAAa;IACf;IAEA,OAAOF,OAAOI,OAAO,CAAC;QACpBO;QACAF,QAAQ;QACRb,OAAO;YAACE;QAAO;QACfD,KAAK,CAAC,mBAAmB,EAAEW,eAAe;IAC5C;AACF;AAUA,OAAO,eAAeI,oBACpBT,OAQK;IAEL,MAAM,EAACL,OAAO,EAAC,GAAGK;IAClB,MAAMH,SAAS,MAAMZ,mBAAmB;QACtCa,YAAYX;QACZY,aAAa;IACf;IAEA,IAAIJ,YAAY,UAAU;QACxB,MAAM,EAACH,SAAS,EAAC,GAAGQ;QACpB,OAAO,MAAMH,OAAOI,OAAO,CAAC;YAC1BR,OAAO;gBAACE,SAAS;YAAQ;YACzBD,KAAK,CAAC,UAAU,EAAEF,UAAU,kBAAkB,CAAC;QACjD;IACF;IAEA,MAAM,EAACkB,cAAc,EAAC,GAAGV;IAEzB,IAAI;QACF,OAAO,MAAMH,OAAOI,OAAO,CAAC;YAC1BR,OAAO;gBAACE,SAAS;gBAAWe,gBAAgBA;YAAe;YAC3DhB,KAAK,CAAC,kBAAkB,CAAC;QAC3B;IACF,EAAE,OAAOiB,OAAO;QACd,iEAAiE;QACjE,uCAAuC;QACvC,IAAIA,OAAOR,eAAe,KAAK;YAC7B,MAAMQ;QACR;QAEA3B,MAAM,mCAAmC2B;QACzC,OAAO;IACT;AACF;AAkBA,OAAO,eAAeC,sBAAsBZ,OAQ3C;IACC,MAAM,EAACL,OAAO,EAAEa,IAAI,EAAC,GAAGR;IAExB,MAAMH,SAAS,MAAMZ,mBAAmB;QACtCa,YAAYX;QACZY,aAAa;IACf;IAEA,IAAIL;IACJ,IAAID;IAEJ,0DAA0D;IAC1D,IAAIE,YAAY,WAAW;QACzB,MAAM,EAACe,cAAc,EAAC,GAAGV;QACzBN,MAAM;QACND,QAAQ;YAACE,SAAS;YAAWe,gBAAgBA;QAAe;IAC9D,OAAO;QACL,MAAM,EAAClB,SAAS,EAAC,GAAGQ;QACpBN,MAAM,CAAC,UAAU,EAAEF,UAAU,kBAAkB,CAAC;QAChDC,QAAQ;YAACE,SAAS;QAAQ;IAC5B;IAEA,OAAOE,OAAOI,OAAO,CAAC;QAACO;QAAMF,QAAQ;QAAQb;QAAOC;IAAG;AACzD;AAgBA,OAAO,eAAemB,iBAAiB,EACrCR,aAAa,EACbS,KAAK,EACLC,cAAc,EACdC,QAAQ,EACRxB,SAAS,EACTyB,OAAO,EACPC,OAAO,EACiB;IACxB,MAAMrB,SAAS,MAAMZ,mBAAmB;QACtCa,YAAYX;QACZY,aAAa;IACf;IAEA,MAAMoB,WAAW,IAAIjC;IACrBiC,SAASC,MAAM,CAAC,kBAAkBL,eAAeM,QAAQ;IACzDF,SAASC,MAAM,CAAC,WAAWF;IAC3B,IAAIF,UAAU;QACZG,SAASC,MAAM,CAAC,YAAYE,KAAKC,SAAS,CAACP;IAC7C;IAEA,IAAIC,SAAS;QACXE,SAASC,MAAM,CAAC,WAAWH,SAAS;YAACO,aAAa;YAAoBC,UAAU;QAAY;IAC9F;IAEA,IAAI/B;IACJ,IAAID;IAEJ,IAAIqB,OAAO;QACTpB,MAAM,CAAC,mBAAmB,EAAEW,cAAc,YAAY,CAAC;QACvDZ,QAAQ;YAACE,SAAS;QAAS;IAC7B,OAAO;QACLD,MAAM,CAAC,UAAU,EAAEF,UAAU,mBAAmB,EAAEa,cAAc,YAAY,CAAC;QAC7EZ,QAAQ;YAACE,SAAS;QAAQ;IAC5B;IAEA,OAAOE,OAAOI,OAAO,CAAC;QACpBO,MAAMW,SAASO,IAAI,CAAC,IAAI3C;QACxB4C,SAASR,SAASS,UAAU;QAC5BtB,QAAQ;QACRb;QACAC;IACF;AACF"}
|
|
@@ -2,7 +2,7 @@ import { isWorkbenchApp } from '@sanity/workbench-cli';
|
|
|
2
2
|
/**
|
|
3
3
|
* Determine if the current project is an app (as opposed to a studio).
|
|
4
4
|
*
|
|
5
|
-
* For workbench apps (`
|
|
5
|
+
* For workbench apps (`defineApplication`), this is driven by the resolved
|
|
6
6
|
* `applicationType` — a studio is not an app, everything else is. The
|
|
7
7
|
* `applicationType` is settled at config-load time (explicit, or inferred from
|
|
8
8
|
* the presence of a `sanity.config.*`). Legacy configs fall back to the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/determineIsApp.ts"],"sourcesContent":["import {type CliConfig} from '@sanity/cli-core'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\n\n/**\n * Determine if the current project is an app (as opposed to a studio).\n *\n * For workbench apps (`
|
|
1
|
+
{"version":3,"sources":["../../src/util/determineIsApp.ts"],"sourcesContent":["import {type CliConfig} from '@sanity/cli-core'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\n\n/**\n * Determine if the current project is an app (as opposed to a studio).\n *\n * For workbench apps (`defineApplication`), this is driven by the resolved\n * `applicationType` — a studio is not an app, everything else is. The\n * `applicationType` is settled at config-load time (explicit, or inferred from\n * the presence of a `sanity.config.*`). Legacy configs fall back to the\n * presence of an `app` field.\n *\n * @returns `true` if the current project is an app, `false` otherwise.\n */\nexport function determineIsApp(cliConfig: CliConfig): boolean {\n const app = cliConfig?.app\n if (isWorkbenchApp(app)) {\n return app.applicationType !== 'studio'\n }\n return Boolean(cliConfig && 'app' in cliConfig)\n}\n"],"names":["isWorkbenchApp","determineIsApp","cliConfig","app","applicationType","Boolean"],"mappings":"AACA,SAAQA,cAAc,QAAO,wBAAuB;AAEpD;;;;;;;;;;CAUC,GACD,OAAO,SAASC,eAAeC,SAAoB;IACjD,MAAMC,MAAMD,WAAWC;IACvB,IAAIH,eAAeG,MAAM;QACvB,OAAOA,IAAIC,eAAe,KAAK;IACjC;IACA,OAAOC,QAAQH,aAAa,SAASA;AACvC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sorts pre-stringified table rows by a single column, ascending.
|
|
3
|
+
*
|
|
4
|
+
* Values are compared as strings, so a numeric column orders lexicographically
|
|
5
|
+
* (`10` before `9`) — kept deliberately, since that is how these listings have
|
|
6
|
+
* always ordered. `Array.prototype.toSorted` is a stable sort, so rows that tie
|
|
7
|
+
* on the column keep their original order. An out-of-range column leaves the
|
|
8
|
+
* rows in their original order.
|
|
9
|
+
*
|
|
10
|
+
* @param rows - The rows to sort
|
|
11
|
+
* @param column - Index of the column to sort by
|
|
12
|
+
* @returns A new, sorted array
|
|
13
|
+
* @internal
|
|
14
|
+
*/ export function sortRowsByColumn(rows, column) {
|
|
15
|
+
return rows.toSorted((a, b)=>{
|
|
16
|
+
const left = a[column];
|
|
17
|
+
const right = b[column];
|
|
18
|
+
if (left === right) return 0;
|
|
19
|
+
return left < right ? -1 : 1;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=sortRowsByColumn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/sortRowsByColumn.ts"],"sourcesContent":["/**\n * Sorts pre-stringified table rows by a single column, ascending.\n *\n * Values are compared as strings, so a numeric column orders lexicographically\n * (`10` before `9`) — kept deliberately, since that is how these listings have\n * always ordered. `Array.prototype.toSorted` is a stable sort, so rows that tie\n * on the column keep their original order. An out-of-range column leaves the\n * rows in their original order.\n *\n * @param rows - The rows to sort\n * @param column - Index of the column to sort by\n * @returns A new, sorted array\n * @internal\n */\nexport function sortRowsByColumn<Row extends readonly string[]>(\n rows: Row[],\n column: number,\n): Row[] {\n return rows.toSorted((a, b) => {\n const left = a[column]\n const right = b[column]\n if (left === right) return 0\n return left < right ? -1 : 1\n })\n}\n"],"names":["sortRowsByColumn","rows","column","toSorted","a","b","left","right"],"mappings":"AAAA;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASA,iBACdC,IAAW,EACXC,MAAc;IAEd,OAAOD,KAAKE,QAAQ,CAAC,CAACC,GAAGC;QACvB,MAAMC,OAAOF,CAAC,CAACF,OAAO;QACtB,MAAMK,QAAQF,CAAC,CAACH,OAAO;QACvB,IAAII,SAASC,OAAO,OAAO;QAC3B,OAAOD,OAAOC,QAAQ,CAAC,IAAI;IAC7B;AACF"}
|