@sanity/cli 3.93.1-next.8.cf0bf8550a → 3.94.0
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 +1 -1
- package/lib/_chunks-cjs/cli.js.map +1 -1
- package/package.json +10 -11
- package/templates/blog/README.md +1 -1
- package/templates/clean/README.md +1 -1
- package/templates/ecommerce/README.md +1 -1
- package/templates/get-started/README.md +1 -1
- package/templates/moviedb/README.md +1 -1
- package/templates/quickstart/README.md +1 -1
- package/src/CommandRunner.ts +0 -219
- package/src/__telemetry__/cli.telemetry.ts +0 -29
- package/src/__telemetry__/init.telemetry.ts +0 -95
- package/src/actions/codemod/codemodAction.ts +0 -109
- package/src/actions/codemod/mods/deskRename.ts +0 -19
- package/src/actions/codemod/mods/index.ts +0 -9
- package/src/actions/codemod/mods/partsTypeDirective.ts +0 -28
- package/src/actions/codemod/mods/reactIconsV3.ts +0 -54
- package/src/actions/codemod/types.ts +0 -10
- package/src/actions/init-plugin/bootstrapFromTemplate.ts +0 -196
- package/src/actions/init-project/bootstrapLocalTemplate.ts +0 -201
- package/src/actions/init-project/bootstrapRemoteTemplate.ts +0 -118
- package/src/actions/init-project/createAppCliConfig.ts +0 -24
- package/src/actions/init-project/createCliConfig.ts +0 -31
- package/src/actions/init-project/createPackageManifest.ts +0 -102
- package/src/actions/init-project/createStudioConfig.ts +0 -53
- package/src/actions/init-project/determineAppTemplate.ts +0 -13
- package/src/actions/init-project/fsUtils.ts +0 -40
- package/src/actions/init-project/git.ts +0 -59
- package/src/actions/init-project/initProject.ts +0 -1708
- package/src/actions/init-project/processTemplate.ts +0 -55
- package/src/actions/init-project/promptForDatasetName.ts +0 -68
- package/src/actions/init-project/prompts/index.ts +0 -51
- package/src/actions/init-project/prompts/nextjs.ts +0 -59
- package/src/actions/init-project/readPackageJson.ts +0 -17
- package/src/actions/init-project/templates/appQuickstart.ts +0 -23
- package/src/actions/init-project/templates/appSanityUi.ts +0 -25
- package/src/actions/init-project/templates/blog.ts +0 -5
- package/src/actions/init-project/templates/clean.ts +0 -5
- package/src/actions/init-project/templates/getStarted.ts +0 -37
- package/src/actions/init-project/templates/index.ts +0 -24
- package/src/actions/init-project/templates/moviedb.ts +0 -35
- package/src/actions/init-project/templates/nextjs/index.ts +0 -238
- package/src/actions/init-project/templates/nextjs/schemaTypes/blog.ts +0 -252
- package/src/actions/init-project/templates/quickstart.ts +0 -5
- package/src/actions/init-project/templates/shopify.ts +0 -78
- package/src/actions/init-project/templates/shopifyOnline.ts +0 -50
- package/src/actions/init-project/updateInitialTemplateMetadata.ts +0 -24
- package/src/actions/login/login.telemetry.ts +0 -18
- package/src/actions/login/login.ts +0 -350
- package/src/actions/login/types.ts +0 -19
- package/src/actions/project/createProject.ts +0 -36
- package/src/actions/telemetry/setTelemetryConsent.ts +0 -101
- package/src/actions/typegen/generate.telemetry.ts +0 -20
- package/src/actions/typegen/generateAction.ts +0 -210
- package/src/actions/versions/findSanityModuleVersions.ts +0 -185
- package/src/actions/yarn/events.ts +0 -73
- package/src/cli.ts +0 -350
- package/src/cliClient.ts +0 -62
- package/src/commands/blueprints/addBlueprintsCommand.ts +0 -155
- package/src/commands/blueprints/blueprintsGroup.ts +0 -10
- package/src/commands/blueprints/configBlueprintsCommand.ts +0 -86
- package/src/commands/blueprints/deployBlueprintsCommand.ts +0 -63
- package/src/commands/blueprints/destroyBlueprintsCommand.ts +0 -78
- package/src/commands/blueprints/infoBlueprintsCommand.ts +0 -55
- package/src/commands/blueprints/initBlueprintsCommand.ts +0 -99
- package/src/commands/blueprints/logsBlueprintsCommand.ts +0 -66
- package/src/commands/blueprints/planBlueprintsCommand.ts +0 -51
- package/src/commands/blueprints/stacksBlueprintsCommand.ts +0 -66
- package/src/commands/codemod/codemodCommand.ts +0 -32
- package/src/commands/debug/debugCommand.ts +0 -26
- package/src/commands/debug/printDebugInfo.ts +0 -243
- package/src/commands/docs/docsCommand.ts +0 -20
- package/src/commands/functions/devFunctionsCommand.ts +0 -73
- package/src/commands/functions/envFunctionsCommand.ts +0 -105
- package/src/commands/functions/functionsGroup.ts +0 -10
- package/src/commands/functions/logsFunctionsCommand.ts +0 -94
- package/src/commands/functions/testFunctionsCommand.ts +0 -93
- package/src/commands/help/helpCommand.ts +0 -21
- package/src/commands/help/showHelp.ts +0 -58
- package/src/commands/index.ts +0 -72
- package/src/commands/init/initCommand.ts +0 -123
- package/src/commands/install/installCommand.ts +0 -38
- package/src/commands/learn/learnCommand.ts +0 -20
- package/src/commands/login/loginCommand.ts +0 -29
- package/src/commands/logout/logoutCommand.ts +0 -52
- package/src/commands/manage/manageCommand.ts +0 -24
- package/src/commands/projects/listProjectsCommand.ts +0 -62
- package/src/commands/projects/projectsGroup.ts +0 -10
- package/src/commands/telemetry/disableTelemetryCommand.ts +0 -19
- package/src/commands/telemetry/enableTelemetryCommand.ts +0 -19
- package/src/commands/telemetry/telemetryGroup.ts +0 -10
- package/src/commands/telemetry/telemetryStatusCommand.ts +0 -89
- package/src/commands/typegen/generateTypesCommand.ts +0 -56
- package/src/commands/typegen/typegenGroup.ts +0 -10
- package/src/commands/versions/printVersionResult.ts +0 -51
- package/src/commands/versions/versionsCommand.ts +0 -13
- package/src/config.ts +0 -14
- package/src/debug.ts +0 -3
- package/src/index.ts +0 -6
- package/src/outputters/cliOutputter.ts +0 -47
- package/src/packageManager/getInstallCommand.ts +0 -26
- package/src/packageManager/getUpgradeCommand.ts +0 -52
- package/src/packageManager/index.ts +0 -33
- package/src/packageManager/installPackages.ts +0 -99
- package/src/packageManager/packageManagerChoice.ts +0 -204
- package/src/packageManager/uninstallPackages.ts +0 -44
- package/src/packageManager/yarnStub.ts +0 -22
- package/src/prompters/cliPrompter.ts +0 -9
- package/src/run.ts +0 -8
- package/src/studioDependencies.ts +0 -25
- package/src/types.ts +0 -387
- package/src/util/canLaunchBrowser.ts +0 -12
- package/src/util/cliWorker.ts +0 -34
- package/src/util/clientWrapper.ts +0 -119
- package/src/util/copy.ts +0 -50
- package/src/util/createExpiringConfig.ts +0 -80
- package/src/util/createTelemetryStore.ts +0 -204
- package/src/util/detectRuntime.ts +0 -12
- package/src/util/dynamicRequire.ts +0 -17
- package/src/util/frameworkPort.ts +0 -63
- package/src/util/generateCommandsDocumentation.ts +0 -62
- package/src/util/getCliConfig.ts +0 -172
- package/src/util/getCliVersion.ts +0 -22
- package/src/util/getLocalVersion.ts +0 -35
- package/src/util/getProjectDefaults.ts +0 -103
- package/src/util/getProviderName.ts +0 -9
- package/src/util/getUserConfig.ts +0 -15
- package/src/util/isCi.ts +0 -7
- package/src/util/isCommandGroup.ts +0 -7
- package/src/util/isInteractive.ts +0 -3
- package/src/util/isTrueish.ts +0 -8
- package/src/util/journeyConfig.ts +0 -280
- package/src/util/loadEnv.ts +0 -110
- package/src/util/mergeCommands.ts +0 -78
- package/src/util/neatStack.ts +0 -30
- package/src/util/noSuchCommandText.ts +0 -91
- package/src/util/parseArguments.ts +0 -76
- package/src/util/pathExists.ts +0 -14
- package/src/util/readJson.ts +0 -6
- package/src/util/readdirRecursive.ts +0 -26
- package/src/util/remoteTemplate.ts +0 -320
- package/src/util/resolveLatestVersions.ts +0 -24
- package/src/util/resolveRootDir.ts +0 -59
- package/src/util/telemetryDisclosure.ts +0 -45
- package/src/util/updateNotifier.ts +0 -158
- package/src/util/writeJson.ts +0 -6
- package/src/workers/getAndWriteJourneySchema.ts +0 -7
- package/src/workers/getCliConfig.ts +0 -14
- package/src/workers/typegenGenerate.ts +0 -228
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
import http, {type Server} from 'node:http'
|
|
2
|
-
import os from 'node:os'
|
|
3
|
-
|
|
4
|
-
import {type SanityClient} from '@sanity/client'
|
|
5
|
-
import open from 'open'
|
|
6
|
-
|
|
7
|
-
import {debug as debugIt} from '../../debug'
|
|
8
|
-
import {
|
|
9
|
-
type CliApiClient,
|
|
10
|
-
type CliCommandArguments,
|
|
11
|
-
type CliCommandContext,
|
|
12
|
-
type CliPrompter,
|
|
13
|
-
} from '../../types'
|
|
14
|
-
import {canLaunchBrowser} from '../../util/canLaunchBrowser'
|
|
15
|
-
import {getCliToken} from '../../util/clientWrapper'
|
|
16
|
-
import {TELEMETRY_CONSENT_CONFIG_KEY} from '../../util/createTelemetryStore'
|
|
17
|
-
import {getUserConfig} from '../../util/getUserConfig'
|
|
18
|
-
import {LoginTrace} from './login.telemetry'
|
|
19
|
-
import {type LoginProvider, type ProvidersResponse, type SamlLoginProvider} from './types'
|
|
20
|
-
|
|
21
|
-
const callbackEndpoint = '/callback'
|
|
22
|
-
|
|
23
|
-
const debug = debugIt.extend('auth')
|
|
24
|
-
const callbackPorts = [4321, 4000, 3003, 1234, 8080, 13333]
|
|
25
|
-
|
|
26
|
-
const platformNames: Record<string, string | undefined> = {
|
|
27
|
-
aix: 'AIX',
|
|
28
|
-
android: 'Android',
|
|
29
|
-
darwin: 'MacOS',
|
|
30
|
-
freebsd: 'FreeBSD',
|
|
31
|
-
linux: 'Linux',
|
|
32
|
-
openbsd: 'OpenBSD',
|
|
33
|
-
sunos: 'SunOS',
|
|
34
|
-
win32: 'Windows',
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface LoginFlags {
|
|
38
|
-
experimental?: boolean
|
|
39
|
-
open?: boolean
|
|
40
|
-
provider?: string
|
|
41
|
-
sso?: string
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
interface TokenDetails {
|
|
45
|
-
token: string
|
|
46
|
-
label: string
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export async function login(
|
|
50
|
-
args: CliCommandArguments<LoginFlags>,
|
|
51
|
-
context: CliCommandContext,
|
|
52
|
-
): Promise<void> {
|
|
53
|
-
const {prompt, output, apiClient, telemetry} = context
|
|
54
|
-
const {sso, experimental, open: openFlag, provider: specifiedProvider} = args.extOptions
|
|
55
|
-
const previousToken = getCliToken()
|
|
56
|
-
const hasExistingToken = Boolean(previousToken)
|
|
57
|
-
|
|
58
|
-
const trace = telemetry.trace(LoginTrace)
|
|
59
|
-
trace.start()
|
|
60
|
-
|
|
61
|
-
// Explicitly tell this client not to use a token
|
|
62
|
-
const client = apiClient({requireUser: false, requireProject: false})
|
|
63
|
-
.clone()
|
|
64
|
-
.config({token: undefined})
|
|
65
|
-
|
|
66
|
-
// Get the desired authentication provider
|
|
67
|
-
const provider = await getProvider({client, sso, experimental, output, prompt, specifiedProvider})
|
|
68
|
-
|
|
69
|
-
trace.log({step: 'selectProvider', provider: provider?.name})
|
|
70
|
-
|
|
71
|
-
if (provider === undefined) {
|
|
72
|
-
throw new Error('No authentication providers found')
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Initiate local listen server for OAuth callback
|
|
76
|
-
const apiHost = client.config().apiHost || 'https://api.sanity.io'
|
|
77
|
-
const {server, token: tokenPromise} = await startServerForTokenCallback({apiHost, apiClient})
|
|
78
|
-
trace.log({step: 'waitForToken'})
|
|
79
|
-
|
|
80
|
-
const serverUrl = server.address()
|
|
81
|
-
if (!serverUrl || typeof serverUrl === 'string') {
|
|
82
|
-
// Note: `serverUrl` is string only when binding to unix sockets,
|
|
83
|
-
// thus we can safely assume Something Is Wrong™ if it's a string
|
|
84
|
-
throw new Error('Failed to start auth callback server')
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Build a login URL that redirects back back to OAuth flow on success
|
|
88
|
-
const loginUrl = new URL(provider.url)
|
|
89
|
-
const platformName = os.platform()
|
|
90
|
-
const platform = platformName in platformNames ? platformNames[platformName] : platformName
|
|
91
|
-
const hostname = os.hostname().replace(/\.(local|lan)$/g, '')
|
|
92
|
-
|
|
93
|
-
loginUrl.searchParams.set('type', 'token')
|
|
94
|
-
loginUrl.searchParams.set('label', `${hostname} / ${platform}`)
|
|
95
|
-
loginUrl.searchParams.set('origin', `http://localhost:${serverUrl.port}${callbackEndpoint}`)
|
|
96
|
-
|
|
97
|
-
// Open a browser on the login page (or tell the user to)
|
|
98
|
-
const shouldLaunchBrowser = canLaunchBrowser() && openFlag !== false
|
|
99
|
-
const actionText = shouldLaunchBrowser ? 'Opening browser at' : 'Please open a browser at'
|
|
100
|
-
|
|
101
|
-
output.print(`\n${actionText} ${loginUrl.href}\n`)
|
|
102
|
-
const spin = output
|
|
103
|
-
.spinner('Waiting for browser login to complete... Press Ctrl + C to cancel')
|
|
104
|
-
.start()
|
|
105
|
-
|
|
106
|
-
if (shouldLaunchBrowser) {
|
|
107
|
-
open(loginUrl.href)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Wait for a success/error on the HTTP callback server
|
|
111
|
-
let authToken: string
|
|
112
|
-
try {
|
|
113
|
-
authToken = (await tokenPromise).token
|
|
114
|
-
spin.stop()
|
|
115
|
-
} catch (err) {
|
|
116
|
-
spin.stop()
|
|
117
|
-
trace.error(err)
|
|
118
|
-
err.message = `Login failed: ${err.message}`
|
|
119
|
-
throw err
|
|
120
|
-
} finally {
|
|
121
|
-
server.close()
|
|
122
|
-
server.unref()
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Store the token
|
|
126
|
-
getUserConfig().set({
|
|
127
|
-
authToken: authToken,
|
|
128
|
-
authType: 'normal',
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
// Clear cached telemetry consent
|
|
132
|
-
getUserConfig().delete(TELEMETRY_CONSENT_CONFIG_KEY)
|
|
133
|
-
|
|
134
|
-
// If we had a session previously, attempt to clear it
|
|
135
|
-
if (hasExistingToken) {
|
|
136
|
-
await apiClient({requireUser: true, requireProject: false})
|
|
137
|
-
.clone()
|
|
138
|
-
.config({token: previousToken})
|
|
139
|
-
.request({uri: '/auth/logout', method: 'POST'})
|
|
140
|
-
.catch((err) => {
|
|
141
|
-
const statusCode = err && err.response && err.response.statusCode
|
|
142
|
-
if (statusCode !== 401) {
|
|
143
|
-
output.warn('[warn] Failed to log out existing session')
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
output.success('Login successful')
|
|
149
|
-
trace.complete()
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function startServerForTokenCallback(options: {
|
|
153
|
-
apiHost: string
|
|
154
|
-
apiClient: CliApiClient
|
|
155
|
-
}): Promise<{token: Promise<TokenDetails>; server: Server}> {
|
|
156
|
-
const {apiHost, apiClient} = options
|
|
157
|
-
const domain = apiHost.includes('.sanity.work') ? 'www.sanity.work' : 'www.sanity.io'
|
|
158
|
-
|
|
159
|
-
const attemptPorts = callbackPorts.slice()
|
|
160
|
-
let callbackPort = attemptPorts.shift()
|
|
161
|
-
|
|
162
|
-
let resolveToken: (resolvedToken: TokenDetails | PromiseLike<TokenDetails>) => void
|
|
163
|
-
let rejectToken: (reason: Error) => void
|
|
164
|
-
const tokenPromise = new Promise<TokenDetails>((resolve, reject) => {
|
|
165
|
-
resolveToken = resolve
|
|
166
|
-
rejectToken = reject
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
return new Promise((resolve, reject) => {
|
|
170
|
-
const server = http.createServer(async function onCallbackServerRequest(req, res) {
|
|
171
|
-
function failLoginRequest(code = '') {
|
|
172
|
-
res.writeHead(303, 'See Other', {
|
|
173
|
-
Location: `https://${domain}/login/error${code ? `?error=${code}` : ''}`,
|
|
174
|
-
})
|
|
175
|
-
res.end()
|
|
176
|
-
server.close()
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const url = new URL(req.url || '/', `http://localhost:${callbackPort}`)
|
|
180
|
-
if (url.pathname !== callbackEndpoint) {
|
|
181
|
-
res.writeHead(404, 'Not Found', {'Content-Type': 'text/plain'})
|
|
182
|
-
res.write('404 Not Found')
|
|
183
|
-
res.end()
|
|
184
|
-
return
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const absoluteTokenUrl = url.searchParams.get('url')
|
|
188
|
-
if (!absoluteTokenUrl) {
|
|
189
|
-
failLoginRequest()
|
|
190
|
-
return
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const tokenUrl = new URL(absoluteTokenUrl)
|
|
194
|
-
if (!tokenUrl.searchParams.has('sid')) {
|
|
195
|
-
failLoginRequest('NO_SESSION_ID')
|
|
196
|
-
return
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
let token: TokenDetails
|
|
200
|
-
try {
|
|
201
|
-
token = await apiClient({requireUser: false, requireProject: false})
|
|
202
|
-
.clone()
|
|
203
|
-
.request({uri: `/auth/fetch${tokenUrl.search}`})
|
|
204
|
-
} catch (err) {
|
|
205
|
-
failLoginRequest('UNRESOLVED_SESSION')
|
|
206
|
-
rejectToken(err)
|
|
207
|
-
return
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
res.writeHead(303, 'See Other', {Location: `https://${domain}/login/success`})
|
|
211
|
-
res.end()
|
|
212
|
-
server.close()
|
|
213
|
-
resolveToken(token)
|
|
214
|
-
})
|
|
215
|
-
|
|
216
|
-
server.on('listening', function onCallbackListen() {
|
|
217
|
-
// Once the server is successfully listening on a port, we can return the promise.
|
|
218
|
-
// We'll then await the _token promise_, while the server is running in the background.
|
|
219
|
-
resolve({token: tokenPromise, server})
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
server.on('error', function onCallbackServerError(err) {
|
|
223
|
-
if ('code' in err && err.code === 'EADDRINUSE') {
|
|
224
|
-
callbackPort = attemptPorts.shift()
|
|
225
|
-
if (!callbackPort) {
|
|
226
|
-
reject(new Error('Failed to find port number to bind auth callback server to'))
|
|
227
|
-
return
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
debug('Port busy, trying %d', callbackPort)
|
|
231
|
-
server.listen(callbackPort)
|
|
232
|
-
} else {
|
|
233
|
-
reject(err)
|
|
234
|
-
}
|
|
235
|
-
})
|
|
236
|
-
|
|
237
|
-
debug('Starting callback server on port %d', callbackPort)
|
|
238
|
-
server.listen(callbackPort)
|
|
239
|
-
})
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
async function getProvider({
|
|
243
|
-
output,
|
|
244
|
-
client,
|
|
245
|
-
sso,
|
|
246
|
-
experimental,
|
|
247
|
-
prompt,
|
|
248
|
-
specifiedProvider,
|
|
249
|
-
}: {
|
|
250
|
-
output: CliCommandContext['output']
|
|
251
|
-
client: SanityClient
|
|
252
|
-
sso?: string
|
|
253
|
-
experimental?: boolean
|
|
254
|
-
prompt: CliPrompter
|
|
255
|
-
specifiedProvider?: string
|
|
256
|
-
}): Promise<LoginProvider | undefined> {
|
|
257
|
-
if (sso) {
|
|
258
|
-
return getSSOProvider({client, prompt, slug: sso})
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// Fetch and prompt for login provider to use
|
|
262
|
-
const spin = output.spinner('Fetching providers...').start()
|
|
263
|
-
let {providers} = await client.request<ProvidersResponse>({uri: '/auth/providers'})
|
|
264
|
-
if (experimental) {
|
|
265
|
-
providers = [...providers, {name: 'sso', title: 'SSO', url: '_not_used_'}]
|
|
266
|
-
}
|
|
267
|
-
spin.stop()
|
|
268
|
-
|
|
269
|
-
const providerNames = providers.map((prov) => prov.name)
|
|
270
|
-
|
|
271
|
-
if (specifiedProvider && providerNames.includes(specifiedProvider)) {
|
|
272
|
-
const provider = providers.find((prov) => prov.name === specifiedProvider)
|
|
273
|
-
|
|
274
|
-
if (!provider) {
|
|
275
|
-
throw new Error(`Cannot find login provider with name "${specifiedProvider}"`)
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
return provider
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
const provider = await promptProviders(prompt, providers)
|
|
282
|
-
if (provider.name === 'sso') {
|
|
283
|
-
const slug = await prompt.single({
|
|
284
|
-
type: 'input',
|
|
285
|
-
message: 'Organization slug:',
|
|
286
|
-
})
|
|
287
|
-
return getSSOProvider({client, prompt, slug})
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return provider
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
async function getSSOProvider({
|
|
294
|
-
client,
|
|
295
|
-
prompt,
|
|
296
|
-
slug,
|
|
297
|
-
}: {
|
|
298
|
-
client: SanityClient
|
|
299
|
-
prompt: CliPrompter
|
|
300
|
-
slug: string
|
|
301
|
-
}): Promise<LoginProvider | undefined> {
|
|
302
|
-
const providers = await client
|
|
303
|
-
.withConfig({apiVersion: '2021-10-01'})
|
|
304
|
-
.request<SamlLoginProvider[]>({
|
|
305
|
-
uri: `/auth/organizations/by-slug/${slug}/providers`,
|
|
306
|
-
})
|
|
307
|
-
|
|
308
|
-
const enabledProviders = providers.filter((candidate) => !candidate.disabled)
|
|
309
|
-
if (enabledProviders.length === 0) {
|
|
310
|
-
return undefined
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
if (enabledProviders.length === 1) {
|
|
314
|
-
return samlProviderToLoginProvider(enabledProviders[0])
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const choice = await prompt.single({
|
|
318
|
-
type: 'list',
|
|
319
|
-
message: 'Select SSO provider',
|
|
320
|
-
choices: enabledProviders.map((provider) => provider.name),
|
|
321
|
-
})
|
|
322
|
-
|
|
323
|
-
const foundProvider = enabledProviders.find((provider) => provider.name === choice)
|
|
324
|
-
return foundProvider ? samlProviderToLoginProvider(foundProvider) : undefined
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
async function promptProviders(
|
|
328
|
-
prompt: CliPrompter,
|
|
329
|
-
providers: LoginProvider[],
|
|
330
|
-
): Promise<LoginProvider> {
|
|
331
|
-
if (providers.length === 1) {
|
|
332
|
-
return providers[0]
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
const provider = await prompt.single({
|
|
336
|
-
type: 'list',
|
|
337
|
-
message: 'Please log in or create a new account',
|
|
338
|
-
choices: providers.map((choice) => choice.title),
|
|
339
|
-
})
|
|
340
|
-
|
|
341
|
-
return providers.find((prov) => prov.title === provider) || providers[0]
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
function samlProviderToLoginProvider(saml: SamlLoginProvider): LoginProvider {
|
|
345
|
-
return {
|
|
346
|
-
name: saml.name,
|
|
347
|
-
title: saml.name,
|
|
348
|
-
url: saml.loginUrl,
|
|
349
|
-
}
|
|
350
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export interface LoginProvider {
|
|
2
|
-
name: string
|
|
3
|
-
title: string
|
|
4
|
-
url: string
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface SamlLoginProvider {
|
|
8
|
-
id: string
|
|
9
|
-
name: string
|
|
10
|
-
type: 'saml'
|
|
11
|
-
disabled: boolean
|
|
12
|
-
organizationId: string
|
|
13
|
-
loginUrl: string
|
|
14
|
-
callbackUrl: string
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface ProvidersResponse {
|
|
18
|
-
providers: LoginProvider[]
|
|
19
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import {type CliApiClient} from '../../types'
|
|
2
|
-
|
|
3
|
-
export interface CreateProjectOptions {
|
|
4
|
-
displayName: string
|
|
5
|
-
organizationId?: string
|
|
6
|
-
subscription?: {planId: string}
|
|
7
|
-
metadata?: {
|
|
8
|
-
coupon?: string
|
|
9
|
-
integration?: string
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function createProject(
|
|
14
|
-
apiClient: CliApiClient,
|
|
15
|
-
options: CreateProjectOptions,
|
|
16
|
-
): Promise<{projectId: string; displayName: string}> {
|
|
17
|
-
return apiClient({
|
|
18
|
-
requireUser: true,
|
|
19
|
-
requireProject: false,
|
|
20
|
-
})
|
|
21
|
-
.request({
|
|
22
|
-
method: 'POST',
|
|
23
|
-
uri: '/projects',
|
|
24
|
-
body: {
|
|
25
|
-
...options,
|
|
26
|
-
metadata: {
|
|
27
|
-
...options?.metadata,
|
|
28
|
-
integration: 'cli',
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
})
|
|
32
|
-
.then((response) => ({
|
|
33
|
-
projectId: response.projectId || response.id,
|
|
34
|
-
displayName: options.displayName || '',
|
|
35
|
-
}))
|
|
36
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import {type ConsentStatus} from '@sanity/telemetry'
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
telemetryLearnMoreMessage,
|
|
5
|
-
telemetryStatusMessage,
|
|
6
|
-
} from '../../commands/telemetry/telemetryStatusCommand'
|
|
7
|
-
import {debug} from '../../debug'
|
|
8
|
-
import {type CliCommandAction} from '../../types'
|
|
9
|
-
import {
|
|
10
|
-
type ConsentInformation,
|
|
11
|
-
resolveConsent,
|
|
12
|
-
TELEMETRY_CONSENT_CONFIG_KEY,
|
|
13
|
-
} from '../../util/createTelemetryStore'
|
|
14
|
-
import {getUserConfig} from '../../util/getUserConfig'
|
|
15
|
-
|
|
16
|
-
type SettableConsentStatus = Extract<ConsentStatus, 'granted' | 'denied'>
|
|
17
|
-
|
|
18
|
-
interface ResultMessage {
|
|
19
|
-
success: () => string
|
|
20
|
-
failure: (message?: string) => string
|
|
21
|
-
unchanged: (consentInformation: ConsentInformation) => string
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const resultMessages: Record<SettableConsentStatus, ResultMessage> = {
|
|
25
|
-
granted: {
|
|
26
|
-
success: () => `You've now enabled telemetry data collection to help us improve Sanity.`,
|
|
27
|
-
unchanged: () => `You've already enabled telemetry data collection to help us improve Sanity.`,
|
|
28
|
-
failure: (message) => {
|
|
29
|
-
if (message) {
|
|
30
|
-
return `Failed to enable telemetry: ${message}`
|
|
31
|
-
}
|
|
32
|
-
return 'Failed to enable telemetry'
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
denied: {
|
|
36
|
-
success: () =>
|
|
37
|
-
`You've opted out of telemetry data collection.\nNo data will be collected from your Sanity account.`,
|
|
38
|
-
unchanged: ({reason}) => {
|
|
39
|
-
if (reason === 'localOverride') {
|
|
40
|
-
return `You've already opted out of telemetry data collection.\nNo data is collected from your machine.\n\nUsing DO_NOT_TRACK environment variable.`
|
|
41
|
-
}
|
|
42
|
-
return `You've already opted out of telemetry data collection.\nNo data is collected from your Sanity account.`
|
|
43
|
-
},
|
|
44
|
-
failure: () => 'Failed to disable telemetry',
|
|
45
|
-
},
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function createSetTelemetryConsentAction(status: SettableConsentStatus): CliCommandAction {
|
|
49
|
-
return async function setTelemetryConsentAction(_, context) {
|
|
50
|
-
const {apiClient, output} = context
|
|
51
|
-
const config = getUserConfig()
|
|
52
|
-
|
|
53
|
-
const client = apiClient({
|
|
54
|
-
requireUser: true,
|
|
55
|
-
requireProject: false,
|
|
56
|
-
}).withConfig({
|
|
57
|
-
apiVersion: '2023-12-18',
|
|
58
|
-
useProjectHostname: false,
|
|
59
|
-
})
|
|
60
|
-
// eslint-disable-next-line no-process-env
|
|
61
|
-
const currentInformation = await resolveConsent({env: process.env})
|
|
62
|
-
const isChanged = currentInformation.status !== status
|
|
63
|
-
|
|
64
|
-
if (!isChanged) {
|
|
65
|
-
debug('Telemetry consent is already "%s"', status)
|
|
66
|
-
output.print(`${telemetryStatusMessage(status, context)}\n`)
|
|
67
|
-
output.print(resultMessages[status].unchanged(currentInformation))
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (isChanged) {
|
|
71
|
-
debug('Setting telemetry consent to "%s"', status)
|
|
72
|
-
try {
|
|
73
|
-
const uri = `/users/me/consents/telemetry/status/${status}`
|
|
74
|
-
debug('Sending telemetry consent status to %s', uri)
|
|
75
|
-
|
|
76
|
-
await client.request({
|
|
77
|
-
method: 'PUT',
|
|
78
|
-
uri,
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
// Clear cached telemetry consent
|
|
82
|
-
config.delete(TELEMETRY_CONSENT_CONFIG_KEY)
|
|
83
|
-
|
|
84
|
-
output.print(`${telemetryStatusMessage(status, context)}\n`)
|
|
85
|
-
output.print(resultMessages[status].success())
|
|
86
|
-
} catch (err) {
|
|
87
|
-
const errorMessage = resultMessages[status].failure(err.response?.body?.message)
|
|
88
|
-
if (err.statusCode === 403) {
|
|
89
|
-
// throw without stack trace from original error
|
|
90
|
-
throw new Error(errorMessage)
|
|
91
|
-
} else {
|
|
92
|
-
// if not 403, throw original error
|
|
93
|
-
err.message = errorMessage
|
|
94
|
-
throw err
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
output.print(`\n${telemetryLearnMoreMessage(status)}`)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import {defineTrace} from '@sanity/telemetry'
|
|
2
|
-
|
|
3
|
-
interface TypesGeneratedTraceAttrubutes {
|
|
4
|
-
outputSize: number
|
|
5
|
-
queriesCount: number
|
|
6
|
-
schemaTypesCount: number
|
|
7
|
-
queryFilesCount: number
|
|
8
|
-
filesWithErrors: number
|
|
9
|
-
typeNodesGenerated: number
|
|
10
|
-
unknownTypeNodesGenerated: number
|
|
11
|
-
unknownTypeNodesRatio: number
|
|
12
|
-
emptyUnionTypeNodesGenerated: number
|
|
13
|
-
configOverloadClientMethods: boolean
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const TypesGeneratedTrace = defineTrace<TypesGeneratedTraceAttrubutes>({
|
|
17
|
-
name: 'Types Generated',
|
|
18
|
-
version: 0,
|
|
19
|
-
description: 'Trace emitted when generating TypeScript types for queries',
|
|
20
|
-
})
|