@sanity/cli 3.65.2-upgrade-vite-v5.31 → 3.66.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/_chunks-cjs/cli.js +5771 -2665
- package/lib/_chunks-cjs/cli.js.map +1 -1
- package/lib/_chunks-cjs/getCliConfig.js +1 -1
- package/lib/_chunks-cjs/getCliConfig.js.map +1 -1
- package/lib/index.d.mts +9 -1
- package/lib/index.d.ts +9 -1
- package/lib/index.esm.js.map +1 -1
- package/lib/index.mjs.map +1 -1
- package/package.json +11 -10
- package/src/CommandRunner.ts +1 -2
- package/src/actions/init-project/{bootstrapTemplate.ts → bootstrapLocalTemplate.ts} +6 -19
- package/src/actions/init-project/bootstrapRemoteTemplate.ts +77 -0
- package/src/actions/init-project/initProject.ts +110 -87
- package/src/actions/init-project/updateInitialTemplateMetadata.ts +24 -0
- package/src/commands/index.ts +0 -2
- package/src/commands/init/initCommand.ts +7 -67
- package/src/types.ts +9 -1
- package/src/util/getCliConfig.ts +1 -1
- package/src/util/getProviderName.ts +9 -0
- package/src/util/remoteTemplate.ts +522 -0
- package/src/actions/init-plugin/initPlugin.ts +0 -119
- package/src/actions/init-plugin/pluginTemplates.ts +0 -38
- package/src/actions/init-project/reconfigureV2Project.ts +0 -446
- package/src/commands/upgrade/upgradeCommand.ts +0 -38
- package/src/commands/upgrade/upgradeDependencies.ts +0 -289
@@ -0,0 +1,77 @@
|
|
1
|
+
import {mkdir} from 'node:fs/promises'
|
2
|
+
import {join} from 'node:path'
|
3
|
+
|
4
|
+
import {debug} from '../../debug'
|
5
|
+
import {type CliCommandContext} from '../../types'
|
6
|
+
import {
|
7
|
+
applyEnvVariables,
|
8
|
+
checkNeedsReadToken,
|
9
|
+
downloadAndExtractRepo,
|
10
|
+
generateSanityApiReadToken,
|
11
|
+
getMonoRepo,
|
12
|
+
isNextJsTemplate,
|
13
|
+
type RepoInfo,
|
14
|
+
tryApplyPackageName,
|
15
|
+
validateRemoteTemplate,
|
16
|
+
} from '../../util/remoteTemplate'
|
17
|
+
import {type GenerateConfigOptions} from './createStudioConfig'
|
18
|
+
import {tryGitInit} from './git'
|
19
|
+
import {updateInitialTemplateMetadata} from './updateInitialTemplateMetadata'
|
20
|
+
|
21
|
+
export interface BootstrapRemoteOptions {
|
22
|
+
outputPath: string
|
23
|
+
repoInfo: RepoInfo
|
24
|
+
bearerToken?: string
|
25
|
+
packageName: string
|
26
|
+
variables: GenerateConfigOptions['variables']
|
27
|
+
}
|
28
|
+
|
29
|
+
const INITIAL_COMMIT_MESSAGE = 'Initial commit from Sanity CLI'
|
30
|
+
|
31
|
+
export async function bootstrapRemoteTemplate(
|
32
|
+
opts: BootstrapRemoteOptions,
|
33
|
+
context: CliCommandContext,
|
34
|
+
): Promise<void> {
|
35
|
+
const {outputPath, repoInfo, bearerToken, variables, packageName} = opts
|
36
|
+
const {output, apiClient} = context
|
37
|
+
const name = [repoInfo.username, repoInfo.name, repoInfo.filePath].filter(Boolean).join('/')
|
38
|
+
const spinner = output.spinner(`Bootstrapping files from template "${name}"`).start()
|
39
|
+
|
40
|
+
debug('Validating remote template')
|
41
|
+
const packages = await getMonoRepo(repoInfo, bearerToken)
|
42
|
+
await validateRemoteTemplate(repoInfo, packages, bearerToken)
|
43
|
+
|
44
|
+
debug('Create new directory "%s"', outputPath)
|
45
|
+
await mkdir(outputPath, {recursive: true})
|
46
|
+
|
47
|
+
debug('Downloading and extracting repo to %s', outputPath)
|
48
|
+
await downloadAndExtractRepo(outputPath, repoInfo, bearerToken)
|
49
|
+
|
50
|
+
debug('Checking if template needs read token')
|
51
|
+
const needsReadToken = await Promise.all(
|
52
|
+
(packages ?? ['']).map((pkg) => checkNeedsReadToken(join(outputPath, pkg))),
|
53
|
+
).then((results) => results.some(Boolean))
|
54
|
+
|
55
|
+
debug('Applying environment variables')
|
56
|
+
const readToken = needsReadToken
|
57
|
+
? await generateSanityApiReadToken('API Read Token', variables.projectId, apiClient)
|
58
|
+
: undefined
|
59
|
+
const isNext = await isNextJsTemplate(outputPath)
|
60
|
+
const envName = isNext ? '.env.local' : '.env'
|
61
|
+
|
62
|
+
for (const folder of packages ?? ['']) {
|
63
|
+
const path = join(outputPath, folder)
|
64
|
+
await applyEnvVariables(path, {...variables, readToken}, envName)
|
65
|
+
}
|
66
|
+
|
67
|
+
debug('Setting package name to %s', packageName)
|
68
|
+
await tryApplyPackageName(outputPath, packageName)
|
69
|
+
|
70
|
+
debug('Initializing git repository')
|
71
|
+
tryGitInit(outputPath, INITIAL_COMMIT_MESSAGE)
|
72
|
+
|
73
|
+
debug('Updating initial template metadata')
|
74
|
+
await updateInitialTemplateMetadata(apiClient, variables.projectId, `external-${name}`)
|
75
|
+
|
76
|
+
spinner.succeed()
|
77
|
+
}
|
@@ -35,17 +35,21 @@ import {
|
|
35
35
|
type CliCommandDefinition,
|
36
36
|
type SanityCore,
|
37
37
|
type SanityModuleInternal,
|
38
|
+
type SanityUser,
|
38
39
|
} from '../../types'
|
39
40
|
import {getClientWrapper} from '../../util/clientWrapper'
|
40
41
|
import {dynamicRequire} from '../../util/dynamicRequire'
|
41
42
|
import {getProjectDefaults, type ProjectDefaults} from '../../util/getProjectDefaults'
|
43
|
+
import {getProviderName} from '../../util/getProviderName'
|
42
44
|
import {getUserConfig} from '../../util/getUserConfig'
|
43
45
|
import {isCommandGroup} from '../../util/isCommandGroup'
|
44
46
|
import {isInteractive} from '../../util/isInteractive'
|
45
47
|
import {fetchJourneyConfig} from '../../util/journeyConfig'
|
48
|
+
import {checkIsRemoteTemplate, getGitHubRepoInfo, type RepoInfo} from '../../util/remoteTemplate'
|
46
49
|
import {login, type LoginFlags} from '../login/login'
|
47
50
|
import {createProject} from '../project/createProject'
|
48
|
-
import {
|
51
|
+
import {bootstrapLocalTemplate} from './bootstrapLocalTemplate'
|
52
|
+
import {bootstrapRemoteTemplate} from './bootstrapRemoteTemplate'
|
49
53
|
import {type GenerateConfigOptions} from './createStudioConfig'
|
50
54
|
import {absolutify, validateEmptyPath} from './fsUtils'
|
51
55
|
import {tryGitInit} from './git'
|
@@ -58,7 +62,6 @@ import {
|
|
58
62
|
promptForStudioPath,
|
59
63
|
} from './prompts/nextjs'
|
60
64
|
import {readPackageJson} from './readPackageJson'
|
61
|
-
import {reconfigureV2Project} from './reconfigureV2Project'
|
62
65
|
import templates from './templates'
|
63
66
|
import {
|
64
67
|
sanityCliTemplate,
|
@@ -68,19 +71,13 @@ import {
|
|
68
71
|
} from './templates/nextjs'
|
69
72
|
|
70
73
|
// eslint-disable-next-line no-process-env
|
71
|
-
const isCI = process.env.CI
|
74
|
+
const isCI = Boolean(process.env.CI)
|
72
75
|
|
73
76
|
/**
|
74
77
|
* @deprecated - No longer used
|
75
78
|
*/
|
76
79
|
export interface InitOptions {
|
77
80
|
template: string
|
78
|
-
// /**
|
79
|
-
// * Used for initializing a project from a server schema that is saved in the Journey API
|
80
|
-
// * This will override the `template` option.
|
81
|
-
// * @beta
|
82
|
-
// */
|
83
|
-
// journeyProjectId?: string
|
84
81
|
outputDir: string
|
85
82
|
name: string
|
86
83
|
displayName: string
|
@@ -117,16 +114,7 @@ export default async function initSanity(
|
|
117
114
|
detectedFramework: Awaited<ReturnType<typeof detectFrameworkRecord>>
|
118
115
|
},
|
119
116
|
): Promise<void> {
|
120
|
-
const {
|
121
|
-
output,
|
122
|
-
prompt,
|
123
|
-
workDir,
|
124
|
-
apiClient,
|
125
|
-
chalk,
|
126
|
-
sanityMajorVersion,
|
127
|
-
telemetry,
|
128
|
-
detectedFramework,
|
129
|
-
} = context
|
117
|
+
const {output, prompt, workDir, apiClient, chalk, telemetry, detectedFramework} = context
|
130
118
|
|
131
119
|
const trace = telemetry.trace(CLIInitStepCompleted)
|
132
120
|
|
@@ -144,6 +132,11 @@ export default async function initSanity(
|
|
144
132
|
const env = cliFlags.env
|
145
133
|
const packageManager = cliFlags['package-manager']
|
146
134
|
|
135
|
+
let remoteTemplateInfo: RepoInfo | undefined
|
136
|
+
if (cliFlags.template && checkIsRemoteTemplate(cliFlags.template)) {
|
137
|
+
remoteTemplateInfo = await getGitHubRepoInfo(cliFlags.template, cliFlags['template-token'])
|
138
|
+
}
|
139
|
+
|
147
140
|
let defaultConfig = cliFlags['dataset-default']
|
148
141
|
let showDefaultConfigPrompt = !defaultConfig
|
149
142
|
|
@@ -162,9 +155,10 @@ export default async function initSanity(
|
|
162
155
|
},
|
163
156
|
})
|
164
157
|
|
165
|
-
if (
|
166
|
-
|
167
|
-
|
158
|
+
if (detectedFramework && detectedFramework.slug !== 'sanity' && remoteTemplateInfo) {
|
159
|
+
throw new Error(
|
160
|
+
`A remote template cannot be used with a detected framework. Detected: ${detectedFramework.name}`,
|
161
|
+
)
|
168
162
|
}
|
169
163
|
|
170
164
|
// Only allow either --project-plan or --coupon
|
@@ -253,25 +247,9 @@ export default async function initSanity(
|
|
253
247
|
}
|
254
248
|
const envFilename = typeof env === 'string' ? env : envFilenameDefault
|
255
249
|
if (!envFilename.startsWith('.env')) {
|
256
|
-
throw new Error(
|
250
|
+
throw new Error('Env filename must start with .env')
|
257
251
|
}
|
258
252
|
|
259
|
-
const usingBareOrEnv = cliFlags.bare || cliFlags.env
|
260
|
-
print(
|
261
|
-
cliFlags.quickstart
|
262
|
-
? "You're ejecting a remote Sanity project!"
|
263
|
-
: `You're setting up a new project!`,
|
264
|
-
)
|
265
|
-
print(`We'll make sure you have an account with Sanity.io. ${usingBareOrEnv ? '' : `Then we'll`}`)
|
266
|
-
if (!usingBareOrEnv) {
|
267
|
-
print('install an open-source JS content editor that connects to')
|
268
|
-
print('the real-time hosted API on Sanity.io. Hang on.\n')
|
269
|
-
}
|
270
|
-
print('Press ctrl + C at any time to quit.\n')
|
271
|
-
print('Prefer web interfaces to terminals?')
|
272
|
-
print('You can also set up best practice Sanity projects with')
|
273
|
-
print('your favorite frontends on https://www.sanity.io/templates\n')
|
274
|
-
|
275
253
|
// If the user isn't already authenticated, make it so
|
276
254
|
const userConfig = getUserConfig()
|
277
255
|
const hasToken = userConfig.get('authToken')
|
@@ -279,12 +257,28 @@ export default async function initSanity(
|
|
279
257
|
debug(hasToken ? 'User already has a token' : 'User has no token')
|
280
258
|
if (hasToken) {
|
281
259
|
trace.log({step: 'login', alreadyLoggedIn: true})
|
282
|
-
|
260
|
+
const user = await getUserData(apiClient)
|
261
|
+
print('')
|
262
|
+
print(
|
263
|
+
`${chalk.gray(" 👤 You're logged in as %s using %s")}`,
|
264
|
+
user.name,
|
265
|
+
getProviderName(user.provider),
|
266
|
+
)
|
267
|
+
print('')
|
283
268
|
} else if (!unattended) {
|
284
269
|
trace.log({step: 'login'})
|
285
270
|
await getOrCreateUser()
|
286
271
|
}
|
287
272
|
|
273
|
+
let introMessage = "Let's get you started with a new project"
|
274
|
+
if (cliFlags.quickstart) {
|
275
|
+
introMessage = "Let's get you started with remote Sanity project"
|
276
|
+
} else if (remoteTemplateInfo) {
|
277
|
+
introMessage = "Let's get you started with a remote Sanity template"
|
278
|
+
}
|
279
|
+
print(` ➡️ ${chalk.gray(introMessage)}`)
|
280
|
+
print('')
|
281
|
+
|
288
282
|
const flags = await prepareFlags()
|
289
283
|
// We're authenticated, now lets select or create a project
|
290
284
|
const {projectId, displayName, isFirstProject, datasetName, schemaUrl} = await getProjectDetails()
|
@@ -581,18 +575,20 @@ export default async function initSanity(
|
|
581
575
|
const templateName = await selectProjectTemplate()
|
582
576
|
trace.log({step: 'selectProjectTemplate', selectedOption: templateName})
|
583
577
|
const template = templates[templateName]
|
584
|
-
if (!template) {
|
578
|
+
if (!remoteTemplateInfo && !template) {
|
585
579
|
throw new Error(`Template "${templateName}" not found`)
|
586
580
|
}
|
587
581
|
|
588
582
|
// Use typescript?
|
589
|
-
const typescriptOnly = template.typescriptOnly === true
|
590
583
|
let useTypeScript = true
|
591
|
-
if (!
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
584
|
+
if (!remoteTemplateInfo && template) {
|
585
|
+
const typescriptOnly = template.typescriptOnly === true
|
586
|
+
if (!typescriptOnly && typeof cliFlags.typescript === 'boolean') {
|
587
|
+
useTypeScript = cliFlags.typescript
|
588
|
+
} else if (!typescriptOnly && !unattended) {
|
589
|
+
useTypeScript = await promptForTypeScript(prompt)
|
590
|
+
trace.log({step: 'useTypeScript', selectedOption: useTypeScript ? 'yes' : 'no'})
|
591
|
+
}
|
596
592
|
}
|
597
593
|
|
598
594
|
// we enable auto-updates by default, but allow users to specify otherwise
|
@@ -601,47 +597,15 @@ export default async function initSanity(
|
|
601
597
|
autoUpdates = cliFlags['auto-updates']
|
602
598
|
}
|
603
599
|
|
604
|
-
// Build a full set of resolved options
|
605
|
-
const templateOptions: BootstrapOptions = {
|
606
|
-
outputPath,
|
607
|
-
packageName: sluggedName,
|
608
|
-
templateName,
|
609
|
-
schemaUrl,
|
610
|
-
useTypeScript,
|
611
|
-
variables: {
|
612
|
-
autoUpdates,
|
613
|
-
dataset: datasetName,
|
614
|
-
projectId,
|
615
|
-
projectName: displayName || answers.projectName,
|
616
|
-
},
|
617
|
-
}
|
618
|
-
|
619
600
|
// If the template has a sample dataset, prompt the user whether or not we should import it
|
620
601
|
const shouldImport =
|
621
|
-
!unattended && template
|
602
|
+
!unattended && template?.datasetUrl && (await promptForDatasetImport(template.importPrompt))
|
622
603
|
|
623
604
|
trace.log({step: 'importTemplateDataset', selectedOption: shouldImport ? 'yes' : 'no'})
|
624
605
|
|
625
606
|
const [_, bootstrapPromise] = await Promise.allSettled([
|
626
|
-
|
627
|
-
|
628
|
-
.request<SanityProject>({uri: `/projects/${projectId}`})
|
629
|
-
.then((project: SanityProject) => {
|
630
|
-
if (!project?.metadata?.cliInitializedAt) {
|
631
|
-
return apiClient({api: {projectId}}).request({
|
632
|
-
method: 'PATCH',
|
633
|
-
uri: `/projects/${projectId}`,
|
634
|
-
body: {metadata: {cliInitializedAt: new Date().toISOString()}},
|
635
|
-
})
|
636
|
-
}
|
637
|
-
return Promise.resolve()
|
638
|
-
})
|
639
|
-
.catch(() => {
|
640
|
-
// Non-critical update
|
641
|
-
debug('Failed to update cliInitializedAt metadata')
|
642
|
-
}),
|
643
|
-
// Bootstrap Sanity, creating required project files, manifests etc
|
644
|
-
bootstrapTemplate(templateOptions, context),
|
607
|
+
updateProjectCliInitializedMetadata(),
|
608
|
+
bootstrapTemplate(),
|
645
609
|
])
|
646
610
|
|
647
611
|
if (bootstrapPromise.status === 'rejected' && bootstrapPromise.reason instanceof Error) {
|
@@ -823,21 +787,19 @@ export default async function initSanity(
|
|
823
787
|
isFirstProject: boolean
|
824
788
|
userAction: 'create' | 'select'
|
825
789
|
}> {
|
826
|
-
const
|
790
|
+
const client = apiClient({requireUser: true, requireProject: false})
|
827
791
|
let projects
|
828
792
|
let organizations: ProjectOrganization[]
|
793
|
+
|
829
794
|
try {
|
830
|
-
const client = apiClient({requireUser: true, requireProject: false})
|
831
795
|
const [allProjects, allOrgs] = await Promise.all([
|
832
796
|
client.projects.list({includeMembers: false}),
|
833
797
|
client.request({uri: '/organizations'}),
|
834
798
|
])
|
835
799
|
projects = allProjects.sort((a, b) => b.createdAt.localeCompare(a.createdAt))
|
836
800
|
organizations = allOrgs
|
837
|
-
spinner.succeed()
|
838
801
|
} catch (err) {
|
839
802
|
if (unattended && flags.project) {
|
840
|
-
spinner.succeed()
|
841
803
|
return {
|
842
804
|
projectId: flags.project,
|
843
805
|
displayName: 'Unknown project',
|
@@ -845,7 +807,6 @@ export default async function initSanity(
|
|
845
807
|
userAction: 'select',
|
846
808
|
}
|
847
809
|
}
|
848
|
-
spinner.fail()
|
849
810
|
throw new Error(`Failed to communicate with the Sanity API:\n${err.message}`)
|
850
811
|
}
|
851
812
|
|
@@ -1117,6 +1078,58 @@ export default async function initSanity(
|
|
1117
1078
|
})
|
1118
1079
|
}
|
1119
1080
|
|
1081
|
+
async function updateProjectCliInitializedMetadata() {
|
1082
|
+
try {
|
1083
|
+
const client = apiClient({api: {projectId}})
|
1084
|
+
const project = await client.request<SanityProject>({uri: `/projects/${projectId}`})
|
1085
|
+
|
1086
|
+
if (!project?.metadata?.cliInitializedAt) {
|
1087
|
+
await client.request({
|
1088
|
+
method: 'PATCH',
|
1089
|
+
uri: `/projects/${projectId}`,
|
1090
|
+
body: {metadata: {cliInitializedAt: new Date().toISOString()}},
|
1091
|
+
})
|
1092
|
+
}
|
1093
|
+
} catch (err) {
|
1094
|
+
// Non-critical update
|
1095
|
+
debug('Failed to update cliInitializedAt metadata')
|
1096
|
+
}
|
1097
|
+
}
|
1098
|
+
|
1099
|
+
async function bootstrapTemplate() {
|
1100
|
+
const bootstrapVariables: GenerateConfigOptions['variables'] = {
|
1101
|
+
autoUpdates,
|
1102
|
+
dataset: datasetName,
|
1103
|
+
projectId,
|
1104
|
+
projectName: displayName || answers.projectName,
|
1105
|
+
}
|
1106
|
+
|
1107
|
+
if (remoteTemplateInfo) {
|
1108
|
+
return bootstrapRemoteTemplate(
|
1109
|
+
{
|
1110
|
+
outputPath,
|
1111
|
+
packageName: sluggedName,
|
1112
|
+
repoInfo: remoteTemplateInfo,
|
1113
|
+
bearerToken: cliFlags['template-token'],
|
1114
|
+
variables: bootstrapVariables,
|
1115
|
+
},
|
1116
|
+
context,
|
1117
|
+
)
|
1118
|
+
}
|
1119
|
+
|
1120
|
+
return bootstrapLocalTemplate(
|
1121
|
+
{
|
1122
|
+
outputPath,
|
1123
|
+
packageName: sluggedName,
|
1124
|
+
templateName,
|
1125
|
+
schemaUrl,
|
1126
|
+
useTypeScript,
|
1127
|
+
variables: bootstrapVariables,
|
1128
|
+
},
|
1129
|
+
context,
|
1130
|
+
)
|
1131
|
+
}
|
1132
|
+
|
1120
1133
|
async function getProjectInfo(): Promise<ProjectDefaults & {outputPath: string}> {
|
1121
1134
|
const specifiedPath = flags['output-path'] && path.resolve(flags['output-path'])
|
1122
1135
|
|
@@ -1479,6 +1492,16 @@ async function getPlanFromCoupon(apiClient: CliApiClient, couponCode: string): P
|
|
1479
1492
|
return planId
|
1480
1493
|
}
|
1481
1494
|
|
1495
|
+
async function getUserData(apiClient: CliApiClient): Promise<SanityUser> {
|
1496
|
+
return await apiClient({
|
1497
|
+
requireUser: true,
|
1498
|
+
requireProject: false,
|
1499
|
+
}).request({
|
1500
|
+
method: 'GET',
|
1501
|
+
uri: 'users/me',
|
1502
|
+
})
|
1503
|
+
}
|
1504
|
+
|
1482
1505
|
async function getPlanFromId(apiClient: CliApiClient, planId: string): Promise<string> {
|
1483
1506
|
const response = await apiClient({
|
1484
1507
|
requireUser: false,
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import {debug} from '../../debug'
|
2
|
+
import {type CliApiClient} from '../../types'
|
3
|
+
|
4
|
+
export async function updateInitialTemplateMetadata(
|
5
|
+
apiClient: CliApiClient,
|
6
|
+
projectId: string,
|
7
|
+
templateName: string,
|
8
|
+
): Promise<void> {
|
9
|
+
try {
|
10
|
+
await apiClient({api: {projectId}}).request({
|
11
|
+
method: 'PATCH',
|
12
|
+
uri: `/projects/${projectId}`,
|
13
|
+
body: {metadata: {initialTemplate: templateName}},
|
14
|
+
})
|
15
|
+
} catch (err: unknown) {
|
16
|
+
// Non-critical that we update this metadata, and user does not need to be aware
|
17
|
+
let message = typeof err === 'string' ? err : '<unknown error>'
|
18
|
+
if (err instanceof Error) {
|
19
|
+
message = err.message
|
20
|
+
}
|
21
|
+
|
22
|
+
debug('Failed to update initial template metadata for project: %s', message)
|
23
|
+
}
|
24
|
+
}
|
package/src/commands/index.ts
CHANGED
@@ -17,7 +17,6 @@ import telemetryGroup from './telemetry/telemetryGroup'
|
|
17
17
|
import telemetryStatusCommand from './telemetry/telemetryStatusCommand'
|
18
18
|
import generateTypegenCommand from './typegen/generateTypesCommand'
|
19
19
|
import typegenGroup from './typegen/typegenGroup'
|
20
|
-
import upgradeCommand from './upgrade/upgradeCommand'
|
21
20
|
import versionsCommand from './versions/versionsCommand'
|
22
21
|
|
23
22
|
export const baseCommands: (CliCommandDefinition | CliCommandGroupDefinition)[] = [
|
@@ -25,7 +24,6 @@ export const baseCommands: (CliCommandDefinition | CliCommandGroupDefinition)[]
|
|
25
24
|
loginCommand,
|
26
25
|
logoutCommand,
|
27
26
|
installCommand,
|
28
|
-
upgradeCommand,
|
29
27
|
versionsCommand,
|
30
28
|
docsCommand,
|
31
29
|
manageCommand,
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import {type Framework, frameworks} from '@vercel/frameworks'
|
2
2
|
import {detectFrameworkRecord, LocalFileSystemDetector} from '@vercel/fs-detectors'
|
3
3
|
|
4
|
-
import initPlugin from '../../actions/init-plugin/initPlugin'
|
5
4
|
import initProject from '../../actions/init-project/initProject'
|
6
5
|
import {
|
7
6
|
allowedPackageManagersString,
|
@@ -58,6 +57,11 @@ export interface InitFlags {
|
|
58
57
|
'project'?: string
|
59
58
|
'dataset'?: string
|
60
59
|
'template'?: string
|
60
|
+
/**
|
61
|
+
* Used for accessing private GitHub repo templates
|
62
|
+
* @beta
|
63
|
+
*/
|
64
|
+
'template-token'?: string
|
61
65
|
|
62
66
|
'visibility'?: string
|
63
67
|
'typescript'?: boolean
|
@@ -97,87 +101,23 @@ export const initCommand: CliCommandDefinition<InitFlags> = {
|
|
97
101
|
description: 'Initializes a new Sanity Studio and/or project',
|
98
102
|
helpText,
|
99
103
|
action: async (args, context) => {
|
100
|
-
const {output, chalk
|
104
|
+
const {output, chalk} = context
|
101
105
|
const [type] = args.argsWithoutOptions
|
102
|
-
const unattended = args.extOptions.y || args.extOptions.yes
|
103
|
-
|
104
|
-
const warn = (msg: string) => output.warn(chalk.yellow.bgBlack(msg))
|
105
|
-
|
106
|
-
// `sanity init plugin`
|
107
|
-
if (type === 'plugin') {
|
108
|
-
return context.sanityMajorVersion === 2
|
109
|
-
? // don't bother with telemetry here, as it's not supported in v3
|
110
|
-
initPlugin(args, context)
|
111
|
-
: Promise.reject(new Error(`'sanity init plugin' is not available in modern studios`))
|
112
|
-
}
|
113
106
|
|
114
107
|
// `sanity init whatever`
|
115
108
|
if (type) {
|
116
109
|
return Promise.reject(new Error(`Unknown init type "${type}"`))
|
117
110
|
}
|
118
111
|
|
119
|
-
// `npm create sanity` (regular v3 init)
|
120
|
-
|
121
112
|
const detectedFramework: Framework | null = await detectFrameworkRecord({
|
122
113
|
fs: new LocalFileSystemDetector(process.cwd()),
|
123
114
|
frameworkList: frameworks as readonly Framework[],
|
124
115
|
})
|
125
116
|
|
126
|
-
|
127
|
-
args.argv.includes('--from-create') ||
|
128
|
-
args.argv.includes('--env') ||
|
129
|
-
args.argv.includes('--bare') ||
|
130
|
-
detectedFramework?.slug === 'nextjs'
|
131
|
-
) {
|
132
|
-
return initProject(args, {
|
133
|
-
...context,
|
134
|
-
detectedFramework,
|
135
|
-
})
|
136
|
-
}
|
137
|
-
|
138
|
-
// `sanity init` (v2 style)
|
139
|
-
warn('╭────────────────────────────────────────────────────────────╮')
|
140
|
-
warn('│ │')
|
141
|
-
warn("│ Welcome to Sanity! It looks like you're following │")
|
142
|
-
warn('│ instructions for Sanity Studio v2, but the version you │')
|
143
|
-
warn('│ have installed is the latest - Sanity Studio v3. │')
|
144
|
-
warn('│ │')
|
145
|
-
warn('│ In Sanity Studio v3, new projects are created by running │')
|
146
|
-
warn('│ [npm create sanity@latest]. For more information, see │')
|
147
|
-
warn('│ https://www.sanity.io/help/studio-v2-vs-v3 │')
|
148
|
-
warn('│ │')
|
149
|
-
warn('╰────────────────────────────────────────────────────────────╯')
|
150
|
-
warn('') // Newline to separate from other output
|
151
|
-
const continueV3Init = unattended
|
152
|
-
? true
|
153
|
-
: await prompt.single({
|
154
|
-
message: 'Continue creating a Sanity Studio v3 project?',
|
155
|
-
type: 'confirm',
|
156
|
-
})
|
157
|
-
|
158
|
-
// Fall back
|
159
|
-
if (!continueV3Init) {
|
160
|
-
// Indicate that the operation did not succeed as expected
|
161
|
-
// eslint-disable-next-line no-process-exit
|
162
|
-
process.exit(1)
|
163
|
-
}
|
164
|
-
|
165
|
-
const returnVal = await initProject(args, {
|
117
|
+
return initProject(args, {
|
166
118
|
...context,
|
167
119
|
detectedFramework,
|
168
|
-
}).catch((err) => {
|
169
|
-
return Promise.reject(err)
|
170
120
|
})
|
171
|
-
|
172
|
-
warn('╭────────────────────────────────────────────────────────────╮')
|
173
|
-
warn('│ │')
|
174
|
-
warn('│ To learn how commands have changed from Studio v2 to v3, │')
|
175
|
-
warn('│ see https://www.sanity.io/help/studio-v2-vs-v3 │')
|
176
|
-
warn('│ │')
|
177
|
-
warn('╰────────────────────────────────────────────────────────────╯')
|
178
|
-
warn('') // Newline to separate from other output
|
179
|
-
|
180
|
-
return returnVal
|
181
121
|
},
|
182
122
|
}
|
183
123
|
|
package/src/types.ts
CHANGED
@@ -82,7 +82,6 @@ export interface CliBaseCommandContext {
|
|
82
82
|
output: CliOutputter
|
83
83
|
prompt: CliPrompter
|
84
84
|
apiClient: CliApiClient
|
85
|
-
yarn: CliStubbedYarn
|
86
85
|
sanityMajorVersion: 2 | 3
|
87
86
|
cliConfigPath?: string
|
88
87
|
cliRoot: string
|
@@ -349,3 +348,12 @@ export interface CliConfig {
|
|
349
348
|
export type UserViteConfig =
|
350
349
|
| InlineConfig
|
351
350
|
| ((config: InlineConfig, env: ConfigEnv) => InlineConfig | Promise<InlineConfig>)
|
351
|
+
|
352
|
+
export type SanityUser = {
|
353
|
+
id: string
|
354
|
+
name: string
|
355
|
+
email: string
|
356
|
+
profileImage?: string
|
357
|
+
tosAcceptedAt?: string
|
358
|
+
provider: 'google' | 'github' | 'sanity' | `saml-${string}`
|
359
|
+
}
|
package/src/util/getCliConfig.ts
CHANGED
@@ -42,7 +42,7 @@ export async function getCliConfig(
|
|
42
42
|
|
43
43
|
const {unregister} = __DEV__
|
44
44
|
? {unregister: () => undefined}
|
45
|
-
: require('esbuild-register/dist/node').register(
|
45
|
+
: require('esbuild-register/dist/node').register()
|
46
46
|
|
47
47
|
try {
|
48
48
|
const v3Config = getSanityCliConfig(cwd)
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import {type SanityUser} from '../types'
|
2
|
+
|
3
|
+
export function getProviderName(provider: SanityUser['provider']) {
|
4
|
+
if (provider === 'google') return 'Google'
|
5
|
+
if (provider === 'github') return 'GitHub'
|
6
|
+
if (provider === 'sanity') return 'Email'
|
7
|
+
if (provider.startsWith('saml-')) return 'SAML'
|
8
|
+
return provider
|
9
|
+
}
|