@sanity/cli 6.1.4 → 6.1.6
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 +78 -78
- 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/exec/execScript.js +19 -7
- package/dist/actions/exec/execScript.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/getExtractOptions.js +14 -3
- package/dist/actions/schema/getExtractOptions.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/util/cliClient.js +1 -1
- package/dist/util/cliClient.js.map +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +12 -12
- package/dist/actions/exec/configClient.worker.js +0 -9
- package/dist/actions/exec/configClient.worker.js.map +0 -1
|
@@ -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,12 +1,13 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { CLIError } from '@oclif/core/errors';
|
|
4
|
+
import { getCliToken } from '@sanity/cli-core';
|
|
3
5
|
export async function execScript(options) {
|
|
4
6
|
const { extraArguments, flags, scriptPath, workDir } = options;
|
|
5
7
|
const mockBrowserEnv = flags['mock-browser-env'];
|
|
6
8
|
const withUserToken = flags['with-user-token'];
|
|
7
9
|
const resolvedScriptPath = path.resolve(scriptPath);
|
|
8
10
|
const browserEnvPath = new URL('registerBrowserEnv.worker.js', import.meta.url).href;
|
|
9
|
-
const configClientPath = new URL('configClient.worker.js', import.meta.url).href;
|
|
10
11
|
// Use tsx loader for TypeScript support in the spawned child process
|
|
11
12
|
// We need to resolve the tsx loader path from the CLI's node_modules since the child
|
|
12
13
|
// process will run from the user's script directory where tsx may not be installed.
|
|
@@ -15,6 +16,21 @@ export async function execScript(options) {
|
|
|
15
16
|
if (!tsxLoaderPath) {
|
|
16
17
|
throw new Error('@sanity/cli not able to resolve tsx loader');
|
|
17
18
|
}
|
|
19
|
+
// When --with-user-token is specified, resolve the token in the parent process
|
|
20
|
+
// and pass it via environment variable. This avoids a module-instance mismatch where
|
|
21
|
+
// the worker's `getCliClient` import resolves to a different module than the script's
|
|
22
|
+
// `import {getCliClient} from 'sanity/cli'`, causing the __internal__getToken mutation
|
|
23
|
+
// to not propagate.
|
|
24
|
+
let tokenEnv = {};
|
|
25
|
+
if (withUserToken) {
|
|
26
|
+
const token = await getCliToken();
|
|
27
|
+
if (!token) {
|
|
28
|
+
throw new CLIError('--with-user-token specified, but no auth token could be found. Run `sanity login`');
|
|
29
|
+
}
|
|
30
|
+
tokenEnv = {
|
|
31
|
+
SANITY_AUTH_TOKEN: token
|
|
32
|
+
};
|
|
33
|
+
}
|
|
18
34
|
const baseArgs = mockBrowserEnv ? [
|
|
19
35
|
'--import',
|
|
20
36
|
tsxLoaderPath,
|
|
@@ -24,20 +40,16 @@ export async function execScript(options) {
|
|
|
24
40
|
'--import',
|
|
25
41
|
tsxLoaderPath
|
|
26
42
|
];
|
|
27
|
-
const tokenArgs = withUserToken ? [
|
|
28
|
-
'--import',
|
|
29
|
-
configClientPath
|
|
30
|
-
] : [];
|
|
31
43
|
const nodeArgs = [
|
|
32
44
|
...baseArgs,
|
|
33
|
-
...tokenArgs,
|
|
34
45
|
resolvedScriptPath,
|
|
35
46
|
...extraArguments
|
|
36
47
|
];
|
|
37
48
|
const proc = spawn(process.argv[0], nodeArgs, {
|
|
38
49
|
env: {
|
|
39
50
|
...process.env,
|
|
40
|
-
SANITY_BASE_PATH: workDir
|
|
51
|
+
SANITY_BASE_PATH: workDir,
|
|
52
|
+
...tokenEnv
|
|
41
53
|
},
|
|
42
54
|
stdio: 'inherit'
|
|
43
55
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/exec/execScript.ts"],"sourcesContent":["import {spawn} from 'node:child_process'\nimport path from 'node:path'\n\ninterface ExecScriptOptions {\n extraArguments: string[]\n flags: {\n 'mock-browser-env': boolean\n 'with-user-token': boolean\n }\n scriptPath: string\n workDir: string\n}\n\nexport async function execScript(options: ExecScriptOptions): Promise<void> {\n const {extraArguments, flags, scriptPath, workDir} = options\n const mockBrowserEnv = flags['mock-browser-env']\n const withUserToken = flags['with-user-token']\n\n const resolvedScriptPath = path.resolve(scriptPath)\n\n const browserEnvPath = new URL('registerBrowserEnv.worker.js', import.meta.url).href\n
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/exec/execScript.ts"],"sourcesContent":["import {spawn} from 'node:child_process'\nimport path from 'node:path'\n\nimport {CLIError} from '@oclif/core/errors'\nimport {getCliToken} from '@sanity/cli-core'\n\ninterface ExecScriptOptions {\n extraArguments: string[]\n flags: {\n 'mock-browser-env': boolean\n 'with-user-token': boolean\n }\n scriptPath: string\n workDir: string\n}\n\nexport async function execScript(options: ExecScriptOptions): Promise<void> {\n const {extraArguments, flags, scriptPath, workDir} = options\n const mockBrowserEnv = flags['mock-browser-env']\n const withUserToken = flags['with-user-token']\n\n const resolvedScriptPath = path.resolve(scriptPath)\n\n const browserEnvPath = new URL('registerBrowserEnv.worker.js', import.meta.url).href\n\n // Use tsx loader for TypeScript support in the spawned child process\n // We need to resolve the tsx loader path from the CLI's node_modules since the child\n // process will run from the user's script directory where tsx may not be installed.\n // Resolve the tsx loader using Node's module resolution relative to package.json\n const tsxLoaderPath: string = import.meta.resolve('tsx', import.meta.url)\n if (!tsxLoaderPath) {\n throw new Error('@sanity/cli not able to resolve tsx loader')\n }\n\n // When --with-user-token is specified, resolve the token in the parent process\n // and pass it via environment variable. This avoids a module-instance mismatch where\n // the worker's `getCliClient` import resolves to a different module than the script's\n // `import {getCliClient} from 'sanity/cli'`, causing the __internal__getToken mutation\n // to not propagate.\n let tokenEnv: Record<string, string> = {}\n if (withUserToken) {\n const token = await getCliToken()\n if (!token) {\n throw new CLIError(\n '--with-user-token specified, but no auth token could be found. Run `sanity login`',\n )\n }\n tokenEnv = {SANITY_AUTH_TOKEN: token}\n }\n\n const baseArgs = mockBrowserEnv\n ? ['--import', tsxLoaderPath, '--import', browserEnvPath]\n : ['--import', tsxLoaderPath]\n\n const nodeArgs = [...baseArgs, resolvedScriptPath, ...extraArguments]\n\n const proc = spawn(process.argv[0], nodeArgs, {\n env: {\n ...process.env,\n SANITY_BASE_PATH: workDir,\n ...tokenEnv,\n },\n stdio: 'inherit',\n })\n\n // Signal handlers to forward signals to child process\n const handleExit = (): void => {\n proc.kill()\n }\n const handleSigInt = (): void => {\n proc.kill('SIGINT')\n }\n const handleSigTerm = (): void => {\n proc.kill('SIGTERM')\n }\n\n process.on('exit', handleExit)\n process.on('SIGINT', handleSigInt)\n process.on('SIGTERM', handleSigTerm)\n\n return new Promise<void>((resolve, reject) => {\n proc.on('exit', (code, signal) => {\n // Clean up listeners when child process exits\n process.removeListener('exit', handleExit)\n process.removeListener('SIGINT', handleSigInt)\n process.removeListener('SIGTERM', handleSigTerm)\n\n if (signal) reject(new Error(`Script terminated by signal: ${signal}`))\n else if (code && code !== 0) reject(new Error(`Script exited with code: ${code}`))\n else resolve()\n })\n proc.on('error', (err) => {\n // Clean up listeners on error too\n process.removeListener('exit', handleExit)\n process.removeListener('SIGINT', handleSigInt)\n process.removeListener('SIGTERM', handleSigTerm)\n reject(err)\n })\n })\n}\n"],"names":["spawn","path","CLIError","getCliToken","execScript","options","extraArguments","flags","scriptPath","workDir","mockBrowserEnv","withUserToken","resolvedScriptPath","resolve","browserEnvPath","URL","url","href","tsxLoaderPath","Error","tokenEnv","token","SANITY_AUTH_TOKEN","baseArgs","nodeArgs","proc","process","argv","env","SANITY_BASE_PATH","stdio","handleExit","kill","handleSigInt","handleSigTerm","on","Promise","reject","code","signal","removeListener","err"],"mappings":"AAAA,SAAQA,KAAK,QAAO,qBAAoB;AACxC,OAAOC,UAAU,YAAW;AAE5B,SAAQC,QAAQ,QAAO,qBAAoB;AAC3C,SAAQC,WAAW,QAAO,mBAAkB;AAY5C,OAAO,eAAeC,WAAWC,OAA0B;IACzD,MAAM,EAACC,cAAc,EAAEC,KAAK,EAAEC,UAAU,EAAEC,OAAO,EAAC,GAAGJ;IACrD,MAAMK,iBAAiBH,KAAK,CAAC,mBAAmB;IAChD,MAAMI,gBAAgBJ,KAAK,CAAC,kBAAkB;IAE9C,MAAMK,qBAAqBX,KAAKY,OAAO,CAACL;IAExC,MAAMM,iBAAiB,IAAIC,IAAI,gCAAgC,YAAYC,GAAG,EAAEC,IAAI;IAEpF,qEAAqE;IACrE,qFAAqF;IACrF,oFAAoF;IACpF,iFAAiF;IACjF,MAAMC,gBAAwB,YAAYL,OAAO,CAAC,OAAO,YAAYG,GAAG;IACxE,IAAI,CAACE,eAAe;QAClB,MAAM,IAAIC,MAAM;IAClB;IAEA,+EAA+E;IAC/E,qFAAqF;IACrF,sFAAsF;IACtF,uFAAuF;IACvF,oBAAoB;IACpB,IAAIC,WAAmC,CAAC;IACxC,IAAIT,eAAe;QACjB,MAAMU,QAAQ,MAAMlB;QACpB,IAAI,CAACkB,OAAO;YACV,MAAM,IAAInB,SACR;QAEJ;QACAkB,WAAW;YAACE,mBAAmBD;QAAK;IACtC;IAEA,MAAME,WAAWb,iBACb;QAAC;QAAYQ;QAAe;QAAYJ;KAAe,GACvD;QAAC;QAAYI;KAAc;IAE/B,MAAMM,WAAW;WAAID;QAAUX;WAAuBN;KAAe;IAErE,MAAMmB,OAAOzB,MAAM0B,QAAQC,IAAI,CAAC,EAAE,EAAEH,UAAU;QAC5CI,KAAK;YACH,GAAGF,QAAQE,GAAG;YACdC,kBAAkBpB;YAClB,GAAGW,QAAQ;QACb;QACAU,OAAO;IACT;IAEA,sDAAsD;IACtD,MAAMC,aAAa;QACjBN,KAAKO,IAAI;IACX;IACA,MAAMC,eAAe;QACnBR,KAAKO,IAAI,CAAC;IACZ;IACA,MAAME,gBAAgB;QACpBT,KAAKO,IAAI,CAAC;IACZ;IAEAN,QAAQS,EAAE,CAAC,QAAQJ;IACnBL,QAAQS,EAAE,CAAC,UAAUF;IACrBP,QAAQS,EAAE,CAAC,WAAWD;IAEtB,OAAO,IAAIE,QAAc,CAACvB,SAASwB;QACjCZ,KAAKU,EAAE,CAAC,QAAQ,CAACG,MAAMC;YACrB,8CAA8C;YAC9Cb,QAAQc,cAAc,CAAC,QAAQT;YAC/BL,QAAQc,cAAc,CAAC,UAAUP;YACjCP,QAAQc,cAAc,CAAC,WAAWN;YAElC,IAAIK,QAAQF,OAAO,IAAIlB,MAAM,CAAC,6BAA6B,EAAEoB,QAAQ;iBAChE,IAAID,QAAQA,SAAS,GAAGD,OAAO,IAAIlB,MAAM,CAAC,yBAAyB,EAAEmB,MAAM;iBAC3EzB;QACP;QACAY,KAAKU,EAAE,CAAC,SAAS,CAACM;YAChB,kCAAkC;YAClCf,QAAQc,cAAc,CAAC,QAAQT;YAC/BL,QAAQc,cAAc,CAAC,UAAUP;YACjCP,QAAQc,cAAc,CAAC,WAAWN;YAClCG,OAAOI;QACT;IACF;AACF"}
|
|
@@ -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"}
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, statSync } from 'node:fs';
|
|
2
|
+
import { extname, join, resolve } from 'node:path';
|
|
2
3
|
export function getExtractOptions({ flags, projectRoot, schemaExtraction }) {
|
|
3
4
|
const pathFlag = flags.path ?? schemaExtraction?.path;
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
let outputPath;
|
|
6
|
+
if (pathFlag) {
|
|
7
|
+
const resolved = resolve(join(projectRoot.directory, pathFlag));
|
|
8
|
+
const isExistingDirectory = existsSync(resolved) && statSync(resolved).isDirectory();
|
|
9
|
+
if (isExistingDirectory || !extname(resolved)) {
|
|
10
|
+
outputPath = join(resolved, 'schema.json');
|
|
11
|
+
} else {
|
|
12
|
+
outputPath = resolved;
|
|
13
|
+
}
|
|
14
|
+
} else {
|
|
15
|
+
outputPath = resolve(join(projectRoot.directory, 'schema.json'));
|
|
16
|
+
}
|
|
6
17
|
return {
|
|
7
18
|
configPath: projectRoot.path,
|
|
8
19
|
enforceRequiredFields: flags['enforce-required-fields'] ?? schemaExtraction?.enforceRequiredFields ?? false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/schema/getExtractOptions.ts"],"sourcesContent":["import {join, resolve} from 'node:path'\n\nimport {type CliConfig, ProjectRootResult} from '@sanity/cli-core'\n\nimport {type ExtractSchemaCommand} from '../../commands/schema/extract.js'\n\nexport interface ExtractOptions {\n configPath: string\n enforceRequiredFields: boolean\n format: string\n outputPath: string\n watchPatterns: string[]\n workspace: string | undefined\n}\n\ninterface GetExtractionOptions {\n flags: ExtractSchemaCommand['flags']\n projectRoot: ProjectRootResult\n schemaExtraction: CliConfig['schemaExtraction']\n}\n\nexport function getExtractOptions({\n flags,\n projectRoot,\n schemaExtraction,\n}: GetExtractionOptions): ExtractOptions {\n const pathFlag = flags.path ?? schemaExtraction?.path\n
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/getExtractOptions.ts"],"sourcesContent":["import {existsSync, statSync} from 'node:fs'\nimport {extname, join, resolve} from 'node:path'\n\nimport {type CliConfig, ProjectRootResult} from '@sanity/cli-core'\n\nimport {type ExtractSchemaCommand} from '../../commands/schema/extract.js'\n\nexport interface ExtractOptions {\n configPath: string\n enforceRequiredFields: boolean\n format: string\n outputPath: string\n watchPatterns: string[]\n workspace: string | undefined\n}\n\ninterface GetExtractionOptions {\n flags: ExtractSchemaCommand['flags']\n projectRoot: ProjectRootResult\n schemaExtraction: CliConfig['schemaExtraction']\n}\n\nexport function getExtractOptions({\n flags,\n projectRoot,\n schemaExtraction,\n}: GetExtractionOptions): ExtractOptions {\n const pathFlag = flags.path ?? schemaExtraction?.path\n let outputPath: string\n if (pathFlag) {\n const resolved = resolve(join(projectRoot.directory, pathFlag))\n const isExistingDirectory = existsSync(resolved) && statSync(resolved).isDirectory()\n\n if (isExistingDirectory || !extname(resolved)) {\n outputPath = join(resolved, 'schema.json')\n } else {\n outputPath = resolved\n }\n } else {\n outputPath = resolve(join(projectRoot.directory, 'schema.json'))\n }\n\n return {\n configPath: projectRoot.path,\n enforceRequiredFields:\n flags['enforce-required-fields'] ?? schemaExtraction?.enforceRequiredFields ?? false,\n format: flags.format ?? 'groq-type-nodes',\n outputPath,\n watchPatterns: flags['watch-patterns'] ?? schemaExtraction?.watchPatterns ?? [],\n workspace: flags.workspace ?? schemaExtraction?.workspace,\n }\n}\n"],"names":["existsSync","statSync","extname","join","resolve","getExtractOptions","flags","projectRoot","schemaExtraction","pathFlag","path","outputPath","resolved","directory","isExistingDirectory","isDirectory","configPath","enforceRequiredFields","format","watchPatterns","workspace"],"mappings":"AAAA,SAAQA,UAAU,EAAEC,QAAQ,QAAO,UAAS;AAC5C,SAAQC,OAAO,EAAEC,IAAI,EAAEC,OAAO,QAAO,YAAW;AAqBhD,OAAO,SAASC,kBAAkB,EAChCC,KAAK,EACLC,WAAW,EACXC,gBAAgB,EACK;IACrB,MAAMC,WAAWH,MAAMI,IAAI,IAAIF,kBAAkBE;IACjD,IAAIC;IACJ,IAAIF,UAAU;QACZ,MAAMG,WAAWR,QAAQD,KAAKI,YAAYM,SAAS,EAAEJ;QACrD,MAAMK,sBAAsBd,WAAWY,aAAaX,SAASW,UAAUG,WAAW;QAElF,IAAID,uBAAuB,CAACZ,QAAQU,WAAW;YAC7CD,aAAaR,KAAKS,UAAU;QAC9B,OAAO;YACLD,aAAaC;QACf;IACF,OAAO;QACLD,aAAaP,QAAQD,KAAKI,YAAYM,SAAS,EAAE;IACnD;IAEA,OAAO;QACLG,YAAYT,YAAYG,IAAI;QAC5BO,uBACEX,KAAK,CAAC,0BAA0B,IAAIE,kBAAkBS,yBAAyB;QACjFC,QAAQZ,MAAMY,MAAM,IAAI;QACxBP;QACAQ,eAAeb,KAAK,CAAC,iBAAiB,IAAIE,kBAAkBW,iBAAiB,EAAE;QAC/EC,WAAWd,MAAMc,SAAS,IAAIZ,kBAAkBY;IAClD;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) {
|