@sanity/cli 6.1.3 → 6.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -79
- package/dist/actions/auth/ensureAuthenticated.js +61 -0
- package/dist/actions/auth/ensureAuthenticated.js.map +1 -0
- package/dist/actions/debug/gatherDebugInfo.js +10 -12
- package/dist/actions/debug/gatherDebugInfo.js.map +1 -1
- package/dist/actions/debug/types.js.map +1 -1
- package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js +19 -15
- package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js.map +1 -1
- package/dist/actions/manifest/types.js.map +1 -1
- package/dist/actions/schema/deploySchemas.js +7 -1
- package/dist/actions/schema/deploySchemas.js.map +1 -1
- package/dist/actions/schema/extractSanityWorkspace.worker.js +9 -1
- package/dist/actions/schema/extractSanityWorkspace.worker.js.map +1 -1
- package/dist/actions/schema/updateWorkspaceSchema.js +2 -2
- package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -1
- package/dist/commands/debug.js +17 -6
- package/dist/commands/debug.js.map +1 -1
- package/dist/commands/init.js +28 -36
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp/configure.js +40 -12
- package/dist/commands/mcp/configure.js.map +1 -1
- package/dist/errors/LoginError.js +11 -0
- package/dist/errors/LoginError.js.map +1 -0
- package/dist/util/getErrorMessage.js +9 -0
- package/dist/util/getErrorMessage.js.map +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { getCliToken } from '@sanity/cli-core';
|
|
2
|
+
import { isHttpError } from '@sanity/client';
|
|
3
|
+
import { LoginError } from '../../errors/LoginError.js';
|
|
4
|
+
import { getCliUser } from '../../services/user.js';
|
|
5
|
+
import { getErrorMessage } from '../../util/getErrorMessage.js';
|
|
6
|
+
import { login } from './login/login.js';
|
|
7
|
+
/**
|
|
8
|
+
* Ensure the user is authenticated. Validates the current token via /users/me
|
|
9
|
+
* and triggers interactive login if the token is missing or invalid.
|
|
10
|
+
*
|
|
11
|
+
* @returns The authenticated user.
|
|
12
|
+
* @throws LoginError if interactive login fails or is cancelled.
|
|
13
|
+
* @throws Error if a network/server error occurs during validation.
|
|
14
|
+
* @internal
|
|
15
|
+
*/ export async function ensureAuthenticated(options) {
|
|
16
|
+
const user = await validateSession();
|
|
17
|
+
if (user) return user;
|
|
18
|
+
try {
|
|
19
|
+
await login({
|
|
20
|
+
output: options.output,
|
|
21
|
+
telemetry: options.telemetry
|
|
22
|
+
});
|
|
23
|
+
} catch (cause) {
|
|
24
|
+
throw new LoginError(getErrorMessage(cause), {
|
|
25
|
+
cause
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
return await getCliUser();
|
|
30
|
+
} catch (cause) {
|
|
31
|
+
if (isHttpError(cause) && (cause.statusCode === 401 || cause.statusCode === 403)) {
|
|
32
|
+
throw new LoginError(`Login succeeded but failed to verify session: ${getErrorMessage(cause)}`, {
|
|
33
|
+
cause
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
throw cause;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Validate the current CLI auth token by calling /users/me.
|
|
41
|
+
*
|
|
42
|
+
* Returns null only for auth failures (401/403). Re-throws network errors,
|
|
43
|
+
* timeouts, and server errors so callers can handle them appropriately
|
|
44
|
+
* instead of triggering an unnecessary re-login prompt.
|
|
45
|
+
*
|
|
46
|
+
* @returns The authenticated user if valid, null if invalid/missing.
|
|
47
|
+
* @internal
|
|
48
|
+
*/ export async function validateSession() {
|
|
49
|
+
const token = await getCliToken();
|
|
50
|
+
if (!token) return null;
|
|
51
|
+
try {
|
|
52
|
+
return await getCliUser();
|
|
53
|
+
} catch (error) {
|
|
54
|
+
if (isHttpError(error) && (error.statusCode === 401 || error.statusCode === 403)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=ensureAuthenticated.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/auth/ensureAuthenticated.ts"],"sourcesContent":["import {\n type CLITelemetryStore,\n getCliToken,\n type Output,\n type SanityOrgUser,\n} from '@sanity/cli-core'\nimport {isHttpError} from '@sanity/client'\n\nimport {LoginError} from '../../errors/LoginError.js'\nimport {getCliUser} from '../../services/user.js'\nimport {getErrorMessage} from '../../util/getErrorMessage.js'\nimport {login} from './login/login.js'\n\n/**\n * Ensure the user is authenticated. Validates the current token via /users/me\n * and triggers interactive login if the token is missing or invalid.\n *\n * @returns The authenticated user.\n * @throws LoginError if interactive login fails or is cancelled.\n * @throws Error if a network/server error occurs during validation.\n * @internal\n */\nexport async function ensureAuthenticated(options: {\n output: Output\n telemetry: CLITelemetryStore\n}): Promise<SanityOrgUser> {\n const user = await validateSession()\n if (user) return user\n\n try {\n await login({output: options.output, telemetry: options.telemetry})\n } catch (cause) {\n throw new LoginError(getErrorMessage(cause), {cause})\n }\n\n try {\n return await getCliUser()\n } catch (cause) {\n if (isHttpError(cause) && (cause.statusCode === 401 || cause.statusCode === 403)) {\n throw new LoginError(\n `Login succeeded but failed to verify session: ${getErrorMessage(cause)}`,\n {cause},\n )\n }\n throw cause\n }\n}\n\n/**\n * Validate the current CLI auth token by calling /users/me.\n *\n * Returns null only for auth failures (401/403). Re-throws network errors,\n * timeouts, and server errors so callers can handle them appropriately\n * instead of triggering an unnecessary re-login prompt.\n *\n * @returns The authenticated user if valid, null if invalid/missing.\n * @internal\n */\nexport async function validateSession(): Promise<SanityOrgUser | null> {\n const token = await getCliToken()\n if (!token) return null\n\n try {\n return await getCliUser()\n } catch (error) {\n if (isHttpError(error) && (error.statusCode === 401 || error.statusCode === 403)) {\n return null\n }\n throw error\n }\n}\n"],"names":["getCliToken","isHttpError","LoginError","getCliUser","getErrorMessage","login","ensureAuthenticated","options","user","validateSession","output","telemetry","cause","statusCode","token","error"],"mappings":"AAAA,SAEEA,WAAW,QAGN,mBAAkB;AACzB,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,UAAU,QAAO,6BAA4B;AACrD,SAAQC,UAAU,QAAO,yBAAwB;AACjD,SAAQC,eAAe,QAAO,gCAA+B;AAC7D,SAAQC,KAAK,QAAO,mBAAkB;AAEtC;;;;;;;;CAQC,GACD,OAAO,eAAeC,oBAAoBC,OAGzC;IACC,MAAMC,OAAO,MAAMC;IACnB,IAAID,MAAM,OAAOA;IAEjB,IAAI;QACF,MAAMH,MAAM;YAACK,QAAQH,QAAQG,MAAM;YAAEC,WAAWJ,QAAQI,SAAS;QAAA;IACnE,EAAE,OAAOC,OAAO;QACd,MAAM,IAAIV,WAAWE,gBAAgBQ,QAAQ;YAACA;QAAK;IACrD;IAEA,IAAI;QACF,OAAO,MAAMT;IACf,EAAE,OAAOS,OAAO;QACd,IAAIX,YAAYW,UAAWA,CAAAA,MAAMC,UAAU,KAAK,OAAOD,MAAMC,UAAU,KAAK,GAAE,GAAI;YAChF,MAAM,IAAIX,WACR,CAAC,8CAA8C,EAAEE,gBAAgBQ,QAAQ,EACzE;gBAACA;YAAK;QAEV;QACA,MAAMA;IACR;AACF;AAEA;;;;;;;;;CASC,GACD,OAAO,eAAeH;IACpB,MAAMK,QAAQ,MAAMd;IACpB,IAAI,CAACc,OAAO,OAAO;IAEnB,IAAI;QACF,OAAO,MAAMX;IACf,EAAE,OAAOY,OAAO;QACd,IAAId,YAAYc,UAAWA,CAAAA,MAAMF,UAAU,KAAK,OAAOE,MAAMF,UAAU,KAAK,GAAE,GAAI;YAChF,OAAO;QACT;QACA,MAAME;IACR;AACF"}
|
|
@@ -8,7 +8,7 @@ export async function gatherDebugInfo(options) {
|
|
|
8
8
|
const [auth, globalConfig, projectConfigResult, versions] = await Promise.all([
|
|
9
9
|
gatherAuthInfo(includeSecrets),
|
|
10
10
|
gatherGlobalConfig(),
|
|
11
|
-
gatherProjectConfig(cliConfig),
|
|
11
|
+
cliConfig ? gatherProjectConfig(cliConfig) : undefined,
|
|
12
12
|
gatherVersionsInfo(projectRoot)
|
|
13
13
|
]);
|
|
14
14
|
// Gather user and project info that depend on auth
|
|
@@ -35,18 +35,16 @@ async function gatherAuthInfo(includeSecrets) {
|
|
|
35
35
|
function gatherGlobalConfig() {
|
|
36
36
|
return getUserConfig().all;
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (!config.api?.projectId) {
|
|
42
|
-
return new Error('Missing required "api.projectId" key');
|
|
43
|
-
}
|
|
44
|
-
return config;
|
|
45
|
-
} catch (error) {
|
|
46
|
-
return error instanceof Error ? error : new Error('Failed to load project config');
|
|
38
|
+
function gatherProjectConfig(cliConfig) {
|
|
39
|
+
if (!cliConfig.api?.projectId) {
|
|
40
|
+
return new Error('Missing required "api.projectId" key');
|
|
47
41
|
}
|
|
42
|
+
return cliConfig;
|
|
48
43
|
}
|
|
49
44
|
async function gatherVersionsInfo(projectRoot) {
|
|
45
|
+
if (!projectRoot) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
50
48
|
try {
|
|
51
49
|
return await findSanityModulesVersions({
|
|
52
50
|
cwd: projectRoot.directory
|
|
@@ -63,7 +61,7 @@ async function gatherUserInfo(projectConfig, hasToken) {
|
|
|
63
61
|
/**
|
|
64
62
|
* If the project config has a project ID, get the user for the project
|
|
65
63
|
* Otherwise, get the user for the global client
|
|
66
|
-
*/ const userInfo = projectConfig instanceof Error || !projectConfig.api?.projectId ? await getCliUser() : await getProjectUser(projectConfig.api.projectId);
|
|
64
|
+
*/ const userInfo = !projectConfig || projectConfig instanceof Error || !projectConfig.api?.projectId ? await getCliUser() : await getProjectUser(projectConfig.api.projectId);
|
|
67
65
|
return {
|
|
68
66
|
email: userInfo.email,
|
|
69
67
|
id: userInfo.id,
|
|
@@ -74,7 +72,7 @@ async function gatherUserInfo(projectConfig, hasToken) {
|
|
|
74
72
|
}
|
|
75
73
|
}
|
|
76
74
|
async function gatherProjectInfo(projectConfig, hasToken, user) {
|
|
77
|
-
if (!hasToken || projectConfig instanceof Error) {
|
|
75
|
+
if (!hasToken || !projectConfig || projectConfig instanceof Error) {
|
|
78
76
|
return null;
|
|
79
77
|
}
|
|
80
78
|
const projectId = projectConfig.api?.projectId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/debug/gatherDebugInfo.ts"],"sourcesContent":["import {type CliConfig, getCliToken, getUserConfig, type ProjectRootResult} from '@sanity/cli-core'\n\nimport {getProjectById} from '../../services/projects.js'\nimport {getCliUser, getProjectUser} from '../../services/user.js'\nimport {findSanityModulesVersions} from '../versions/findSanityModulesVersions.js'\nimport {type ModuleVersionResult} from '../versions/types.js'\nimport {\n type AuthInfo,\n type DebugInfo,\n type DebugInfoOptions,\n type ProjectInfo,\n type UserInfo,\n} from './types.js'\n\nexport async function gatherDebugInfo(options: DebugInfoOptions): Promise<DebugInfo> {\n const {cliConfig, includeSecrets, projectRoot} = options\n\n // Gather all info in parallel where possible\n const [auth, globalConfig, projectConfigResult, versions] = await Promise.all([\n gatherAuthInfo(includeSecrets),\n gatherGlobalConfig(),\n gatherProjectConfig(cliConfig),\n gatherVersionsInfo(projectRoot),\n ])\n\n // Gather user and project info that depend on auth\n const user = await gatherUserInfo(projectConfigResult, auth.hasToken)\n const project = await gatherProjectInfo(projectConfigResult, auth.hasToken, user)\n\n return {\n auth,\n globalConfig,\n project,\n projectConfig: projectConfigResult,\n user,\n versions,\n }\n}\n\nasync function gatherAuthInfo(includeSecrets: boolean): Promise<AuthInfo> {\n const token = await getCliToken()\n const hasToken = Boolean(token)\n\n return {\n authToken: includeSecrets && token ? token : '<redacted>',\n hasToken,\n userType: 'normal',\n }\n}\n\nfunction gatherGlobalConfig(): Record<string, unknown> {\n return getUserConfig().all\n}\n\
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/debug/gatherDebugInfo.ts"],"sourcesContent":["import {type CliConfig, getCliToken, getUserConfig, type ProjectRootResult} from '@sanity/cli-core'\n\nimport {getProjectById} from '../../services/projects.js'\nimport {getCliUser, getProjectUser} from '../../services/user.js'\nimport {findSanityModulesVersions} from '../versions/findSanityModulesVersions.js'\nimport {type ModuleVersionResult} from '../versions/types.js'\nimport {\n type AuthInfo,\n type DebugInfo,\n type DebugInfoOptions,\n type ProjectInfo,\n type UserInfo,\n} from './types.js'\n\nexport async function gatherDebugInfo(options: DebugInfoOptions): Promise<DebugInfo> {\n const {cliConfig, includeSecrets, projectRoot} = options\n\n // Gather all info in parallel where possible\n const [auth, globalConfig, projectConfigResult, versions] = await Promise.all([\n gatherAuthInfo(includeSecrets),\n gatherGlobalConfig(),\n cliConfig ? gatherProjectConfig(cliConfig) : undefined,\n gatherVersionsInfo(projectRoot),\n ])\n\n // Gather user and project info that depend on auth\n const user = await gatherUserInfo(projectConfigResult, auth.hasToken)\n const project = await gatherProjectInfo(projectConfigResult, auth.hasToken, user)\n\n return {\n auth,\n globalConfig,\n project,\n projectConfig: projectConfigResult,\n user,\n versions,\n }\n}\n\nasync function gatherAuthInfo(includeSecrets: boolean): Promise<AuthInfo> {\n const token = await getCliToken()\n const hasToken = Boolean(token)\n\n return {\n authToken: includeSecrets && token ? token : '<redacted>',\n hasToken,\n userType: 'normal',\n }\n}\n\nfunction gatherGlobalConfig(): Record<string, unknown> {\n return getUserConfig().all\n}\n\nfunction gatherProjectConfig(cliConfig: CliConfig): CliConfig | Error {\n if (!cliConfig.api?.projectId) {\n return new Error('Missing required \"api.projectId\" key')\n }\n\n return cliConfig\n}\n\nasync function gatherVersionsInfo(\n projectRoot: ProjectRootResult | undefined,\n): Promise<ModuleVersionResult[] | undefined> {\n if (!projectRoot) {\n return undefined\n }\n\n try {\n return await findSanityModulesVersions({cwd: projectRoot.directory})\n } catch {\n return []\n }\n}\n\nasync function gatherUserInfo(\n projectConfig: CliConfig | Error | undefined,\n hasToken: boolean,\n): Promise<Error | UserInfo | null> {\n if (!hasToken) {\n return new Error('Not logged in')\n }\n\n try {\n /**\n * If the project config has a project ID, get the user for the project\n * Otherwise, get the user for the global client\n */\n const userInfo =\n !projectConfig || projectConfig instanceof Error || !projectConfig.api?.projectId\n ? await getCliUser()\n : await getProjectUser(projectConfig.api.projectId)\n\n return {\n email: userInfo.email,\n id: userInfo.id,\n name: userInfo.name,\n }\n } catch (error) {\n return error instanceof Error ? error : new Error('Failed to fetch user info')\n }\n}\n\nasync function gatherProjectInfo(\n projectConfig: CliConfig | Error | undefined,\n hasToken: boolean,\n user: Error | UserInfo | null,\n): Promise<Error | ProjectInfo | null> {\n if (!hasToken || !projectConfig || projectConfig instanceof Error) {\n return null\n }\n\n const projectId = projectConfig.api?.projectId\n if (!projectId) {\n return null\n }\n\n try {\n const projectInfo = await getProjectById(projectId)\n\n if (!projectInfo) {\n return new Error(`Project specified in configuration (${projectId}) does not exist in API`)\n }\n\n const userId = user instanceof Error || !user ? null : user.id\n const member = (projectInfo.members || []).find((member) => member.id === userId)\n\n return {\n displayName: projectInfo.displayName,\n id: projectId,\n // @ts-expect-error - Incorrect type definition in @sanity/client\n userRoles: member && member.roles ? member.roles.map((role) => role.name) : ['<none>'],\n }\n } catch (error) {\n return error instanceof Error ? error : new Error('Failed to fetch project info')\n }\n}\n"],"names":["getCliToken","getUserConfig","getProjectById","getCliUser","getProjectUser","findSanityModulesVersions","gatherDebugInfo","options","cliConfig","includeSecrets","projectRoot","auth","globalConfig","projectConfigResult","versions","Promise","all","gatherAuthInfo","gatherGlobalConfig","gatherProjectConfig","undefined","gatherVersionsInfo","user","gatherUserInfo","hasToken","project","gatherProjectInfo","projectConfig","token","Boolean","authToken","userType","api","projectId","Error","cwd","directory","userInfo","email","id","name","error","projectInfo","userId","member","members","find","displayName","userRoles","roles","map","role"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/debug/types.ts"],"sourcesContent":["import {type CliConfig, type ProjectRootResult} from '@sanity/cli-core'\n\nimport {type ModuleVersionResult} from '../versions/types.js'\n\nexport interface DebugInfoOptions {\n cliConfig: CliConfig\n includeSecrets: boolean\n projectRoot: ProjectRootResult\n}\n\nexport interface UserInfo {\n email: string\n id: string\n name: string\n}\n\nexport interface ProjectInfo {\n displayName: string\n id: string\n userRoles: string[]\n}\n\nexport interface AuthInfo {\n authToken: string\n hasToken: boolean\n userType: string\n}\n\nexport interface DebugInfo {\n auth: AuthInfo\n globalConfig: Record<string, unknown>\n project: Error | ProjectInfo | null\n projectConfig: CliConfig | Error\n user: Error | UserInfo | null\n versions: ModuleVersionResult[]\n}\n"],"names":[],"mappings":"AA4BA,WAOC"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/debug/types.ts"],"sourcesContent":["import {type CliConfig, type ProjectRootResult} from '@sanity/cli-core'\n\nimport {type ModuleVersionResult} from '../versions/types.js'\n\nexport interface DebugInfoOptions {\n cliConfig: CliConfig | undefined\n includeSecrets: boolean\n projectRoot: ProjectRootResult | undefined\n}\n\nexport interface UserInfo {\n email: string\n id: string\n name: string\n}\n\nexport interface ProjectInfo {\n displayName: string\n id: string\n userRoles: string[]\n}\n\nexport interface AuthInfo {\n authToken: string\n hasToken: boolean\n userType: string\n}\n\nexport interface DebugInfo {\n auth: AuthInfo\n globalConfig: Record<string, unknown>\n project: Error | ProjectInfo | null\n projectConfig: CliConfig | Error | undefined\n user: Error | UserInfo | null\n versions: ModuleVersionResult[] | undefined\n}\n"],"names":[],"mappings":"AA4BA,WAOC"}
|
|
@@ -19,12 +19,23 @@ async function main() {
|
|
|
19
19
|
if (workspaces.length === 0) {
|
|
20
20
|
throw new Error('No workspaces found');
|
|
21
21
|
}
|
|
22
|
+
// Extract manifest data (including ManifestSchemaType[]) once, while Schema objects are
|
|
23
|
+
// still live. Both writeWorkspaceToDist and updateWorkspacesSchemas consume the result.
|
|
24
|
+
const workspaceManifests = await extractWorkspaceManifest(workspaces, workDir);
|
|
25
|
+
const schemaInputs = workspaceManifests.map((manifest)=>({
|
|
26
|
+
dataset: manifest.dataset,
|
|
27
|
+
manifestSchema: manifest.schema,
|
|
28
|
+
name: manifest.name,
|
|
29
|
+
projectId: manifest.projectId,
|
|
30
|
+
title: manifest.title
|
|
31
|
+
}));
|
|
22
32
|
debug('Handling deployment for %s', isExternal ? 'external' : 'internal');
|
|
23
33
|
let studioManifest = null;
|
|
24
34
|
if (isExternal) {
|
|
25
35
|
;
|
|
26
36
|
[studioManifest] = await handleExternalDeployment({
|
|
27
37
|
projectId,
|
|
38
|
+
schemaInputs,
|
|
28
39
|
schemaRequired,
|
|
29
40
|
verbose,
|
|
30
41
|
workDir,
|
|
@@ -35,8 +46,10 @@ async function main() {
|
|
|
35
46
|
[studioManifest] = await handleInternalDeployment({
|
|
36
47
|
outPath,
|
|
37
48
|
projectId,
|
|
49
|
+
schemaInputs,
|
|
38
50
|
verbose,
|
|
39
51
|
workDir,
|
|
52
|
+
workspaceManifests,
|
|
40
53
|
workspaces
|
|
41
54
|
});
|
|
42
55
|
}
|
|
@@ -54,20 +67,11 @@ async function main() {
|
|
|
54
67
|
});
|
|
55
68
|
}
|
|
56
69
|
}
|
|
57
|
-
async function writeWorkspaceToDist({ outPath, workDir, workspaces }) {
|
|
58
|
-
// Get the create manifest workspace
|
|
59
|
-
const workspaceManifests = await extractWorkspaceManifest(workspaces, workDir);
|
|
60
|
-
await writeManifestFile({
|
|
61
|
-
outPath,
|
|
62
|
-
workDir,
|
|
63
|
-
workspaceManifests
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
70
|
/**
|
|
67
71
|
* External deployments:
|
|
68
72
|
* 1. Update the workspace schemas to the /schemas endpoint IF --schema-required is passed
|
|
69
73
|
* 2. Update server-side schemas
|
|
70
|
-
*/ async function handleExternalDeployment({ projectId, schemaRequired, verbose, workDir, workspaces }) {
|
|
74
|
+
*/ async function handleExternalDeployment({ projectId, schemaInputs, schemaRequired, verbose, workDir, workspaces }) {
|
|
71
75
|
const [studioManifest] = await Promise.all([
|
|
72
76
|
uploadSchemaToLexicon({
|
|
73
77
|
projectId,
|
|
@@ -77,7 +81,7 @@ async function writeWorkspaceToDist({ outPath, workDir, workspaces }) {
|
|
|
77
81
|
}),
|
|
78
82
|
schemaRequired ? updateWorkspacesSchemas({
|
|
79
83
|
verbose,
|
|
80
|
-
workspaces
|
|
84
|
+
workspaces: schemaInputs
|
|
81
85
|
}) : undefined
|
|
82
86
|
]);
|
|
83
87
|
return [
|
|
@@ -92,7 +96,7 @@ async function writeWorkspaceToDist({ outPath, workDir, workspaces }) {
|
|
|
92
96
|
* 3. Update server-side schemas
|
|
93
97
|
*
|
|
94
98
|
* @param workspaces - The workspaces to deploy
|
|
95
|
-
*/ async function handleInternalDeployment({ outPath, projectId, verbose, workDir, workspaces }) {
|
|
99
|
+
*/ async function handleInternalDeployment({ outPath, projectId, schemaInputs, verbose, workDir, workspaceManifests, workspaces }) {
|
|
96
100
|
const [studioManifest] = await Promise.all([
|
|
97
101
|
uploadSchemaToLexicon({
|
|
98
102
|
projectId,
|
|
@@ -100,15 +104,15 @@ async function writeWorkspaceToDist({ outPath, workDir, workspaces }) {
|
|
|
100
104
|
workDir,
|
|
101
105
|
workspaces
|
|
102
106
|
}),
|
|
103
|
-
|
|
107
|
+
writeManifestFile({
|
|
104
108
|
outPath,
|
|
105
109
|
workDir,
|
|
106
|
-
|
|
110
|
+
workspaceManifests
|
|
107
111
|
}),
|
|
108
112
|
// Updates the workspaces schemas to /schemas endpoint
|
|
109
113
|
updateWorkspacesSchemas({
|
|
110
114
|
verbose,
|
|
111
|
-
workspaces
|
|
115
|
+
workspaces: schemaInputs
|
|
112
116
|
})
|
|
113
117
|
]);
|
|
114
118
|
return [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/deploy/deployStudioSchemasAndManifests.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {getStudioWorkspaces, subdebug} from '@sanity/cli-core'\nimport {type StudioManifest, type Workspace} from 'sanity'\n\nimport {extractWorkspaceManifest} from '../manifest/extractWorkspaceManifest.js'\nimport {writeManifestFile} from '../manifest/writeManifestFile.js'\nimport {updateWorkspacesSchemas} from '../schema/updateWorkspaceSchema.js'\nimport {uploadSchemaToLexicon} from '../schema/uploadSchemaToLexicon.js'\nimport {extractValidationFromSchemaError} from '../schema/utils/extractValidationFromSchemaError.js'\nimport {deployStudioSchemasAndManifestsWorkerData} from './types.js'\n\nconst debug = subdebug('deployStudioSchemasAndManifests.worker')\n\nasync function main() {\n if (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n }\n\n const {configPath, isExternal, outPath, projectId, schemaRequired, verbose, workDir} =\n deployStudioSchemasAndManifestsWorkerData.parse(workerData)\n\n try {\n debug('Deploying studio schemas and manifests from config path %s', configPath)\n const workspaces = await getStudioWorkspaces(configPath)\n debug('Workspaces %o', workspaces)\n\n if (workspaces.length === 0) {\n throw new Error('No workspaces found')\n }\n\n debug('Handling deployment for %s', isExternal ? 'external' : 'internal')\n\n let studioManifest: StudioManifest | null = null\n\n if (isExternal) {\n ;[studioManifest] = await handleExternalDeployment({\n projectId,\n schemaRequired,\n verbose,\n workDir,\n workspaces,\n })\n } else {\n ;[studioManifest] = await handleInternalDeployment({\n outPath,\n projectId,\n verbose,\n workDir,\n workspaces,\n })\n }\n\n parentPort.postMessage({\n studioManifest,\n type: 'success',\n })\n } catch (error) {\n debug('Error deploying studio schemas and manifests', error)\n const validation = await extractValidationFromSchemaError(error, workDir)\n parentPort.postMessage({\n error: error instanceof Error ? error.message : String(error),\n type: 'error',\n validation,\n })\n }\n}\n\
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/deploy/deployStudioSchemasAndManifests.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {getStudioWorkspaces, subdebug} from '@sanity/cli-core'\nimport {type StudioManifest, type Workspace} from 'sanity'\n\nimport {extractWorkspaceManifest} from '../manifest/extractWorkspaceManifest.js'\nimport {type CreateWorkspaceManifest} from '../manifest/types.js'\nimport {writeManifestFile} from '../manifest/writeManifestFile.js'\nimport {\n updateWorkspacesSchemas,\n type WorkspaceSchemaInput,\n} from '../schema/updateWorkspaceSchema.js'\nimport {uploadSchemaToLexicon} from '../schema/uploadSchemaToLexicon.js'\nimport {extractValidationFromSchemaError} from '../schema/utils/extractValidationFromSchemaError.js'\nimport {deployStudioSchemasAndManifestsWorkerData} from './types.js'\n\nconst debug = subdebug('deployStudioSchemasAndManifests.worker')\n\nasync function main() {\n if (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n }\n\n const {configPath, isExternal, outPath, projectId, schemaRequired, verbose, workDir} =\n deployStudioSchemasAndManifestsWorkerData.parse(workerData)\n\n try {\n debug('Deploying studio schemas and manifests from config path %s', configPath)\n const workspaces = await getStudioWorkspaces(configPath)\n debug('Workspaces %o', workspaces)\n\n if (workspaces.length === 0) {\n throw new Error('No workspaces found')\n }\n\n // Extract manifest data (including ManifestSchemaType[]) once, while Schema objects are\n // still live. Both writeWorkspaceToDist and updateWorkspacesSchemas consume the result.\n const workspaceManifests = await extractWorkspaceManifest(workspaces, workDir)\n\n const schemaInputs: WorkspaceSchemaInput[] = workspaceManifests.map((manifest) => ({\n dataset: manifest.dataset,\n manifestSchema: manifest.schema,\n name: manifest.name,\n projectId: manifest.projectId,\n title: manifest.title,\n }))\n\n debug('Handling deployment for %s', isExternal ? 'external' : 'internal')\n\n let studioManifest: StudioManifest | null = null\n\n if (isExternal) {\n ;[studioManifest] = await handleExternalDeployment({\n projectId,\n schemaInputs,\n schemaRequired,\n verbose,\n workDir,\n workspaces,\n })\n } else {\n ;[studioManifest] = await handleInternalDeployment({\n outPath,\n projectId,\n schemaInputs,\n verbose,\n workDir,\n workspaceManifests,\n workspaces,\n })\n }\n\n parentPort.postMessage({\n studioManifest,\n type: 'success',\n })\n } catch (error) {\n debug('Error deploying studio schemas and manifests', error)\n const validation = await extractValidationFromSchemaError(error, workDir)\n parentPort.postMessage({\n error: error instanceof Error ? error.message : String(error),\n type: 'error',\n validation,\n })\n }\n}\n\n/**\n * External deployments:\n * 1. Update the workspace schemas to the /schemas endpoint IF --schema-required is passed\n * 2. Update server-side schemas\n */\nasync function handleExternalDeployment({\n projectId,\n schemaInputs,\n schemaRequired,\n verbose,\n workDir,\n workspaces,\n}: {\n projectId: string\n schemaInputs: WorkspaceSchemaInput[]\n schemaRequired: boolean\n verbose: boolean\n workDir: string\n workspaces: Workspace[]\n}): Promise<[StudioManifest | null]> {\n const [studioManifest] = await Promise.all([\n uploadSchemaToLexicon({\n projectId,\n verbose,\n workDir,\n workspaces,\n }),\n schemaRequired ? updateWorkspacesSchemas({verbose, workspaces: schemaInputs}) : undefined,\n ])\n\n return [studioManifest]\n}\n\n/**\n *\n * Internal deployments:\n * 1. Write the workspace manifests to the dist directory\n * 2. Update the workspaces schemas to the /schemas endpoint\n * 3. Update server-side schemas\n *\n * @param workspaces - The workspaces to deploy\n */\nasync function handleInternalDeployment({\n outPath,\n projectId,\n schemaInputs,\n verbose,\n workDir,\n workspaceManifests,\n workspaces,\n}: {\n outPath: string\n projectId: string\n schemaInputs: WorkspaceSchemaInput[]\n verbose: boolean\n workDir: string\n workspaceManifests: CreateWorkspaceManifest[]\n workspaces: Workspace[]\n}): Promise<[StudioManifest | null]> {\n const [studioManifest] = await Promise.all([\n uploadSchemaToLexicon({\n projectId,\n verbose,\n workDir,\n workspaces,\n }),\n writeManifestFile({outPath, workDir, workspaceManifests}),\n // Updates the workspaces schemas to /schemas endpoint\n updateWorkspacesSchemas({\n verbose,\n workspaces: schemaInputs,\n }),\n ])\n\n return [studioManifest]\n}\n\nawait main()\n"],"names":["isMainThread","parentPort","workerData","getStudioWorkspaces","subdebug","extractWorkspaceManifest","writeManifestFile","updateWorkspacesSchemas","uploadSchemaToLexicon","extractValidationFromSchemaError","deployStudioSchemasAndManifestsWorkerData","debug","main","Error","configPath","isExternal","outPath","projectId","schemaRequired","verbose","workDir","parse","workspaces","length","workspaceManifests","schemaInputs","map","manifest","dataset","manifestSchema","schema","name","title","studioManifest","handleExternalDeployment","handleInternalDeployment","postMessage","type","error","validation","message","String","Promise","all","undefined"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/manifest/types.ts"],"sourcesContent":["import {type SanityDocumentLike} from '@sanity/types'\nimport {type MediaLibraryConfig
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/manifest/types.ts"],"sourcesContent":["import {type SanityDocumentLike} from '@sanity/types'\nimport {type MediaLibraryConfig} from 'sanity'\nimport {z} from 'zod'\n\nexport const SANITY_WORKSPACE_SCHEMA_ID_PREFIX = '_.schemas'\nexport const SANITY_WORKSPACE_SCHEMA_TYPE = 'system.schema'\nexport const CURRENT_WORKSPACE_SCHEMA_VERSION = '2025-05-01'\n\nexport type ManifestSerializable =\n | boolean\n | ManifestSerializable[]\n | number\n | string\n | {[k: string]: ManifestSerializable}\n\nexport interface CreateManifest {\n createdAt: string\n studioVersion: string | null\n version: number\n workspaces: ManifestWorkspaceFile[]\n}\n\nexport interface AppManifest {\n version: '1'\n\n icon?: string\n title?: string\n}\n\nexport interface ManifestWorkspaceFile extends Omit<CreateWorkspaceManifest, 'schema' | 'tools'> {\n schema: string // filename\n tools: string // filename\n}\n\nexport interface CreateWorkspaceManifest {\n basePath: string\n dataset: string\n /**\n * returns null in the case of the icon not being able to be stringified\n */\n icon: string | null\n name: string\n projectId: string\n schema: ManifestSchemaType[]\n tools: ManifestTool[]\n\n mediaLibrary?: MediaLibraryConfig\n subtitle?: string\n title?: string\n}\n\nexport interface ManifestSchemaType {\n name: string\n type: string\n\n deprecated?: {\n reason: string\n }\n fields?: ManifestField[]\n fieldsets?: ManifestFieldset[]\n hidden?: 'conditional' | boolean\n lists?: ManifestTitledValue[]\n //portable text\n marks?: {\n annotations?: ManifestArrayMember[]\n decorators?: ManifestTitledValue[]\n }\n of?: ManifestArrayMember[]\n options?: Record<string, ManifestSerializable>\n preview?: {\n select: Record<string, string>\n }\n readOnly?: 'conditional' | boolean\n styles?: ManifestTitledValue[]\n title?: string\n to?: ManifestReferenceMember[]\n validation?: ManifestValidationGroup[]\n\n // userland (assignable to ManifestSerializable | undefined)\n // not included to add some typesafty to extractManifest\n // [index: string]: unknown\n}\n\nexport interface ManifestFieldset {\n [index: string]: ManifestSerializable | undefined\n name: string\n\n title?: string\n}\n\nexport interface ManifestTitledValue {\n value: string\n\n title?: string\n}\n\ntype ManifestArrayMember = Omit<ManifestSchemaType, 'name'> & {name?: string}\ntype ManifestReferenceMember = Omit<ManifestSchemaType, 'name'> & {name?: string}\nexport type ManifestField = ManifestSchemaType & {fieldset?: string}\n\nexport interface ManifestValidationGroup {\n rules: ManifestValidationRule[]\n\n level?: 'error' | 'info' | 'warning'\n message?: string\n}\n\nexport type ManifestValidationRule = {\n [index: string]: ManifestSerializable | undefined\n constraint?: ManifestSerializable\n flag: string\n}\n\nexport interface ManifestTool {\n /**\n * returns null in the case of the icon not being able to be stringified\n */\n icon: string | null\n name: string\n title: string\n type: string | null\n}\n\nexport type DefaultWorkspaceSchemaId = `${typeof SANITY_WORKSPACE_SCHEMA_ID_PREFIX}.${string}`\ntype PrefixedWorkspaceSchemaId = `${DefaultWorkspaceSchemaId}.${string}`\nexport type WorkspaceSchemaId = DefaultWorkspaceSchemaId | PrefixedWorkspaceSchemaId\n\nexport interface StoredWorkspaceSchema extends SanityDocumentLike {\n _id: WorkspaceSchemaId\n _type: typeof SANITY_WORKSPACE_SCHEMA_TYPE\n /**\n * The API expects JSON coming in, but will store a string to save on attribute paths.\n * Consumers must use JSON.parse on the value, but we deploy to the API using ManifestSchemaType[]\n */\n schema: ManifestSchemaType[] | string\n /* api-like version string: date at which the format had a meaningful change */\n version: typeof CURRENT_WORKSPACE_SCHEMA_VERSION | undefined\n workspace: {\n name: string\n title?: string\n }\n\n tag?: string\n}\n\nexport const extractManifestWorkerData = z.object({configPath: z.string(), workDir: z.string()})\n\nexport type ExtractManifestWorkerData = z.infer<typeof extractManifestWorkerData>\n"],"names":["z","SANITY_WORKSPACE_SCHEMA_ID_PREFIX","SANITY_WORKSPACE_SCHEMA_TYPE","CURRENT_WORKSPACE_SCHEMA_VERSION","extractManifestWorkerData","object","configPath","string","workDir"],"mappings":"AAEA,SAAQA,CAAC,QAAO,MAAK;AAErB,OAAO,MAAMC,oCAAoC,YAAW;AAC5D,OAAO,MAAMC,+BAA+B,gBAAe;AAC3D,OAAO,MAAMC,mCAAmC,aAAY;AA2I5D,OAAO,MAAMC,4BAA4BJ,EAAEK,MAAM,CAAC;IAACC,YAAYN,EAAEO,MAAM;IAAIC,SAASR,EAAEO,MAAM;AAAE,GAAE"}
|
|
@@ -14,7 +14,13 @@ export async function deploySchemas(options) {
|
|
|
14
14
|
if (result.type === 'error') {
|
|
15
15
|
throw new SchemaExtractionError(result.error, result.validation);
|
|
16
16
|
}
|
|
17
|
-
const workspaces = result.workspaces.filter((workspace)=>!workspaceName || workspace.name === workspaceName)
|
|
17
|
+
const workspaces = result.workspaces.filter((workspace)=>!workspaceName || workspace.name === workspaceName).map((workspace)=>({
|
|
18
|
+
dataset: workspace.dataset,
|
|
19
|
+
manifestSchema: workspace.manifestSchema,
|
|
20
|
+
name: workspace.name,
|
|
21
|
+
projectId: workspace.projectId,
|
|
22
|
+
title: workspace.title
|
|
23
|
+
}));
|
|
18
24
|
if (workspaces.length === 0) {
|
|
19
25
|
const error = workspaceName ? new Error(`Found no workspaces named "${workspaceName}"`) : new Error('No workspaces found');
|
|
20
26
|
throw error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/schema/deploySchemas.ts"],"sourcesContent":["import {studioWorkerTask} from '@sanity/cli-core'\nimport {type SchemaValidationProblemGroup} from '@sanity/types'\nimport {type Workspace} from 'sanity'\n\nimport {type ExtractWorkspaceWorkerData} from './types.js'\nimport {updateWorkspacesSchemas} from './updateWorkspaceSchema.js'\nimport {SchemaExtractionError} from './utils/SchemaExtractionError.js'\n\ninterface DeploySchemasOptions {\n verbose: boolean\n workDir: string\n\n tag?: string\n workspaceName?: string\n}\n\ntype ExtractWorkspaceWorkerMessage =\n | {\n error: string\n type: 'error'\n validation?: SchemaValidationProblemGroup[]\n }\n | {\n type: 'success'\n workspaces:
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/deploySchemas.ts"],"sourcesContent":["import {studioWorkerTask} from '@sanity/cli-core'\nimport {type SchemaValidationProblemGroup} from '@sanity/types'\nimport {type Workspace} from 'sanity'\n\nimport {type ManifestSchemaType} from '../manifest/types.js'\nimport {type ExtractWorkspaceWorkerData} from './types.js'\nimport {updateWorkspacesSchemas, type WorkspaceSchemaInput} from './updateWorkspaceSchema.js'\nimport {SchemaExtractionError} from './utils/SchemaExtractionError.js'\n\ninterface DeploySchemasOptions {\n verbose: boolean\n workDir: string\n\n tag?: string\n workspaceName?: string\n}\n\ntype WorkspaceWithManifest = Workspace & {manifestSchema: ManifestSchemaType[]}\n\ntype ExtractWorkspaceWorkerMessage =\n | {\n error: string\n type: 'error'\n validation?: SchemaValidationProblemGroup[]\n }\n | {\n type: 'success'\n workspaces: WorkspaceWithManifest[]\n }\n\nexport async function deploySchemas(options: DeploySchemasOptions): Promise<void> {\n const {tag, verbose, workDir, workspaceName} = options\n\n const result = await studioWorkerTask<ExtractWorkspaceWorkerMessage>(\n new URL('extractSanityWorkspace.worker.js', import.meta.url),\n {\n name: 'extractSanityWorkspace',\n studioRootPath: workDir,\n workerData: {\n configPath: workDir,\n workDir,\n } satisfies ExtractWorkspaceWorkerData,\n },\n )\n\n if (result.type === 'error') {\n throw new SchemaExtractionError(result.error, result.validation)\n }\n\n const workspaces: WorkspaceSchemaInput[] = result.workspaces\n .filter((workspace) => !workspaceName || workspace.name === workspaceName)\n .map((workspace) => ({\n dataset: workspace.dataset,\n manifestSchema: workspace.manifestSchema,\n name: workspace.name,\n projectId: workspace.projectId,\n title: workspace.title,\n }))\n\n if (workspaces.length === 0) {\n const error = workspaceName\n ? new Error(`Found no workspaces named \"${workspaceName}\"`)\n : new Error('No workspaces found')\n throw error\n }\n\n await updateWorkspacesSchemas({\n tag,\n verbose,\n workspaces,\n })\n}\n"],"names":["studioWorkerTask","updateWorkspacesSchemas","SchemaExtractionError","deploySchemas","options","tag","verbose","workDir","workspaceName","result","URL","url","name","studioRootPath","workerData","configPath","type","error","validation","workspaces","filter","workspace","map","dataset","manifestSchema","projectId","title","length","Error"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,mBAAkB;AAMjD,SAAQC,uBAAuB,QAAkC,6BAA4B;AAC7F,SAAQC,qBAAqB,QAAO,mCAAkC;AAuBtE,OAAO,eAAeC,cAAcC,OAA6B;IAC/D,MAAM,EAACC,GAAG,EAAEC,OAAO,EAAEC,OAAO,EAAEC,aAAa,EAAC,GAAGJ;IAE/C,MAAMK,SAAS,MAAMT,iBACnB,IAAIU,IAAI,oCAAoC,YAAYC,GAAG,GAC3D;QACEC,MAAM;QACNC,gBAAgBN;QAChBO,YAAY;YACVC,YAAYR;YACZA;QACF;IACF;IAGF,IAAIE,OAAOO,IAAI,KAAK,SAAS;QAC3B,MAAM,IAAId,sBAAsBO,OAAOQ,KAAK,EAAER,OAAOS,UAAU;IACjE;IAEA,MAAMC,aAAqCV,OAAOU,UAAU,CACzDC,MAAM,CAAC,CAACC,YAAc,CAACb,iBAAiBa,UAAUT,IAAI,KAAKJ,eAC3Dc,GAAG,CAAC,CAACD,YAAe,CAAA;YACnBE,SAASF,UAAUE,OAAO;YAC1BC,gBAAgBH,UAAUG,cAAc;YACxCZ,MAAMS,UAAUT,IAAI;YACpBa,WAAWJ,UAAUI,SAAS;YAC9BC,OAAOL,UAAUK,KAAK;QACxB,CAAA;IAEF,IAAIP,WAAWQ,MAAM,KAAK,GAAG;QAC3B,MAAMV,QAAQT,gBACV,IAAIoB,MAAM,CAAC,2BAA2B,EAAEpB,cAAc,CAAC,CAAC,IACxD,IAAIoB,MAAM;QACd,MAAMX;IACR;IAEA,MAAMhB,wBAAwB;QAC5BI;QACAC;QACAa;IACF;AACF"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isMainThread, parentPort, workerData } from 'node:worker_threads';
|
|
2
2
|
import { getStudioWorkspaces, safeStructuredClone } from '@sanity/cli-core';
|
|
3
|
+
import { extractManifestSchemaTypes } from '../manifest/extractWorkspaceManifest.js';
|
|
3
4
|
import { extractWorkspaceWorkerData } from './types.js';
|
|
4
5
|
import { extractValidationFromSchemaError } from './utils/extractValidationFromSchemaError.js';
|
|
5
6
|
if (isMainThread || !parentPort) {
|
|
@@ -8,9 +9,16 @@ if (isMainThread || !parentPort) {
|
|
|
8
9
|
const { configPath, workDir } = extractWorkspaceWorkerData.parse(workerData);
|
|
9
10
|
try {
|
|
10
11
|
const workspaces = await getStudioWorkspaces(configPath);
|
|
12
|
+
// Extract manifest schemas while Schema objects are still live (before structured clone
|
|
13
|
+
// strips class methods like getTypeNames/get). The API expects ManifestSchemaType[], not
|
|
14
|
+
// the runtime Schema class instance.
|
|
15
|
+
const workspacesWithManifest = await Promise.all(workspaces.map(async (workspace)=>({
|
|
16
|
+
...safeStructuredClone(workspace),
|
|
17
|
+
manifestSchema: await extractManifestSchemaTypes(workspace.schema, workDir)
|
|
18
|
+
})));
|
|
11
19
|
parentPort.postMessage({
|
|
12
20
|
type: 'success',
|
|
13
|
-
workspaces:
|
|
21
|
+
workspaces: workspacesWithManifest
|
|
14
22
|
});
|
|
15
23
|
} catch (error) {
|
|
16
24
|
const validation = await extractValidationFromSchemaError(error, workDir);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/schema/extractSanityWorkspace.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {getStudioWorkspaces, safeStructuredClone} from '@sanity/cli-core'\n\nimport {extractWorkspaceWorkerData} from './types.js'\nimport {extractValidationFromSchemaError} from './utils/extractValidationFromSchemaError.js'\n\nif (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n}\n\nconst {configPath, workDir} = extractWorkspaceWorkerData.parse(workerData)\n\ntry {\n const workspaces = await getStudioWorkspaces(configPath)\n\n parentPort.postMessage({\n type: 'success',\n workspaces:
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/extractSanityWorkspace.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {getStudioWorkspaces, safeStructuredClone} from '@sanity/cli-core'\nimport {type Schema} from '@sanity/types'\n\nimport {extractManifestSchemaTypes} from '../manifest/extractWorkspaceManifest.js'\nimport {extractWorkspaceWorkerData} from './types.js'\nimport {extractValidationFromSchemaError} from './utils/extractValidationFromSchemaError.js'\n\nif (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n}\n\nconst {configPath, workDir} = extractWorkspaceWorkerData.parse(workerData)\n\ntry {\n const workspaces = await getStudioWorkspaces(configPath)\n\n // Extract manifest schemas while Schema objects are still live (before structured clone\n // strips class methods like getTypeNames/get). The API expects ManifestSchemaType[], not\n // the runtime Schema class instance.\n const workspacesWithManifest = await Promise.all(\n workspaces.map(async (workspace) => ({\n ...safeStructuredClone(workspace),\n manifestSchema: await extractManifestSchemaTypes(workspace.schema as Schema, workDir),\n })),\n )\n\n parentPort.postMessage({\n type: 'success',\n workspaces: workspacesWithManifest,\n })\n} catch (error) {\n const validation = await extractValidationFromSchemaError(error, workDir)\n parentPort.postMessage({\n error: error instanceof Error ? error.message : String(error),\n type: 'error',\n validation,\n })\n}\n"],"names":["isMainThread","parentPort","workerData","getStudioWorkspaces","safeStructuredClone","extractManifestSchemaTypes","extractWorkspaceWorkerData","extractValidationFromSchemaError","Error","configPath","workDir","parse","workspaces","workspacesWithManifest","Promise","all","map","workspace","manifestSchema","schema","postMessage","type","error","validation","message","String"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,UAAU,EAAEC,UAAU,QAAO,sBAAqB;AAExE,SAAQC,mBAAmB,EAAEC,mBAAmB,QAAO,mBAAkB;AAGzE,SAAQC,0BAA0B,QAAO,0CAAyC;AAClF,SAAQC,0BAA0B,QAAO,aAAY;AACrD,SAAQC,gCAAgC,QAAO,8CAA6C;AAE5F,IAAIP,gBAAgB,CAACC,YAAY;IAC/B,MAAM,IAAIO,MAAM;AAClB;AAEA,MAAM,EAACC,UAAU,EAAEC,OAAO,EAAC,GAAGJ,2BAA2BK,KAAK,CAACT;AAE/D,IAAI;IACF,MAAMU,aAAa,MAAMT,oBAAoBM;IAE7C,wFAAwF;IACxF,yFAAyF;IACzF,qCAAqC;IACrC,MAAMI,yBAAyB,MAAMC,QAAQC,GAAG,CAC9CH,WAAWI,GAAG,CAAC,OAAOC,YAAe,CAAA;YACnC,GAAGb,oBAAoBa,UAAU;YACjCC,gBAAgB,MAAMb,2BAA2BY,UAAUE,MAAM,EAAYT;QAC/E,CAAA;IAGFT,WAAWmB,WAAW,CAAC;QACrBC,MAAM;QACNT,YAAYC;IACd;AACF,EAAE,OAAOS,OAAO;IACd,MAAMC,aAAa,MAAMhB,iCAAiCe,OAAOZ;IACjET,WAAWmB,WAAW,CAAC;QACrBE,OAAOA,iBAAiBd,QAAQc,MAAME,OAAO,GAAGC,OAAOH;QACvDD,MAAM;QACNE;IACF;AACF"}
|
|
@@ -27,7 +27,7 @@ import { getWorkspaceSchemaId } from './utils/workspaceSchemaId.js';
|
|
|
27
27
|
* Updates a workspace schema in the dataset.
|
|
28
28
|
*/ async function updateWorkspaceSchema(args) {
|
|
29
29
|
const { tag, verbose, workspace } = args;
|
|
30
|
-
const { dataset, projectId } = workspace;
|
|
30
|
+
const { dataset, manifestSchema, projectId } = workspace;
|
|
31
31
|
const { idWarning, safeBaseId: id } = getWorkspaceSchemaId({
|
|
32
32
|
tag,
|
|
33
33
|
workspaceName: workspace.name
|
|
@@ -37,7 +37,7 @@ import { getWorkspaceSchemaId } from './utils/workspaceSchemaId.js';
|
|
|
37
37
|
await updateSchemas(dataset, projectId, [
|
|
38
38
|
{
|
|
39
39
|
// the API will stringify the schema – we send as JSON
|
|
40
|
-
schema:
|
|
40
|
+
schema: manifestSchema,
|
|
41
41
|
tag,
|
|
42
42
|
version: CURRENT_WORKSPACE_SCHEMA_VERSION,
|
|
43
43
|
workspace: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/schema/updateWorkspaceSchema.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {ux} from '@oclif/core/ux'\nimport {spinner} from '@sanity/cli-core/ux'\nimport partition from 'lodash-es/partition.js'\
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/updateWorkspaceSchema.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {ux} from '@oclif/core/ux'\nimport {spinner} from '@sanity/cli-core/ux'\nimport partition from 'lodash-es/partition.js'\n\nimport {updateSchemas} from '../../services/schemas.js'\nimport {\n CURRENT_WORKSPACE_SCHEMA_VERSION,\n type ManifestSchemaType,\n type StoredWorkspaceSchema,\n} from '../manifest/types.js'\nimport {SCHEMA_PERMISSION_HELP_TEXT} from './utils/schemaStoreValidation.js'\nimport {getWorkspaceSchemaId} from './utils/workspaceSchemaId.js'\n\n/**\n * Workspace metadata + pre-extracted manifest schema for deployment.\n * The schema must already be in ManifestSchemaType[] format (extracted from\n * the live Schema object before any structured clone boundary).\n */\nexport interface WorkspaceSchemaInput {\n dataset: string\n manifestSchema: ManifestSchemaType[]\n name: string\n projectId: string\n\n title?: string\n}\n\n/**\n * Updates the schemas for a list of workspaces.\n */\nexport async function updateWorkspacesSchemas(args: {\n tag?: string\n verbose: boolean\n workspaces: WorkspaceSchemaInput[]\n}) {\n const {tag, verbose, workspaces} = args\n\n /* Known caveat: we _don't_ rollback failed operations or partial success */\n const results = await Promise.allSettled(\n workspaces.map(async (workspace): Promise<void> => {\n await updateWorkspaceSchema({\n tag,\n verbose,\n workspace,\n })\n }),\n )\n\n const [fulfilledUpdates, rejectedUpdates] = partition(\n results,\n (result) => result.status === 'fulfilled',\n )\n\n if (rejectedUpdates.length > 0) {\n throw new Error(\n `Failed to deploy ${rejectedUpdates.length}/${workspaces.length} schemas. Successfully deployed ${fulfilledUpdates.length}/${workspaces.length} schemas.`,\n )\n }\n\n spinner(`Deployed ${fulfilledUpdates.length}/${workspaces.length} schemas`).succeed()\n}\n\n/**\n * Updates a workspace schema in the dataset.\n */\nasync function updateWorkspaceSchema(args: {\n tag?: string\n verbose: boolean\n workspace: WorkspaceSchemaInput\n}) {\n const {tag, verbose, workspace} = args\n\n const {dataset, manifestSchema, projectId} = workspace\n\n const {idWarning, safeBaseId: id} = getWorkspaceSchemaId({\n tag,\n workspaceName: workspace.name,\n })\n\n if (idWarning) ux.warn(idWarning)\n\n try {\n await updateSchemas<Omit<StoredWorkspaceSchema, '_id' | '_type'>[]>(dataset, projectId, [\n {\n // the API will stringify the schema – we send as JSON\n schema: manifestSchema,\n tag,\n version: CURRENT_WORKSPACE_SCHEMA_VERSION,\n workspace: {\n name: workspace.name,\n title: workspace.title,\n },\n },\n ])\n\n if (verbose) {\n ux.stdout(\n styleText('gray', `↳ schemaId: ${id}, projectId: ${projectId}, dataset: ${dataset}`),\n )\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n if (\n err instanceof Error &&\n 'statusCode' in err &&\n (err as {statusCode: unknown}).statusCode === 401\n ) {\n ux.warn(\n `↳ No permissions to write schema for workspace \"${workspace.name}\" in dataset \"${workspace.dataset}\". ${\n SCHEMA_PERMISSION_HELP_TEXT\n }:\\n ${styleText('red', message)}`,\n )\n } else {\n ux.stdout(\n styleText(\n 'red',\n `↳ Error deploying schema for workspace \"${workspace.name}\":\\n ${styleText('red', message)}`,\n ),\n )\n }\n\n throw err\n }\n}\n"],"names":["styleText","ux","spinner","partition","updateSchemas","CURRENT_WORKSPACE_SCHEMA_VERSION","SCHEMA_PERMISSION_HELP_TEXT","getWorkspaceSchemaId","updateWorkspacesSchemas","args","tag","verbose","workspaces","results","Promise","allSettled","map","workspace","updateWorkspaceSchema","fulfilledUpdates","rejectedUpdates","result","status","length","Error","succeed","dataset","manifestSchema","projectId","idWarning","safeBaseId","id","workspaceName","name","warn","schema","version","title","stdout","err","message","String","statusCode"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,EAAE,QAAO,iBAAgB;AACjC,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,OAAOC,eAAe,yBAAwB;AAE9C,SAAQC,aAAa,QAAO,4BAA2B;AACvD,SACEC,gCAAgC,QAG3B,uBAAsB;AAC7B,SAAQC,2BAA2B,QAAO,mCAAkC;AAC5E,SAAQC,oBAAoB,QAAO,+BAA8B;AAgBjE;;CAEC,GACD,OAAO,eAAeC,wBAAwBC,IAI7C;IACC,MAAM,EAACC,GAAG,EAAEC,OAAO,EAAEC,UAAU,EAAC,GAAGH;IAEnC,0EAA0E,GAC1E,MAAMI,UAAU,MAAMC,QAAQC,UAAU,CACtCH,WAAWI,GAAG,CAAC,OAAOC;QACpB,MAAMC,sBAAsB;YAC1BR;YACAC;YACAM;QACF;IACF;IAGF,MAAM,CAACE,kBAAkBC,gBAAgB,GAAGjB,UAC1CU,SACA,CAACQ,SAAWA,OAAOC,MAAM,KAAK;IAGhC,IAAIF,gBAAgBG,MAAM,GAAG,GAAG;QAC9B,MAAM,IAAIC,MACR,CAAC,iBAAiB,EAAEJ,gBAAgBG,MAAM,CAAC,CAAC,EAAEX,WAAWW,MAAM,CAAC,gCAAgC,EAAEJ,iBAAiBI,MAAM,CAAC,CAAC,EAAEX,WAAWW,MAAM,CAAC,SAAS,CAAC;IAE7J;IAEArB,QAAQ,CAAC,SAAS,EAAEiB,iBAAiBI,MAAM,CAAC,CAAC,EAAEX,WAAWW,MAAM,CAAC,QAAQ,CAAC,EAAEE,OAAO;AACrF;AAEA;;CAEC,GACD,eAAeP,sBAAsBT,IAIpC;IACC,MAAM,EAACC,GAAG,EAAEC,OAAO,EAAEM,SAAS,EAAC,GAAGR;IAElC,MAAM,EAACiB,OAAO,EAAEC,cAAc,EAAEC,SAAS,EAAC,GAAGX;IAE7C,MAAM,EAACY,SAAS,EAAEC,YAAYC,EAAE,EAAC,GAAGxB,qBAAqB;QACvDG;QACAsB,eAAef,UAAUgB,IAAI;IAC/B;IAEA,IAAIJ,WAAW5B,GAAGiC,IAAI,CAACL;IAEvB,IAAI;QACF,MAAMzB,cAA8DsB,SAASE,WAAW;YACtF;gBACE,sDAAsD;gBACtDO,QAAQR;gBACRjB;gBACA0B,SAAS/B;gBACTY,WAAW;oBACTgB,MAAMhB,UAAUgB,IAAI;oBACpBI,OAAOpB,UAAUoB,KAAK;gBACxB;YACF;SACD;QAED,IAAI1B,SAAS;YACXV,GAAGqC,MAAM,CACPtC,UAAU,QAAQ,CAAC,YAAY,EAAE+B,GAAG,aAAa,EAAEH,UAAU,WAAW,EAAEF,SAAS;QAEvF;IACF,EAAE,OAAOa,KAAK;QACZ,MAAMC,UAAUD,eAAef,QAAQe,IAAIC,OAAO,GAAGC,OAAOF;QAC5D,IACEA,eAAef,SACf,gBAAgBe,OAChB,AAACA,IAA8BG,UAAU,KAAK,KAC9C;YACAzC,GAAGiC,IAAI,CACL,CAAC,gDAAgD,EAAEjB,UAAUgB,IAAI,CAAC,cAAc,EAAEhB,UAAUS,OAAO,CAAC,GAAG,EACrGpB,4BACD,KAAK,EAAEN,UAAU,OAAOwC,UAAU;QAEvC,OAAO;YACLvC,GAAGqC,MAAM,CACPtC,UACE,OACA,CAAC,wCAAwC,EAAEiB,UAAUgB,IAAI,CAAC,MAAM,EAAEjC,UAAU,OAAOwC,UAAU;QAGnG;QAEA,MAAMD;IACR;AACF"}
|
package/dist/commands/debug.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { styleText } from 'node:util';
|
|
3
3
|
import { Flags } from '@oclif/core';
|
|
4
|
-
import { SanityCommand } from '@sanity/cli-core';
|
|
4
|
+
import { ProjectRootNotFoundError, SanityCommand } from '@sanity/cli-core';
|
|
5
5
|
import omit from 'lodash-es/omit.js';
|
|
6
6
|
import padStart from 'lodash-es/padStart.js';
|
|
7
7
|
import { formatObject, printKeyValue } from '../actions/debug/formatters.js';
|
|
@@ -23,8 +23,13 @@ export class Debug extends SanityCommand {
|
|
|
23
23
|
async run() {
|
|
24
24
|
const { flags } = this;
|
|
25
25
|
try {
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
let projectRoot;
|
|
27
|
+
try {
|
|
28
|
+
projectRoot = await this.getProjectRoot();
|
|
29
|
+
} catch (err) {
|
|
30
|
+
if (!(err instanceof ProjectRootNotFoundError)) throw err;
|
|
31
|
+
}
|
|
32
|
+
const cliConfig = projectRoot ? await this.getCliConfig() : undefined;
|
|
28
33
|
const { auth, globalConfig, project, projectConfig, user, versions } = await gatherDebugInfo({
|
|
29
34
|
cliConfig,
|
|
30
35
|
includeSecrets: flags.secrets,
|
|
@@ -69,11 +74,17 @@ export class Debug extends SanityCommand {
|
|
|
69
74
|
'authToken'
|
|
70
75
|
]);
|
|
71
76
|
this.log(` ${formatObject(globalCfg).replaceAll('\n', '\n ')}\n`);
|
|
72
|
-
// Project configuration (projectDir/sanity.
|
|
73
|
-
if (
|
|
74
|
-
|
|
77
|
+
// Project configuration (projectDir/sanity.cli.ts)
|
|
78
|
+
if (!projectRoot) {
|
|
79
|
+
this.log('No project found\n');
|
|
80
|
+
} else if (projectConfig instanceof Error) {
|
|
81
|
+
this.log(`CLI configuration error: ${styleText('red', projectConfig.message)}\n`);
|
|
82
|
+
} else if (projectConfig) {
|
|
83
|
+
const configLocation = ` (${styleText('yellow', path.relative(process.cwd(), projectRoot.path))})`;
|
|
75
84
|
this.log(`Project config${configLocation}:`);
|
|
76
85
|
this.log(` ${formatObject(projectConfig).replaceAll('\n', '\n ')}`);
|
|
86
|
+
} else {
|
|
87
|
+
this.log('No CLI configuration file found\n');
|
|
77
88
|
}
|
|
78
89
|
// Print installed package versions
|
|
79
90
|
if (versions) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/debug.ts"],"sourcesContent":["import path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\nimport omit from 'lodash-es/omit.js'\nimport padStart from 'lodash-es/padStart.js'\n\nimport {formatObject, printKeyValue} from '../actions/debug/formatters.js'\nimport {gatherDebugInfo} from '../actions/debug/gatherDebugInfo.js'\nimport {getGlobalConfigLocation} from '../actions/debug/getGlobalConfigLocation.js'\nimport {getDisplayName, getFormatters} from '../actions/versions/getFormatters.js'\n\nexport class Debug extends SanityCommand<typeof Debug> {\n static override description = 'Provides diagnostic info for Sanity Studio troubleshooting'\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n '<%= config.bin %> <%= command.id %> --secrets',\n ]\n\n static override flags = {\n secrets: Flags.boolean({\n default: false,\n description: 'Include API keys in output',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = this\n\n try {\n
|
|
1
|
+
{"version":3,"sources":["../../src/commands/debug.ts"],"sourcesContent":["import path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {ProjectRootNotFoundError, SanityCommand} from '@sanity/cli-core'\nimport omit from 'lodash-es/omit.js'\nimport padStart from 'lodash-es/padStart.js'\n\nimport {formatObject, printKeyValue} from '../actions/debug/formatters.js'\nimport {gatherDebugInfo} from '../actions/debug/gatherDebugInfo.js'\nimport {getGlobalConfigLocation} from '../actions/debug/getGlobalConfigLocation.js'\nimport {getDisplayName, getFormatters} from '../actions/versions/getFormatters.js'\n\nexport class Debug extends SanityCommand<typeof Debug> {\n static override description = 'Provides diagnostic info for Sanity Studio troubleshooting'\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n '<%= config.bin %> <%= command.id %> --secrets',\n ]\n\n static override flags = {\n secrets: Flags.boolean({\n default: false,\n description: 'Include API keys in output',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = this\n\n try {\n let projectRoot\n try {\n projectRoot = await this.getProjectRoot()\n } catch (err) {\n if (!(err instanceof ProjectRootNotFoundError)) throw err\n }\n\n const cliConfig = projectRoot ? await this.getCliConfig() : undefined\n\n const {auth, globalConfig, project, projectConfig, user, versions} = await gatherDebugInfo({\n cliConfig,\n includeSecrets: flags.secrets,\n projectRoot,\n })\n\n this.output.log('\\nUser:')\n if (user instanceof Error) {\n this.log(` ${styleText('red', user.message)}\\n`)\n } else if (user) {\n printKeyValue({\n ID: user.id,\n Name: user.name,\n // eslint-disable-next-line perfectionist/sort-objects\n Email: user.email,\n Roles: project && 'userRoles' in project ? project.userRoles : undefined,\n })\n }\n\n // Project info (API-based)\n if (project && 'id' in project) {\n this.log('Project:')\n printKeyValue({\n ID: project.id,\n // eslint-disable-next-line perfectionist/sort-objects\n 'Display name': project.displayName,\n })\n }\n\n // Auth info\n if (auth.hasToken) {\n this.log('Authentication:')\n printKeyValue({\n 'Auth token': flags.secrets ? auth.authToken : `<redacted>`,\n 'User type': globalConfig.authType || 'normal',\n })\n\n if (!flags.secrets) {\n this.log(' (run with --secrets to reveal token)\\n')\n }\n }\n\n // Global configuration (user home dir config file)\n this.log(`Global config (${styleText('yellow', getGlobalConfigLocation())}):`)\n const globalCfg = omit(globalConfig, ['authType', 'authToken'])\n this.log(` ${formatObject(globalCfg).replaceAll('\\n', '\\n ')}\\n`)\n\n // Project configuration (projectDir/sanity.cli.ts)\n if (!projectRoot) {\n this.log('No project found\\n')\n } else if (projectConfig instanceof Error) {\n this.log(`CLI configuration error: ${styleText('red', projectConfig.message)}\\n`)\n } else if (projectConfig) {\n const configLocation = ` (${styleText('yellow', path.relative(process.cwd(), projectRoot.path))})`\n\n this.log(`Project config${configLocation}:`)\n this.log(` ${formatObject(projectConfig).replaceAll('\\n', '\\n ')}`)\n } else {\n this.log('No CLI configuration file found\\n')\n }\n\n // Print installed package versions\n if (versions) {\n this.log('\\nPackage versions:')\n\n const {formatName, versionLength} = getFormatters(versions)\n for (const mod of versions) {\n const version = padStart(mod.installed || '<missing>', versionLength)\n const latest =\n mod.installed === mod.latest\n ? styleText('green', '(up to date)')\n : `(latest: ${styleText('yellow', mod.latest)})`\n\n this.log(`${formatName(getDisplayName(mod))} ${version} ${latest}`)\n }\n\n this.log('')\n }\n } catch (error) {\n this.error(\n `Failed to gather debug information: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n }\n}\n"],"names":["path","styleText","Flags","ProjectRootNotFoundError","SanityCommand","omit","padStart","formatObject","printKeyValue","gatherDebugInfo","getGlobalConfigLocation","getDisplayName","getFormatters","Debug","description","examples","flags","secrets","boolean","default","run","projectRoot","getProjectRoot","err","cliConfig","getCliConfig","undefined","auth","globalConfig","project","projectConfig","user","versions","includeSecrets","output","log","Error","message","ID","id","Name","name","Email","email","Roles","userRoles","displayName","hasToken","authToken","authType","globalCfg","replaceAll","configLocation","relative","process","cwd","formatName","versionLength","mod","version","installed","latest","error"],"mappings":"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"}
|