@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.
@@ -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 {type BootstrapOptions, bootstrapTemplate} from './bootstrapTemplate'
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 (sanityMajorVersion === 2) {
166
- await reconfigureV2Project(args, context)
167
- return
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(`Env filename must start with .env`)
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
- print('Looks like you already have a Sanity-account. Sweet!\n')
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 (!typescriptOnly && typeof cliFlags.typescript === 'boolean') {
592
- useTypeScript = cliFlags.typescript
593
- } else if (!typescriptOnly && !unattended) {
594
- useTypeScript = await promptForTypeScript(prompt)
595
- trace.log({step: 'useTypeScript', selectedOption: useTypeScript ? 'yes' : 'no'})
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.datasetUrl && (await promptForDatasetImport(template.importPrompt))
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
- // record template files attempted to be created locally
627
- apiClient({api: {projectId: projectId}})
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 spinner = context.output.spinner('Fetching existing projects').start()
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
+ }
@@ -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, prompt} = context
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
- if (
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
+ }
@@ -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({supported: {'dynamic-import': true}})
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
+ }