@sanity/cli 8.0.1 → 8.0.3
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/SanityHelp.js.map +1 -1
- package/dist/actions/backup/assertDatasetExist.js +2 -1
- package/dist/actions/backup/assertDatasetExist.js.map +1 -1
- package/dist/actions/backup/downloadAsset.js +3 -24
- package/dist/actions/backup/downloadAsset.js.map +1 -1
- package/dist/actions/backup/downloadDocument.js +11 -22
- package/dist/actions/backup/downloadDocument.js.map +1 -1
- package/dist/actions/backup/downloadStream.js +83 -0
- package/dist/actions/backup/downloadStream.js.map +1 -0
- package/dist/actions/build/buildStudio.js +3 -2
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/build/eventListenerFactory.js +7 -6
- package/dist/actions/build/eventListenerFactory.js.map +1 -1
- package/dist/actions/build/shouldAutoUpdate.js +2 -1
- package/dist/actions/build/shouldAutoUpdate.js.map +1 -1
- package/dist/actions/cors/filterAndValidateOrigin.js +3 -2
- package/dist/actions/cors/filterAndValidateOrigin.js.map +1 -1
- package/dist/actions/deploy/createUserApplication.js +2 -1
- package/dist/actions/deploy/createUserApplication.js.map +1 -1
- package/dist/actions/deploy/deployRunner.js +3 -2
- package/dist/actions/deploy/deployRunner.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +3 -3
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/findUserApplication.js +8 -7
- package/dist/actions/deploy/findUserApplication.js.map +1 -1
- package/dist/actions/dev/servers/startAppDevServer.js +2 -1
- package/dist/actions/dev/servers/startAppDevServer.js.map +1 -1
- package/dist/actions/dev/servers/startStudioDevServer.js +3 -3
- package/dist/actions/dev/servers/startStudioDevServer.js.map +1 -1
- package/dist/actions/documents/validate.js +5 -5
- package/dist/actions/documents/validate.js.map +1 -1
- package/dist/actions/documents/validateDocuments.worker.js +4 -1
- package/dist/actions/documents/validateDocuments.worker.js.map +1 -1
- package/dist/actions/init/env/createOrAppendEnvVars.js +2 -1
- package/dist/actions/init/env/createOrAppendEnvVars.js.map +1 -1
- package/dist/actions/init/env/parseAndUpdateEnvVars.js +2 -2
- package/dist/actions/init/env/parseAndUpdateEnvVars.js.map +1 -1
- package/dist/actions/schema/extractSchema.js +2 -2
- package/dist/actions/schema/extractSchema.js.map +1 -1
- package/dist/actions/schema/extractSchemaWatcher.js +2 -1
- package/dist/actions/schema/extractSchemaWatcher.js.map +1 -1
- package/dist/actions/schema/uploadSchemaToLexicon.js +3 -0
- package/dist/actions/schema/uploadSchemaToLexicon.js.map +1 -1
- package/dist/actions/telemetry/telemetryDebug.js +2 -2
- package/dist/actions/telemetry/telemetryDebug.js.map +1 -1
- package/dist/actions/undeploy/runUndeploy.js +2 -2
- package/dist/actions/undeploy/runUndeploy.js.map +1 -1
- package/dist/commands/backups/list.js +5 -8
- package/dist/commands/backups/list.js.map +1 -1
- package/dist/commands/datasets/copy.js +5 -7
- package/dist/commands/datasets/copy.js.map +1 -1
- package/dist/commands/datasets/import.js +7 -10
- package/dist/commands/datasets/import.js.map +1 -1
- package/dist/commands/docs/search.js +2 -2
- package/dist/commands/docs/search.js.map +1 -1
- package/dist/commands/mcp/configure.js +2 -2
- package/dist/commands/mcp/configure.js.map +1 -1
- package/dist/commands/typegen/generate.js +6 -6
- package/dist/commands/typegen/generate.js.map +1 -1
- package/dist/exports/_internal.d.ts +50 -82
- package/dist/exports/index.d.ts +48 -78
- package/dist/exports/invokeSanityCli/index.d.ts +108 -18
- package/dist/exports/invokeSanityCli/index.js +2 -1
- package/dist/exports/invokeSanityCli/index.js.map +1 -1
- package/dist/exports/runtime.d.ts +3 -65
- package/dist/services/api.js +23 -15
- package/dist/services/api.js.map +1 -1
- package/dist/services/auth.js +4 -4
- package/dist/services/auth.js.map +1 -1
- package/dist/services/backup.js +3 -3
- package/dist/services/backup.js.map +1 -1
- package/dist/services/cors.js +3 -3
- package/dist/services/cors.js.map +1 -1
- package/dist/services/datasetAliases.js +5 -5
- package/dist/services/datasetAliases.js.map +1 -1
- package/dist/services/datasets.js +3 -3
- package/dist/services/datasets.js.map +1 -1
- package/dist/services/documents.js +1 -1
- package/dist/services/documents.js.map +1 -1
- package/dist/services/getProjectFeatures.js +1 -1
- package/dist/services/getProjectFeatures.js.map +1 -1
- package/dist/services/getUrlHeaders.js +3 -9
- package/dist/services/getUrlHeaders.js.map +1 -1
- package/dist/services/grants.js +1 -1
- package/dist/services/grants.js.map +1 -1
- package/dist/services/graphql.js +4 -3
- package/dist/services/graphql.js.map +1 -1
- package/dist/services/hooks.js +6 -6
- package/dist/services/hooks.js.map +1 -1
- package/dist/services/mcp.js +4 -4
- package/dist/services/mcp.js.map +1 -1
- package/dist/services/mediaLibraries.js +3 -3
- package/dist/services/mediaLibraries.js.map +1 -1
- package/dist/services/mintProject.js +33 -14
- package/dist/services/mintProject.js.map +1 -1
- package/dist/services/organizations.js +6 -6
- package/dist/services/organizations.js.map +1 -1
- package/dist/services/plans.js +2 -2
- package/dist/services/plans.js.map +1 -1
- package/dist/services/projects.js +7 -7
- package/dist/services/projects.js.map +1 -1
- package/dist/services/schemas.js +2 -2
- package/dist/services/schemas.js.map +1 -1
- package/dist/services/telemetry.js +2 -2
- package/dist/services/telemetry.js.map +1 -1
- package/dist/services/tokens.js +5 -5
- package/dist/services/tokens.js.map +1 -1
- package/dist/services/user.js +1 -1
- package/dist/services/user.js.map +1 -1
- package/dist/services/userApplications.js +18 -18
- package/dist/services/userApplications.js.map +1 -1
- package/dist/util/appId.js +2 -1
- package/dist/util/appId.js.map +1 -1
- package/dist/util/dates.js +125 -0
- package/dist/util/dates.js.map +1 -0
- package/dist/util/getCliVersion.js +1 -11
- package/dist/util/getCliVersion.js.map +1 -1
- package/oclif.manifest.json +1093 -1093
- package/package.json +12 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/telemetry.ts"],"sourcesContent":["import {createHash} from 'node:crypto'\n\nimport {getCliToken, getGlobalCliClient, getUserConfig} from '@sanity/cli-core'\nimport {getCliExecutionContext} from '@sanity/cli-core/executionContext'\nimport {type TelemetryEvent} from '@sanity/telemetry'\n\nimport {telemetryDebug} from '../actions/telemetry/telemetryDebug.js'\nimport {createExpiringConfig} from '../util/createExpiringConfig.js'\n\nexport const TELEMETRY_API_VERSION = 'v2026-01-22'\n\nexport const VALID_API_STATUSES = ['granted', 'denied', 'unset'] as const\nexport type ValidApiConsentStatus = (typeof VALID_API_STATUSES)[number]\n\nexport async function sendEvents(batch: TelemetryEvent[]) {\n const client = await getGlobalCliClient({\n apiVersion: TELEMETRY_API_VERSION,\n requireUser: true,\n })\n\n const projectId = process.env.SANITY_TELEMETRY_PROJECT_ID\n\n return client.request({\n body: {batch, projectId},\n json: true,\n method: 'POST',\n
|
|
1
|
+
{"version":3,"sources":["../../src/services/telemetry.ts"],"sourcesContent":["import {createHash} from 'node:crypto'\n\nimport {getCliToken, getGlobalCliClient, getUserConfig} from '@sanity/cli-core'\nimport {getCliExecutionContext} from '@sanity/cli-core/executionContext'\nimport {type TelemetryEvent} from '@sanity/telemetry'\n\nimport {telemetryDebug} from '../actions/telemetry/telemetryDebug.js'\nimport {createExpiringConfig} from '../util/createExpiringConfig.js'\n\nexport const TELEMETRY_API_VERSION = 'v2026-01-22'\n\nexport const VALID_API_STATUSES = ['granted', 'denied', 'unset'] as const\nexport type ValidApiConsentStatus = (typeof VALID_API_STATUSES)[number]\n\nexport async function sendEvents(batch: TelemetryEvent[]) {\n const client = await getGlobalCliClient({\n apiVersion: TELEMETRY_API_VERSION,\n requireUser: true,\n })\n\n const projectId = process.env.SANITY_TELEMETRY_PROJECT_ID\n\n return client.request({\n body: {batch, projectId},\n json: true,\n method: 'POST',\n url: '/intake/batch',\n })\n}\n\nasync function getTelemetryConsent(): Promise<{\n status: ValidApiConsentStatus\n}> {\n const client = await getGlobalCliClient({\n apiVersion: TELEMETRY_API_VERSION,\n requireUser: false,\n })\n\n return client.request({tag: 'telemetry-consent', url: '/intake/telemetry-status'})\n}\n\n/**\n * Check if the given status is a valid consent status\n *\n * @param status - The status to check\n * @returns True if the status is valid, false otherwise\n * @internal\n */\nexport function isValidApiConsentStatus(status: string): status is ValidApiConsentStatus {\n return VALID_API_STATUSES.includes(status as ValidApiConsentStatus)\n}\n\n/**\n * Check if the given response is a valid API consent response\n *\n * @param response - The response to check\n * @returns True if the response is valid, false otherwise\n * @internal\n */\nfunction isValidApiConsentResponse(response: unknown): response is {status: ValidApiConsentStatus} {\n return (\n typeof response === 'object' &&\n response !== null &&\n 'status' in response &&\n typeof response.status === 'string' &&\n isValidApiConsentStatus(response.status)\n )\n}\n\nexport const TELEMETRY_CONSENT_CONFIG_KEY = 'telemetryConsent'\nconst FIVE_MINUTES = 1000 * 60 * 5\n\n/**\n * Get a token-scoped cache key for telemetry consent. This ensures that switching\n * users (via login/logout) always results in a cache miss, preventing one user\n * from inheriting another user's cached consent status.\n *\n * @param token - The current auth token, or undefined if not logged in\n * @returns A cache key scoped to the token\n */\nexport function getTelemetryConsentCacheKey(token: string | undefined): string {\n if (!token) {\n return TELEMETRY_CONSENT_CONFIG_KEY\n }\n\n const hash = createHash('sha256').update(token).digest('hex').slice(0, 12)\n return `${TELEMETRY_CONSENT_CONFIG_KEY}:${hash}`\n}\n\n/**\n * Fetch the telemetry consent status for the current user\n * @returns The telemetry consent status\n *\n * @internal\n */\nexport async function fetchTelemetryConsent(): Promise<{\n status: ValidApiConsentStatus\n}> {\n // Programmatic invocations must not use the host user's disk-backed consent\n // cache. The request is already authenticated with the invocation token.\n if (getCliExecutionContext()) return getTelemetryConsent()\n\n const token = await getCliToken()\n const cacheKey = getTelemetryConsentCacheKey(token)\n\n // NOTE: createExpiringConfig is instantiated on every call, so in-flight request\n // deduplication (via currentFetch) does not work across concurrent calls to\n // fetchTelemetryConsent(). Two concurrent callers will make two HTTP requests.\n // Consider moving to module-level instance if this becomes a bottleneck.\n const telemetryConsentConfig = createExpiringConfig<{\n status: ValidApiConsentStatus\n }>({\n fetchValue: () => getTelemetryConsent(),\n key: cacheKey,\n onCacheHit() {\n telemetryDebug('Retrieved telemetry consent status from cache')\n },\n onFetch() {\n telemetryDebug('Fetching telemetry consent status...')\n },\n onRevalidate() {\n telemetryDebug('Revalidating cached telemetry consent status...')\n },\n store: getUserConfig(),\n ttl: FIVE_MINUTES,\n validateValue: isValidApiConsentResponse,\n })\n\n return telemetryConsentConfig.get()\n}\n"],"names":["createHash","getCliToken","getGlobalCliClient","getUserConfig","getCliExecutionContext","telemetryDebug","createExpiringConfig","TELEMETRY_API_VERSION","VALID_API_STATUSES","sendEvents","batch","client","apiVersion","requireUser","projectId","process","env","SANITY_TELEMETRY_PROJECT_ID","request","body","json","method","url","getTelemetryConsent","tag","isValidApiConsentStatus","status","includes","isValidApiConsentResponse","response","TELEMETRY_CONSENT_CONFIG_KEY","FIVE_MINUTES","getTelemetryConsentCacheKey","token","hash","update","digest","slice","fetchTelemetryConsent","cacheKey","telemetryConsentConfig","fetchValue","key","onCacheHit","onFetch","onRevalidate","store","ttl","validateValue","get"],"mappings":"AAAA,SAAQA,UAAU,QAAO,cAAa;AAEtC,SAAQC,WAAW,EAAEC,kBAAkB,EAAEC,aAAa,QAAO,mBAAkB;AAC/E,SAAQC,sBAAsB,QAAO,oCAAmC;AAGxE,SAAQC,cAAc,QAAO,yCAAwC;AACrE,SAAQC,oBAAoB,QAAO,kCAAiC;AAEpE,OAAO,MAAMC,wBAAwB,cAAa;AAElD,OAAO,MAAMC,qBAAqB;IAAC;IAAW;IAAU;CAAQ,CAAS;AAGzE,OAAO,eAAeC,WAAWC,KAAuB;IACtD,MAAMC,SAAS,MAAMT,mBAAmB;QACtCU,YAAYL;QACZM,aAAa;IACf;IAEA,MAAMC,YAAYC,QAAQC,GAAG,CAACC,2BAA2B;IAEzD,OAAON,OAAOO,OAAO,CAAC;QACpBC,MAAM;YAACT;YAAOI;QAAS;QACvBM,MAAM;QACNC,QAAQ;QACRC,KAAK;IACP;AACF;AAEA,eAAeC;IAGb,MAAMZ,SAAS,MAAMT,mBAAmB;QACtCU,YAAYL;QACZM,aAAa;IACf;IAEA,OAAOF,OAAOO,OAAO,CAAC;QAACM,KAAK;QAAqBF,KAAK;IAA0B;AAClF;AAEA;;;;;;CAMC,GACD,OAAO,SAASG,wBAAwBC,MAAc;IACpD,OAAOlB,mBAAmBmB,QAAQ,CAACD;AACrC;AAEA;;;;;;CAMC,GACD,SAASE,0BAA0BC,QAAiB;IAClD,OACE,OAAOA,aAAa,YACpBA,aAAa,QACb,YAAYA,YACZ,OAAOA,SAASH,MAAM,KAAK,YAC3BD,wBAAwBI,SAASH,MAAM;AAE3C;AAEA,OAAO,MAAMI,+BAA+B,mBAAkB;AAC9D,MAAMC,eAAe,OAAO,KAAK;AAEjC;;;;;;;CAOC,GACD,OAAO,SAASC,4BAA4BC,KAAyB;IACnE,IAAI,CAACA,OAAO;QACV,OAAOH;IACT;IAEA,MAAMI,OAAOlC,WAAW,UAAUmC,MAAM,CAACF,OAAOG,MAAM,CAAC,OAAOC,KAAK,CAAC,GAAG;IACvE,OAAO,GAAGP,6BAA6B,CAAC,EAAEI,MAAM;AAClD;AAEA;;;;;CAKC,GACD,OAAO,eAAeI;IAGpB,4EAA4E;IAC5E,yEAAyE;IACzE,IAAIlC,0BAA0B,OAAOmB;IAErC,MAAMU,QAAQ,MAAMhC;IACpB,MAAMsC,WAAWP,4BAA4BC;IAE7C,iFAAiF;IACjF,4EAA4E;IAC5E,+EAA+E;IAC/E,yEAAyE;IACzE,MAAMO,yBAAyBlC,qBAE5B;QACDmC,YAAY,IAAMlB;QAClBmB,KAAKH;QACLI;YACEtC,eAAe;QACjB;QACAuC;YACEvC,eAAe;QACjB;QACAwC;YACExC,eAAe;QACjB;QACAyC,OAAO3C;QACP4C,KAAKhB;QACLiB,eAAepB;IACjB;IAEA,OAAOY,uBAAuBS,GAAG;AACnC"}
|
package/dist/services/tokens.js
CHANGED
|
@@ -9,7 +9,7 @@ function getClient(token) {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
|
-
async function fetchAllPages(client,
|
|
12
|
+
async function fetchAllPages(client, url) {
|
|
13
13
|
const items = [];
|
|
14
14
|
let cursor = null;
|
|
15
15
|
do {
|
|
@@ -17,7 +17,7 @@ async function fetchAllPages(client, uri) {
|
|
|
17
17
|
query: cursor === null ? {} : {
|
|
18
18
|
nextCursor: cursor
|
|
19
19
|
},
|
|
20
|
-
|
|
20
|
+
url
|
|
21
21
|
});
|
|
22
22
|
items.push(...response.data);
|
|
23
23
|
cursor = response.nextCursor;
|
|
@@ -63,7 +63,7 @@ async function fetchAllPages(client, uri) {
|
|
|
63
63
|
query: sendNotification === false ? {
|
|
64
64
|
sendNotification: 'false'
|
|
65
65
|
} : {},
|
|
66
|
-
|
|
66
|
+
url: `/access/project/${projectId}/robots`
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
@@ -78,7 +78,7 @@ async function fetchAllPages(client, uri) {
|
|
|
78
78
|
const client = await getClient();
|
|
79
79
|
return client.request({
|
|
80
80
|
method: 'DELETE',
|
|
81
|
-
|
|
81
|
+
url: `/access/project/${projectId}/robots/${tokenId}`
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
84
|
/**
|
|
@@ -93,7 +93,7 @@ async function fetchAllPages(client, uri) {
|
|
|
93
93
|
const client = await getClient(token);
|
|
94
94
|
return client.request({
|
|
95
95
|
method: 'POST',
|
|
96
|
-
|
|
96
|
+
url: '/access/robots/me/rotate'
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
@@ -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} 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, url: string): 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: 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 CreateTokenOptions {\n label: string\n projectId: string\n roleName: 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, roleName, sendNotification} = options\n\n const client = await getClient()\n\n return client.request<RobotWithToken>({\n body: {\n label,\n memberships: [{resourceId: projectId, resourceType: 'project', roleNames: [roleName]}],\n ...(expiresAt === undefined ? {} : {expiresAt}),\n },\n method: 'POST',\n query: sendNotification === false ? {sendNotification: 'false'} : {},\n url: `/access/project/${projectId}/robots`,\n })\n}\n\ninterface DeleteTokenOptions {\n projectId: string\n tokenId: string\n}\n\n/**\n * Delete a token from a project\n * @param options - The options for deleting a token from a project; `tokenId`\n * is the id reported by `getTokens`/`createToken`\n * @returns A promise that resolves when the token is deleted\n *\n * @internal\n */\nexport async function deleteToken(options: DeleteTokenOptions): Promise<void> {\n const {projectId, tokenId} = options\n\n const client = await getClient()\n\n return client.request({\n method: 'DELETE',\n url: `/access/project/${projectId}/robots/${tokenId}`,\n })\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/**\n * Get all tokens for a project. Tokens managed by an organization are\n * excluded: they cannot be managed at the project scope.\n * @param projectId - The project ID\n * @returns A promise that resolves to an array of robots\n *\n * @internal\n */\nexport async function getTokens(projectId: string): Promise<Robot[]> {\n const client = await getClient()\n\n const robots = await fetchAllPages<Robot>(client, `/access/project/${projectId}/robots`)\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","items","cursor","response","request","query","nextCursor","push","data","getProjectMembership","robot","projectId","memberships","find","membership","resourceType","resourceId","createToken","options","expiresAt","label","roleName","sendNotification","body","roleNames","method","deleteToken","tokenId","rotateToken","getTokens","robots","filter","managedBy","getTokenRoles"],"mappings":"AAAA,SAAQA,kBAAkB,QAAO,mBAAkB;AAGnD,SAAQC,kBAAkB,QAAO,iCAAgC;AAajE,SAASC,UAAUC,KAAc;IAC/B,OAAOH,mBAAmB;QACxBI,YAAYH;QACZI,aAAa;QACb,GAAIF,UAAUG,YAAY,CAAC,IAAI;YAACH;QAAK,CAAC;IACxC;AACF;AAEA,eAAeI,cAAiBC,MAAoB,EAAEC,GAAW;IAC/D,MAAMC,QAAa,EAAE;IACrB,IAAIC,SAAwB;IAE5B,GAAG;QACD,MAAMC,WAAiC,MAAMJ,OAAOK,OAAO,CAAuB;YAChFC,OAAOH,WAAW,OAAO,CAAC,IAAI;gBAACI,YAAYJ;YAAM;YACjDF;QACF;QACAC,MAAMM,IAAI,IAAIJ,SAASK,IAAI;QAC3BN,SAASC,SAASG,UAAU;IAC9B,QAASJ,WAAW,KAAK;IAEzB,OAAOD;AACT;AAEA;;;;;;;CAOC,GACD,OAAO,SAASQ,qBAAqBC,KAAY,EAAEC,SAAiB;IAClE,OAAOD,MAAME,WAAW,CAACC,IAAI,CAC3B,CAACC,aAAeA,WAAWC,YAAY,KAAK,aAAaD,WAAWE,UAAU,KAAKL;AAEvF;AAWA;;;;;;CAMC,GACD,OAAO,eAAeM,YAAYC,OAA2B;IAC3D,MAAM,EAACC,SAAS,EAAEC,KAAK,EAAET,SAAS,EAAEU,QAAQ,EAAEC,gBAAgB,EAAC,GAAGJ;IAElE,MAAMnB,SAAS,MAAMN;IAErB,OAAOM,OAAOK,OAAO,CAAiB;QACpCmB,MAAM;YACJH;YACAR,aAAa;gBAAC;oBAACI,YAAYL;oBAAWI,cAAc;oBAAWS,WAAW;wBAACH;qBAAS;gBAAA;aAAE;YACtF,GAAIF,cAActB,YAAY,CAAC,IAAI;gBAACsB;YAAS,CAAC;QAChD;QACAM,QAAQ;QACRpB,OAAOiB,qBAAqB,QAAQ;YAACA,kBAAkB;QAAO,IAAI,CAAC;QACnEtB,KAAK,CAAC,gBAAgB,EAAEW,UAAU,OAAO,CAAC;IAC5C;AACF;AAOA;;;;;;;CAOC,GACD,OAAO,eAAee,YAAYR,OAA2B;IAC3D,MAAM,EAACP,SAAS,EAAEgB,OAAO,EAAC,GAAGT;IAE7B,MAAMnB,SAAS,MAAMN;IAErB,OAAOM,OAAOK,OAAO,CAAC;QACpBqB,QAAQ;QACRzB,KAAK,CAAC,gBAAgB,EAAEW,UAAU,QAAQ,EAAEgB,SAAS;IACvD;AACF;AAEA;;;;;;;;CAQC,GACD,OAAO,eAAeC,YAAYlC,KAAa;IAC7C,MAAMK,SAAS,MAAMN,UAAUC;IAE/B,OAAOK,OAAOK,OAAO,CAAiB;QACpCqB,QAAQ;QACRzB,KAAK;IACP;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,eAAe6B,UAAUlB,SAAiB;IAC/C,MAAMZ,SAAS,MAAMN;IAErB,MAAMqC,SAAS,MAAMhC,cAAqBC,QAAQ,CAAC,gBAAgB,EAAEY,UAAU,OAAO,CAAC;IAEvF,OAAOmB,OAAOC,MAAM,CAAC,CAACrB,QAAUA,MAAMsB,SAAS,EAAEjB,iBAAiB;AACpE;AAEA;;;;;;CAMC,GACD,OAAO,eAAekB,cAActB,SAAiB;IACnD,MAAMZ,SAAS,MAAMN;IAErB,OAAOK,cAAoBC,QAAQ,CAAC,gBAAgB,EAAEY,UAAU,MAAM,CAAC;AACzE"}
|
package/dist/services/user.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/user.ts"],"sourcesContent":["import {getGlobalCliClient, getProjectCliClient, type SanityOrgUser} from '@sanity/cli-core'\n\nimport {type User} from '../actions/users/types.js'\n\n/**\n * The API version to use for the users list command\n *\n * @internal\n */\nexport const USERS_API_VERSION = 'v2025-08-30'\n\nexport async function getCliUser() {\n const client = await getGlobalCliClient({\n apiVersion: USERS_API_VERSION,\n requireUser: true,\n })\n\n return client.users.getById('me') as unknown as SanityOrgUser\n}\n\nexport async function getMembers(memberIds: string[]) {\n const client = await getGlobalCliClient({\n apiVersion: USERS_API_VERSION,\n requireUser: true,\n })\n\n return client.request<User | User[]>({
|
|
1
|
+
{"version":3,"sources":["../../src/services/user.ts"],"sourcesContent":["import {getGlobalCliClient, getProjectCliClient, type SanityOrgUser} from '@sanity/cli-core'\n\nimport {type User} from '../actions/users/types.js'\n\n/**\n * The API version to use for the users list command\n *\n * @internal\n */\nexport const USERS_API_VERSION = 'v2025-08-30'\n\nexport async function getCliUser() {\n const client = await getGlobalCliClient({\n apiVersion: USERS_API_VERSION,\n requireUser: true,\n })\n\n return client.users.getById('me') as unknown as SanityOrgUser\n}\n\nexport async function getMembers(memberIds: string[]) {\n const client = await getGlobalCliClient({\n apiVersion: USERS_API_VERSION,\n requireUser: true,\n })\n\n return client.request<User | User[]>({url: `/users/${memberIds.join(',')}`})\n}\n\n/**\n * Get the user for a project\n * @param projectId - The ID of the project\n */\nexport async function getProjectUser(projectId: string) {\n const client = await getProjectCliClient({\n apiVersion: USERS_API_VERSION,\n projectId,\n requireUser: true,\n })\n\n return client.users.getById('me')\n}\n"],"names":["getGlobalCliClient","getProjectCliClient","USERS_API_VERSION","getCliUser","client","apiVersion","requireUser","users","getById","getMembers","memberIds","request","url","join","getProjectUser","projectId"],"mappings":"AAAA,SAAQA,kBAAkB,EAAEC,mBAAmB,QAA2B,mBAAkB;AAI5F;;;;CAIC,GACD,OAAO,MAAMC,oBAAoB,cAAa;AAE9C,OAAO,eAAeC;IACpB,MAAMC,SAAS,MAAMJ,mBAAmB;QACtCK,YAAYH;QACZI,aAAa;IACf;IAEA,OAAOF,OAAOG,KAAK,CAACC,OAAO,CAAC;AAC9B;AAEA,OAAO,eAAeC,WAAWC,SAAmB;IAClD,MAAMN,SAAS,MAAMJ,mBAAmB;QACtCK,YAAYH;QACZI,aAAa;IACf;IAEA,OAAOF,OAAOO,OAAO,CAAgB;QAACC,KAAK,CAAC,OAAO,EAAEF,UAAUG,IAAI,CAAC,MAAM;IAAA;AAC5E;AAEA;;;CAGC,GACD,OAAO,eAAeC,eAAeC,SAAiB;IACpD,MAAMX,SAAS,MAAMH,oBAAoB;QACvCI,YAAYH;QACZa;QACAT,aAAa;IACf;IAEA,OAAOF,OAAOG,KAAK,CAACC,OAAO,CAAC;AAC9B"}
|
|
@@ -4,12 +4,12 @@ import FormData from 'form-data';
|
|
|
4
4
|
export const USER_APPLICATIONS_API_VERSION = 'v2024-08-01';
|
|
5
5
|
export async function getUserApplication({ appHost, appId, isSdkApp, projectId }) {
|
|
6
6
|
let query;
|
|
7
|
-
let
|
|
8
|
-
// set the
|
|
7
|
+
let url;
|
|
8
|
+
// set the url
|
|
9
9
|
if (isSdkApp) {
|
|
10
|
-
|
|
10
|
+
url = appId ? `/user-applications/${appId}` : '/user-applications';
|
|
11
11
|
} else {
|
|
12
|
-
|
|
12
|
+
url = appId ? `/projects/${projectId}/user-applications/${appId}` : `/projects/${projectId}/user-applications`;
|
|
13
13
|
}
|
|
14
14
|
// set the query
|
|
15
15
|
if (isSdkApp) {
|
|
@@ -33,9 +33,9 @@ export async function getUserApplication({ appHost, appId, isSdkApp, projectId }
|
|
|
33
33
|
try {
|
|
34
34
|
const options = query ? {
|
|
35
35
|
query,
|
|
36
|
-
|
|
36
|
+
url
|
|
37
37
|
} : {
|
|
38
|
-
|
|
38
|
+
url
|
|
39
39
|
};
|
|
40
40
|
return await client.request(options);
|
|
41
41
|
} catch (err) {
|
|
@@ -56,7 +56,7 @@ export async function deleteUserApplication({ applicationId, appType }) {
|
|
|
56
56
|
query: {
|
|
57
57
|
appType
|
|
58
58
|
},
|
|
59
|
-
|
|
59
|
+
url: `/user-applications/${applicationId}`
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
export async function updateUserApplication({ applicationId, appType, body }) {
|
|
@@ -70,7 +70,7 @@ export async function updateUserApplication({ applicationId, appType, body }) {
|
|
|
70
70
|
query: {
|
|
71
71
|
appType
|
|
72
72
|
},
|
|
73
|
-
|
|
73
|
+
url: `/user-applications/${applicationId}`
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
76
|
export async function getUserApplications(options) {
|
|
@@ -85,7 +85,7 @@ export async function getUserApplications(options) {
|
|
|
85
85
|
query: {
|
|
86
86
|
appType: 'studio'
|
|
87
87
|
},
|
|
88
|
-
|
|
88
|
+
url: `/projects/${projectId}/user-applications`
|
|
89
89
|
});
|
|
90
90
|
}
|
|
91
91
|
const { organizationId } = options;
|
|
@@ -95,7 +95,7 @@ export async function getUserApplications(options) {
|
|
|
95
95
|
appType: 'coreApp',
|
|
96
96
|
organizationId: organizationId
|
|
97
97
|
},
|
|
98
|
-
|
|
98
|
+
url: `/user-applications`
|
|
99
99
|
});
|
|
100
100
|
} catch (error) {
|
|
101
101
|
// User doesn't have permission to view applications for the org,
|
|
@@ -113,19 +113,19 @@ export async function createUserApplication(options) {
|
|
|
113
113
|
apiVersion: USER_APPLICATIONS_API_VERSION,
|
|
114
114
|
requireUser: true
|
|
115
115
|
});
|
|
116
|
-
let
|
|
116
|
+
let url;
|
|
117
117
|
let query;
|
|
118
118
|
// If we have an organizationId, we're creating a core app
|
|
119
119
|
if (appType === 'coreApp') {
|
|
120
120
|
const { organizationId } = options;
|
|
121
|
-
|
|
121
|
+
url = '/user-applications';
|
|
122
122
|
query = {
|
|
123
123
|
appType: 'coreApp',
|
|
124
124
|
organizationId: organizationId
|
|
125
125
|
};
|
|
126
126
|
} else {
|
|
127
127
|
const { projectId } = options;
|
|
128
|
-
|
|
128
|
+
url = `/projects/${projectId}/user-applications`;
|
|
129
129
|
query = {
|
|
130
130
|
appType: 'studio'
|
|
131
131
|
};
|
|
@@ -134,7 +134,7 @@ export async function createUserApplication(options) {
|
|
|
134
134
|
body,
|
|
135
135
|
method: 'POST',
|
|
136
136
|
query,
|
|
137
|
-
|
|
137
|
+
url
|
|
138
138
|
});
|
|
139
139
|
}
|
|
140
140
|
export async function createDeployment({ applicationId, isApp, isAutoUpdating, manifest, projectId, tarball, version }) {
|
|
@@ -154,15 +154,15 @@ export async function createDeployment({ applicationId, isApp, isAutoUpdating, m
|
|
|
154
154
|
filename: 'app.tar.gz'
|
|
155
155
|
});
|
|
156
156
|
}
|
|
157
|
-
let
|
|
157
|
+
let url;
|
|
158
158
|
let query;
|
|
159
159
|
if (isApp) {
|
|
160
|
-
|
|
160
|
+
url = `/user-applications/${applicationId}/deployments`;
|
|
161
161
|
query = {
|
|
162
162
|
appType: 'coreApp'
|
|
163
163
|
};
|
|
164
164
|
} else {
|
|
165
|
-
|
|
165
|
+
url = `/projects/${projectId}/user-applications/${applicationId}/deployments`;
|
|
166
166
|
query = {
|
|
167
167
|
appType: 'studio'
|
|
168
168
|
};
|
|
@@ -172,7 +172,7 @@ export async function createDeployment({ applicationId, isApp, isAutoUpdating, m
|
|
|
172
172
|
headers: formData.getHeaders(),
|
|
173
173
|
method: 'POST',
|
|
174
174
|
query,
|
|
175
|
-
|
|
175
|
+
url
|
|
176
176
|
});
|
|
177
177
|
}
|
|
178
178
|
|
|
@@ -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 uri: string\n\n // set the uri\n if (isSdkApp) {\n uri = appId ? `/user-applications/${appId}` : '/user-applications'\n } else {\n uri = 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, uri} : {uri}\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 uri: `/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 uri: `/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 uri: `/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 uri: `/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 uri\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 uri = '/user-applications'\n query = {appType: 'coreApp', organizationId: organizationId!}\n } else {\n const {projectId} = options as {appType: 'studio'; projectId?: string}\n uri = `/projects/${projectId}/user-applications`\n query = {appType: 'studio'}\n }\n\n return client.request({body, method: 'POST', query, uri})\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 uri\n let query\n\n if (isApp) {\n uri = `/user-applications/${applicationId}/deployments`\n query = {appType: 'coreApp'}\n } else {\n uri = `/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 uri,\n })\n}\n"],"names":["PassThrough","debug","getGlobalCliClient","FormData","USER_APPLICATIONS_API_VERSION","getUserApplication","appHost","appId","isSdkApp","projectId","query","uri","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 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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"}
|
package/dist/util/appId.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
|
+
import { exitCodes } from '@sanity/cli-core';
|
|
2
3
|
function getDeploymentAppId(cliConfig) {
|
|
3
4
|
const id = cliConfig?.deployment?.appId;
|
|
4
5
|
return id;
|
|
@@ -33,7 +34,7 @@ function hasDeprecatedAppId(cliConfig) {
|
|
|
33
34
|
output.error(`${styleText('bold', 'Found both app.id (deprecated) and deployment.appId in your application configuration.')}
|
|
34
35
|
|
|
35
36
|
Please remove app.id from your sanity.cli.js or sanity.cli.ts file.`, {
|
|
36
|
-
exit:
|
|
37
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
// Just warn if only the old app ID config is found
|
package/dist/util/appId.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/appId.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type CliConfig, type Output} from '@sanity/cli-core'\n\ninterface Options {\n cliConfig: CliConfig\n output: Output\n}\n\nfunction getDeploymentAppId(cliConfig: CliConfig): string | undefined {\n const id = cliConfig?.deployment?.appId\n return id\n}\n\nfunction getDeprecatedAppId(cliConfig: CliConfig): string | undefined {\n const id = cliConfig?.app?.id\n return id\n}\n\nfunction hasNewAppId(cliConfig: CliConfig) {\n return Boolean(getDeploymentAppId(cliConfig))\n}\n\nfunction hasDeprecatedAppId(cliConfig: CliConfig) {\n return Boolean(getDeprecatedAppId(cliConfig))\n}\n\n/** The one app-id configuration problem to surface, if any. */\nexport type AppIdIssue = 'conflicting-config' | 'deprecated-config'\n\n/**\n * Decides which app-id problem a config has: both the deprecated `app.id` and\n * `deployment.appId` (a conflict), only the deprecated one, or neither. Shared\n * so the real deploy and the dry-run check reach the same verdict.\n * @internal\n */\nexport function resolveAppIdIssue(cliConfig: CliConfig): AppIdIssue | null {\n if (!hasDeprecatedAppId(cliConfig)) return null\n return hasNewAppId(cliConfig) ? 'conflicting-config' : 'deprecated-config'\n}\n\n/**\n * Checks if an SDK app uses the deprecated app.id config & throws a warning if so.\n * @remarks Throws an error if an app uses both deployment.appId and app.id\n * @internal\n */\nexport function checkForDeprecatedAppId({cliConfig, output}: Options): void {\n const issue = resolveAppIdIssue(cliConfig)\n\n // Both configs set: a real deploy can't pick one, so stop here\n if (issue === 'conflicting-config') {\n output.error(\n `${styleText('bold', 'Found both app.id (deprecated) and deployment.appId in your application configuration.')}\n\nPlease remove app.id from your sanity.cli.js or sanity.cli.ts file.`,\n {\n exit:
|
|
1
|
+
{"version":3,"sources":["../../src/util/appId.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type CliConfig, exitCodes, type Output} from '@sanity/cli-core'\n\ninterface Options {\n cliConfig: CliConfig\n output: Output\n}\n\nfunction getDeploymentAppId(cliConfig: CliConfig): string | undefined {\n const id = cliConfig?.deployment?.appId\n return id\n}\n\nfunction getDeprecatedAppId(cliConfig: CliConfig): string | undefined {\n const id = cliConfig?.app?.id\n return id\n}\n\nfunction hasNewAppId(cliConfig: CliConfig) {\n return Boolean(getDeploymentAppId(cliConfig))\n}\n\nfunction hasDeprecatedAppId(cliConfig: CliConfig) {\n return Boolean(getDeprecatedAppId(cliConfig))\n}\n\n/** The one app-id configuration problem to surface, if any. */\nexport type AppIdIssue = 'conflicting-config' | 'deprecated-config'\n\n/**\n * Decides which app-id problem a config has: both the deprecated `app.id` and\n * `deployment.appId` (a conflict), only the deprecated one, or neither. Shared\n * so the real deploy and the dry-run check reach the same verdict.\n * @internal\n */\nexport function resolveAppIdIssue(cliConfig: CliConfig): AppIdIssue | null {\n if (!hasDeprecatedAppId(cliConfig)) return null\n return hasNewAppId(cliConfig) ? 'conflicting-config' : 'deprecated-config'\n}\n\n/**\n * Checks if an SDK app uses the deprecated app.id config & throws a warning if so.\n * @remarks Throws an error if an app uses both deployment.appId and app.id\n * @internal\n */\nexport function checkForDeprecatedAppId({cliConfig, output}: Options): void {\n const issue = resolveAppIdIssue(cliConfig)\n\n // Both configs set: a real deploy can't pick one, so stop here\n if (issue === 'conflicting-config') {\n output.error(\n `${styleText('bold', 'Found both app.id (deprecated) and deployment.appId in your application configuration.')}\n\nPlease remove app.id from your sanity.cli.js or sanity.cli.ts file.`,\n {\n exit: exitCodes.RUNTIME_ERROR,\n },\n )\n }\n\n // Just warn if only the old app ID config is found\n if (issue === 'deprecated-config') {\n output.warn(\n `${styleText('bold', 'The `app.id` config has moved to `deployment.appId`.')}\n\nPlease update \\`sanity.cli.ts\\` or \\`sanity.cli.js\\` and move:\n${styleText('red', `app: {id: \"${getDeprecatedAppId(cliConfig)}\", ... }`)}\nto\n${styleText('green', `deployment: {appId: \"${getDeprecatedAppId(cliConfig)}\", ... }`)}\n`,\n )\n }\n}\n\n/**\n * Get an application's ID\n * @remarks Favors the current implementation (deployment.appId) but will fall back to the deprecated app.id\n * @internal\n */\nexport function getAppId(cliConfig: CliConfig): string | undefined {\n const hasNew = hasNewAppId(cliConfig)\n const hasOld = hasDeprecatedAppId(cliConfig)\n\n if (hasNew) {\n return getDeploymentAppId(cliConfig)\n }\n\n if (hasOld) {\n return getDeprecatedAppId(cliConfig)\n }\n\n return undefined\n}\n"],"names":["styleText","exitCodes","getDeploymentAppId","cliConfig","id","deployment","appId","getDeprecatedAppId","app","hasNewAppId","Boolean","hasDeprecatedAppId","resolveAppIdIssue","checkForDeprecatedAppId","output","issue","error","exit","RUNTIME_ERROR","warn","getAppId","hasNew","hasOld","undefined"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAwBC,SAAS,QAAoB,mBAAkB;AAOvE,SAASC,mBAAmBC,SAAoB;IAC9C,MAAMC,KAAKD,WAAWE,YAAYC;IAClC,OAAOF;AACT;AAEA,SAASG,mBAAmBJ,SAAoB;IAC9C,MAAMC,KAAKD,WAAWK,KAAKJ;IAC3B,OAAOA;AACT;AAEA,SAASK,YAAYN,SAAoB;IACvC,OAAOO,QAAQR,mBAAmBC;AACpC;AAEA,SAASQ,mBAAmBR,SAAoB;IAC9C,OAAOO,QAAQH,mBAAmBJ;AACpC;AAKA;;;;;CAKC,GACD,OAAO,SAASS,kBAAkBT,SAAoB;IACpD,IAAI,CAACQ,mBAAmBR,YAAY,OAAO;IAC3C,OAAOM,YAAYN,aAAa,uBAAuB;AACzD;AAEA;;;;CAIC,GACD,OAAO,SAASU,wBAAwB,EAACV,SAAS,EAAEW,MAAM,EAAU;IAClE,MAAMC,QAAQH,kBAAkBT;IAEhC,+DAA+D;IAC/D,IAAIY,UAAU,sBAAsB;QAClCD,OAAOE,KAAK,CACV,GAAGhB,UAAU,QAAQ,0FAA0F;;mEAElD,CAAC,EAC9D;YACEiB,MAAMhB,UAAUiB,aAAa;QAC/B;IAEJ;IAEA,mDAAmD;IACnD,IAAIH,UAAU,qBAAqB;QACjCD,OAAOK,IAAI,CACT,GAAGnB,UAAU,QAAQ,wDAAwD;;;AAGnF,EAAEA,UAAU,OAAO,CAAC,WAAW,EAAEO,mBAAmBJ,WAAW,QAAQ,CAAC,EAAE;;AAE1E,EAAEH,UAAU,SAAS,CAAC,qBAAqB,EAAEO,mBAAmBJ,WAAW,QAAQ,CAAC,EAAE;AACtF,CAAC;IAEC;AACF;AAEA;;;;CAIC,GACD,OAAO,SAASiB,SAASjB,SAAoB;IAC3C,MAAMkB,SAASZ,YAAYN;IAC3B,MAAMmB,SAASX,mBAAmBR;IAElC,IAAIkB,QAAQ;QACV,OAAOnB,mBAAmBC;IAC5B;IAEA,IAAImB,QAAQ;QACV,OAAOf,mBAAmBJ;IAC5B;IAEA,OAAOoB;AACT"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { pluralize } from './pluralize.js';
|
|
2
|
+
const MS_IN = {
|
|
3
|
+
day: 86_400_000,
|
|
4
|
+
hour: 3_600_000,
|
|
5
|
+
minute: 60_000,
|
|
6
|
+
month: 2_592_000_000,
|
|
7
|
+
second: 1000,
|
|
8
|
+
week: 604_800_000,
|
|
9
|
+
year: 31_536_000_000
|
|
10
|
+
};
|
|
11
|
+
/** Largest unit first, so the first unit the duration fills is the one we report. */ const UNITS = [
|
|
12
|
+
{
|
|
13
|
+
ms: MS_IN.year,
|
|
14
|
+
unit: 'year'
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
ms: MS_IN.month,
|
|
18
|
+
unit: 'month'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
ms: MS_IN.week,
|
|
22
|
+
unit: 'week'
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
ms: MS_IN.day,
|
|
26
|
+
unit: 'day'
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
ms: MS_IN.hour,
|
|
30
|
+
unit: 'hour'
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
ms: MS_IN.minute,
|
|
34
|
+
unit: 'minute'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
ms: MS_IN.second,
|
|
38
|
+
unit: 'second'
|
|
39
|
+
}
|
|
40
|
+
];
|
|
41
|
+
const relativeTime = new Intl.RelativeTimeFormat('en', {
|
|
42
|
+
numeric: 'always'
|
|
43
|
+
});
|
|
44
|
+
const DATE_ONLY_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
45
|
+
function pad(value, length = 2) {
|
|
46
|
+
return String(value).padStart(length, '0');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Returns the coarsest unit the elapsed time fills and the rounded number of those
|
|
50
|
+
* units, or `undefined` below a second.
|
|
51
|
+
*
|
|
52
|
+
* Rounding can land the value on the boundary of the next unit up, so we promote
|
|
53
|
+
* rather than report `60 minutes` where `1 hour` is meant. Units aren't all whole
|
|
54
|
+
* multiples of each other, so the boundary is the rounded count we'd display, which
|
|
55
|
+
* is why 25+ days reads as `1 month` rather than `4 weeks`.
|
|
56
|
+
*/ function selectUnit(elapsed) {
|
|
57
|
+
let index = UNITS.findIndex(({ ms })=>elapsed >= ms);
|
|
58
|
+
if (index === -1) return undefined;
|
|
59
|
+
while(index > 0 && Math.round(elapsed / UNITS[index].ms) >= Math.round(UNITS[index - 1].ms / UNITS[index].ms)){
|
|
60
|
+
index -= 1;
|
|
61
|
+
}
|
|
62
|
+
const { ms, unit } = UNITS[index];
|
|
63
|
+
return {
|
|
64
|
+
unit,
|
|
65
|
+
value: Math.round(elapsed / ms)
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Formats a timestamp as `YYYY-MM-DD HH:mm:ss` in the local time zone. Unparseable
|
|
70
|
+
* timestamps are returned as-is, so a bad value from the API doesn't fail the command.
|
|
71
|
+
*
|
|
72
|
+
* @param timestamp - An ISO 8601 timestamp
|
|
73
|
+
* @internal
|
|
74
|
+
*/ export function formatDateTime(timestamp) {
|
|
75
|
+
const date = new Date(timestamp);
|
|
76
|
+
if (!Number.isFinite(date.getTime())) return timestamp;
|
|
77
|
+
const day = `${pad(date.getFullYear(), 4)}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
78
|
+
const time = `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
|
|
79
|
+
return `${day} ${time}`;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Formats a duration in milliseconds as an approximate, human readable length of
|
|
83
|
+
* time, eg `less than a minute`, `5 minutes` or `2 days`.
|
|
84
|
+
*
|
|
85
|
+
* @param ms - The duration in milliseconds
|
|
86
|
+
* @internal
|
|
87
|
+
*/ export function formatDuration(ms) {
|
|
88
|
+
if (!Number.isFinite(ms)) return '';
|
|
89
|
+
const selected = selectUnit(Math.abs(ms));
|
|
90
|
+
if (!selected || selected.unit === 'second') return 'less than a minute';
|
|
91
|
+
return `${selected.value} ${pluralize(selected.unit, selected.value)}`;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Formats a date relative to now, eg `2 days ago` or `in 3 hours`.
|
|
95
|
+
*
|
|
96
|
+
* @param date - The date to describe
|
|
97
|
+
* @param now - The reference point to compare against, defaults to the current time
|
|
98
|
+
* @internal
|
|
99
|
+
*/ export function formatTimeAgo(date, now = Date.now()) {
|
|
100
|
+
const delta = date.getTime() - now;
|
|
101
|
+
if (!Number.isFinite(delta)) return '';
|
|
102
|
+
const selected = selectUnit(Math.abs(delta));
|
|
103
|
+
if (!selected) return 'just now';
|
|
104
|
+
return relativeTime.format(delta < 0 ? -selected.value : selected.value, selected.unit);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Parses a `YYYY-MM-DD` date into a `Date` at local midnight. Returns `undefined`
|
|
108
|
+
* for anything that isn't a real calendar date in that exact format.
|
|
109
|
+
*
|
|
110
|
+
* @param value - The date string to parse
|
|
111
|
+
* @internal
|
|
112
|
+
*/ export function parseDateOnly(value) {
|
|
113
|
+
const match = DATE_ONLY_PATTERN.exec(value);
|
|
114
|
+
if (!match) return undefined;
|
|
115
|
+
const year = Number(match[1]);
|
|
116
|
+
const month = Number(match[2]);
|
|
117
|
+
const day = Number(match[3]);
|
|
118
|
+
const date = new Date(year, month - 1, day);
|
|
119
|
+
// `new Date(2024, 1, 31)` silently rolls over into March, so reject anything
|
|
120
|
+
// that didn't survive the round trip
|
|
121
|
+
const isRoundTrip = date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
|
|
122
|
+
return isRoundTrip ? date : undefined;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
//# sourceMappingURL=dates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/dates.ts"],"sourcesContent":["import {pluralize} from './pluralize.js'\n\nconst MS_IN = {\n day: 86_400_000,\n hour: 3_600_000,\n minute: 60_000,\n month: 2_592_000_000, // 30 days\n second: 1000,\n week: 604_800_000,\n year: 31_536_000_000, // 365 days\n} as const\n\n/** Largest unit first, so the first unit the duration fills is the one we report. */\nconst UNITS: {ms: number; unit: Intl.RelativeTimeFormatUnit}[] = [\n {ms: MS_IN.year, unit: 'year'},\n {ms: MS_IN.month, unit: 'month'},\n {ms: MS_IN.week, unit: 'week'},\n {ms: MS_IN.day, unit: 'day'},\n {ms: MS_IN.hour, unit: 'hour'},\n {ms: MS_IN.minute, unit: 'minute'},\n {ms: MS_IN.second, unit: 'second'},\n]\n\nconst relativeTime = new Intl.RelativeTimeFormat('en', {numeric: 'always'})\n\nconst DATE_ONLY_PATTERN = /^(\\d{4})-(\\d{2})-(\\d{2})$/\n\nfunction pad(value: number, length = 2): string {\n return String(value).padStart(length, '0')\n}\n\n/**\n * Returns the coarsest unit the elapsed time fills and the rounded number of those\n * units, or `undefined` below a second.\n *\n * Rounding can land the value on the boundary of the next unit up, so we promote\n * rather than report `60 minutes` where `1 hour` is meant. Units aren't all whole\n * multiples of each other, so the boundary is the rounded count we'd display, which\n * is why 25+ days reads as `1 month` rather than `4 weeks`.\n */\nfunction selectUnit(\n elapsed: number,\n): {unit: Intl.RelativeTimeFormatUnit; value: number} | undefined {\n let index = UNITS.findIndex(({ms}) => elapsed >= ms)\n if (index === -1) return undefined\n\n while (\n index > 0 &&\n Math.round(elapsed / UNITS[index].ms) >= Math.round(UNITS[index - 1].ms / UNITS[index].ms)\n ) {\n index -= 1\n }\n\n const {ms, unit} = UNITS[index]\n return {unit, value: Math.round(elapsed / ms)}\n}\n\n/**\n * Formats a timestamp as `YYYY-MM-DD HH:mm:ss` in the local time zone. Unparseable\n * timestamps are returned as-is, so a bad value from the API doesn't fail the command.\n *\n * @param timestamp - An ISO 8601 timestamp\n * @internal\n */\nexport function formatDateTime(timestamp: string): string {\n const date = new Date(timestamp)\n if (!Number.isFinite(date.getTime())) return timestamp\n\n const day = `${pad(date.getFullYear(), 4)}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`\n const time = `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`\n return `${day} ${time}`\n}\n\n/**\n * Formats a duration in milliseconds as an approximate, human readable length of\n * time, eg `less than a minute`, `5 minutes` or `2 days`.\n *\n * @param ms - The duration in milliseconds\n * @internal\n */\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms)) return ''\n\n const selected = selectUnit(Math.abs(ms))\n if (!selected || selected.unit === 'second') return 'less than a minute'\n\n return `${selected.value} ${pluralize(selected.unit, selected.value)}`\n}\n\n/**\n * Formats a date relative to now, eg `2 days ago` or `in 3 hours`.\n *\n * @param date - The date to describe\n * @param now - The reference point to compare against, defaults to the current time\n * @internal\n */\nexport function formatTimeAgo(date: Date, now: number = Date.now()): string {\n const delta = date.getTime() - now\n if (!Number.isFinite(delta)) return ''\n\n const selected = selectUnit(Math.abs(delta))\n if (!selected) return 'just now'\n\n return relativeTime.format(delta < 0 ? -selected.value : selected.value, selected.unit)\n}\n\n/**\n * Parses a `YYYY-MM-DD` date into a `Date` at local midnight. Returns `undefined`\n * for anything that isn't a real calendar date in that exact format.\n *\n * @param value - The date string to parse\n * @internal\n */\nexport function parseDateOnly(value: string): Date | undefined {\n const match = DATE_ONLY_PATTERN.exec(value)\n if (!match) return undefined\n\n const year = Number(match[1])\n const month = Number(match[2])\n const day = Number(match[3])\n const date = new Date(year, month - 1, day)\n\n // `new Date(2024, 1, 31)` silently rolls over into March, so reject anything\n // that didn't survive the round trip\n const isRoundTrip =\n date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day\n\n return isRoundTrip ? date : undefined\n}\n"],"names":["pluralize","MS_IN","day","hour","minute","month","second","week","year","UNITS","ms","unit","relativeTime","Intl","RelativeTimeFormat","numeric","DATE_ONLY_PATTERN","pad","value","length","String","padStart","selectUnit","elapsed","index","findIndex","undefined","Math","round","formatDateTime","timestamp","date","Date","Number","isFinite","getTime","getFullYear","getMonth","getDate","time","getHours","getMinutes","getSeconds","formatDuration","selected","abs","formatTimeAgo","now","delta","format","parseDateOnly","match","exec","isRoundTrip"],"mappings":"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"}
|
|
@@ -1,24 +1,14 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
3
2
|
import { readPackageJson } from '@sanity/cli-core';
|
|
4
|
-
import { packageDirectory } from 'package-directory';
|
|
5
3
|
/**
|
|
6
4
|
* Get the version of the `@sanity/cli` package.
|
|
7
5
|
*
|
|
8
6
|
* @internal
|
|
9
7
|
* @returns The version of the `@sanity/cli` package.
|
|
10
8
|
*/ export async function getCliVersion() {
|
|
11
|
-
// using the meta.url will resolve to the code running from the cli
|
|
12
|
-
// this will find the package.json in cli package.
|
|
13
|
-
const cliPath = await packageDirectory({
|
|
14
|
-
cwd: fileURLToPath(import.meta.url)
|
|
15
|
-
});
|
|
16
|
-
if (!cliPath) {
|
|
17
|
-
throw new Error('Unable to resolve root of @sanity/cli module');
|
|
18
|
-
}
|
|
19
9
|
let pkg;
|
|
20
10
|
try {
|
|
21
|
-
pkg = await readPackageJson(path.join(
|
|
11
|
+
pkg = await readPackageJson(path.join(import.meta.dirname, '..', '..', 'package.json'));
|
|
22
12
|
} catch (err) {
|
|
23
13
|
throw new Error(`Unable to read @sanity/cli/package.json: ${err.message}`, {
|
|
24
14
|
cause: err
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/getCliVersion.ts"],"sourcesContent":["import path from 'node:path'\
|
|
1
|
+
{"version":3,"sources":["../../src/util/getCliVersion.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {type PackageJson, readPackageJson} from '@sanity/cli-core'\n\n/**\n * Get the version of the `@sanity/cli` package.\n *\n * @internal\n * @returns The version of the `@sanity/cli` package.\n */\nexport async function getCliVersion(): Promise<string> {\n let pkg: PackageJson | undefined\n try {\n pkg = await readPackageJson(path.join(import.meta.dirname, '..', '..', 'package.json'))\n } catch (err) {\n throw new Error(`Unable to read @sanity/cli/package.json: ${(err as Error).message}`, {\n cause: err,\n })\n }\n\n return pkg.version\n}\n"],"names":["path","readPackageJson","getCliVersion","pkg","join","dirname","err","Error","message","cause","version"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,SAA0BC,eAAe,QAAO,mBAAkB;AAElE;;;;;CAKC,GACD,OAAO,eAAeC;IACpB,IAAIC;IACJ,IAAI;QACFA,MAAM,MAAMF,gBAAgBD,KAAKI,IAAI,CAAC,YAAYC,OAAO,EAAE,MAAM,MAAM;IACzE,EAAE,OAAOC,KAAK;QACZ,MAAM,IAAIC,MAAM,CAAC,yCAAyC,EAAE,AAACD,IAAcE,OAAO,EAAE,EAAE;YACpFC,OAAOH;QACT;IACF;IAEA,OAAOH,IAAIO,OAAO;AACpB"}
|