@sanity/cli 3.93.1-next.9.198ab74452 → 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,80 +0,0 @@
|
|
|
1
|
-
import type ConfigStore from 'configstore'
|
|
2
|
-
|
|
3
|
-
export interface ExpiringConfigOptions<Type> {
|
|
4
|
-
/** Config store */
|
|
5
|
-
store: ConfigStore
|
|
6
|
-
/** Config key */
|
|
7
|
-
key: string
|
|
8
|
-
/** TTL (milliseconds) */
|
|
9
|
-
ttl: number
|
|
10
|
-
/** Fetch value */
|
|
11
|
-
fetchValue: () => Type | Promise<Type>
|
|
12
|
-
/** Subscribe to revalidate event */
|
|
13
|
-
onRevalidate?: () => void
|
|
14
|
-
/** Subscribe to fetch event */
|
|
15
|
-
onFetch?: () => void
|
|
16
|
-
/** Subscribe to cache hit event */
|
|
17
|
-
onCacheHit?: () => void
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface ExpiringConfigApi<Type> {
|
|
21
|
-
/**
|
|
22
|
-
* Attempt to get the cached value. If there is no cached value, or the cached value has expired,
|
|
23
|
-
* fetch, cache, and return the value.
|
|
24
|
-
*/
|
|
25
|
-
get: () => Promise<Type>
|
|
26
|
-
/**
|
|
27
|
-
* Delete the cached value.
|
|
28
|
-
*/
|
|
29
|
-
delete: () => void
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Create a config in the provided config store that expires after the provided TTL.
|
|
34
|
-
*/
|
|
35
|
-
export function createExpiringConfig<Type>({
|
|
36
|
-
key,
|
|
37
|
-
ttl,
|
|
38
|
-
store,
|
|
39
|
-
fetchValue,
|
|
40
|
-
onRevalidate = () => null,
|
|
41
|
-
onFetch = () => null,
|
|
42
|
-
onCacheHit = () => null,
|
|
43
|
-
}: ExpiringConfigOptions<Type>): ExpiringConfigApi<Type> {
|
|
44
|
-
let currentFetch: Promise<Type> | null = null
|
|
45
|
-
return {
|
|
46
|
-
async get() {
|
|
47
|
-
const {value, updatedAt} = store.get(key) ?? {}
|
|
48
|
-
|
|
49
|
-
if (value && updatedAt) {
|
|
50
|
-
const hasExpired = Date.now() - updatedAt > ttl
|
|
51
|
-
|
|
52
|
-
if (!hasExpired) {
|
|
53
|
-
onCacheHit()
|
|
54
|
-
return value
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
onRevalidate()
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (currentFetch) {
|
|
61
|
-
return currentFetch
|
|
62
|
-
}
|
|
63
|
-
onFetch()
|
|
64
|
-
|
|
65
|
-
currentFetch = Promise.resolve(fetchValue())
|
|
66
|
-
const nextValue = await currentFetch
|
|
67
|
-
currentFetch = null
|
|
68
|
-
|
|
69
|
-
store.set(key, {
|
|
70
|
-
value: nextValue,
|
|
71
|
-
updatedAt: Date.now(),
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
return nextValue
|
|
75
|
-
},
|
|
76
|
-
delete() {
|
|
77
|
-
store.delete(key)
|
|
78
|
-
},
|
|
79
|
-
}
|
|
80
|
-
}
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import {appendFile} from 'node:fs/promises'
|
|
2
|
-
|
|
3
|
-
import {type SanityClient} from '@sanity/client'
|
|
4
|
-
import {
|
|
5
|
-
type ConsentStatus,
|
|
6
|
-
createBatchedStore,
|
|
7
|
-
createSessionId,
|
|
8
|
-
type TelemetryEvent,
|
|
9
|
-
} from '@sanity/telemetry'
|
|
10
|
-
|
|
11
|
-
import {debug as baseDebug} from '../debug'
|
|
12
|
-
import {getClientWrapper, getCliToken} from './clientWrapper'
|
|
13
|
-
import {createExpiringConfig} from './createExpiringConfig'
|
|
14
|
-
import {getUserConfig} from './getUserConfig'
|
|
15
|
-
import {isCi} from './isCi'
|
|
16
|
-
import {isTrueish} from './isTrueish'
|
|
17
|
-
|
|
18
|
-
const debug = baseDebug.extend('telemetry')
|
|
19
|
-
|
|
20
|
-
const FIVE_MINUTES = 1000 * 60 * 5
|
|
21
|
-
const LOG_FILE_NAME = 'telemetry-events.ndjson'
|
|
22
|
-
|
|
23
|
-
export const TELEMETRY_CONSENT_CONFIG_KEY = 'telemetryConsent'
|
|
24
|
-
|
|
25
|
-
const VALID_API_STATUSES = ['granted', 'denied', 'unset'] as const
|
|
26
|
-
type ValidApiConsentStatus = (typeof VALID_API_STATUSES)[number]
|
|
27
|
-
|
|
28
|
-
function isValidApiConsentStatus(status: string): status is ValidApiConsentStatus {
|
|
29
|
-
return VALID_API_STATUSES.includes(status as ValidApiConsentStatus)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function parseApiConsentStatus(value: unknown): ValidApiConsentStatus {
|
|
33
|
-
if (typeof value === 'string' && isValidApiConsentStatus(value)) {
|
|
34
|
-
return value
|
|
35
|
-
}
|
|
36
|
-
throw new Error(`Invalid consent status. Must be one of: ${VALID_API_STATUSES.join(', ')}`)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function createTelemetryClient(token: string) {
|
|
40
|
-
const getClient = getClientWrapper(null, 'sanity.cli.js')
|
|
41
|
-
return getClient({requireUser: false, requireProject: false}).config({
|
|
42
|
-
apiVersion: '2023-12-18',
|
|
43
|
-
token,
|
|
44
|
-
useCdn: false,
|
|
45
|
-
useProjectHostname: false,
|
|
46
|
-
})
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
let _client: SanityClient | null = null
|
|
50
|
-
function getCachedClient(token: string) {
|
|
51
|
-
if (!_client) {
|
|
52
|
-
_client = createTelemetryClient(token)
|
|
53
|
-
}
|
|
54
|
-
return _client
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
interface Env {
|
|
58
|
-
DO_NOT_TRACK?: string
|
|
59
|
-
SANITY_TELEMETRY_INSPECT?: string
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
interface Options {
|
|
63
|
-
env: Env | NodeJS.ProcessEnv
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export type ConsentInformation =
|
|
67
|
-
| {
|
|
68
|
-
status: Extract<ConsentStatus, 'granted'>
|
|
69
|
-
reason?: never
|
|
70
|
-
}
|
|
71
|
-
| {
|
|
72
|
-
status: Extract<ConsentStatus, 'undetermined'>
|
|
73
|
-
reason: 'unauthenticated' | 'fetchError'
|
|
74
|
-
}
|
|
75
|
-
| {
|
|
76
|
-
status: Extract<ConsentStatus, 'denied'>
|
|
77
|
-
reason?: 'localOverride'
|
|
78
|
-
}
|
|
79
|
-
| {
|
|
80
|
-
status: Extract<ConsentStatus, 'unset'>
|
|
81
|
-
reason?: never
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export function resolveConsent({env}: Options): Promise<ConsentInformation> {
|
|
85
|
-
debug('Resolving consent…')
|
|
86
|
-
if (isCi) {
|
|
87
|
-
debug('CI environment detected, treating telemetry consent as denied')
|
|
88
|
-
return Promise.resolve({status: 'denied'})
|
|
89
|
-
}
|
|
90
|
-
if (isTrueish(env.DO_NOT_TRACK)) {
|
|
91
|
-
debug('DO_NOT_TRACK is set, consent is denied')
|
|
92
|
-
return Promise.resolve({
|
|
93
|
-
status: 'denied',
|
|
94
|
-
reason: 'localOverride',
|
|
95
|
-
})
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const token = getCliToken()
|
|
99
|
-
if (!token) {
|
|
100
|
-
debug('User is not logged in, consent is undetermined')
|
|
101
|
-
return Promise.resolve({
|
|
102
|
-
status: 'undetermined',
|
|
103
|
-
reason: 'unauthenticated',
|
|
104
|
-
})
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const client = getCachedClient(token)
|
|
108
|
-
|
|
109
|
-
function fetchConsent(): Promise<{
|
|
110
|
-
status: ValidApiConsentStatus
|
|
111
|
-
}> {
|
|
112
|
-
const telemetryConsentConfig = createExpiringConfig<{
|
|
113
|
-
status: ValidApiConsentStatus
|
|
114
|
-
}>({
|
|
115
|
-
store: getUserConfig(),
|
|
116
|
-
key: TELEMETRY_CONSENT_CONFIG_KEY,
|
|
117
|
-
ttl: FIVE_MINUTES,
|
|
118
|
-
fetchValue: () =>
|
|
119
|
-
client.request({uri: '/intake/telemetry-status', tag: 'telemetry-consent.cli'}),
|
|
120
|
-
onRevalidate() {
|
|
121
|
-
debug('Revalidating cached telemetry consent status...')
|
|
122
|
-
},
|
|
123
|
-
onFetch() {
|
|
124
|
-
debug('Fetching telemetry consent status...')
|
|
125
|
-
},
|
|
126
|
-
onCacheHit() {
|
|
127
|
-
debug('Retrieved telemetry consent status from cache')
|
|
128
|
-
},
|
|
129
|
-
})
|
|
130
|
-
return telemetryConsentConfig.get()
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return fetchConsent()
|
|
134
|
-
.then<ConsentInformation>((response) => {
|
|
135
|
-
debug('User consent status is %s', response.status)
|
|
136
|
-
return {status: parseApiConsentStatus(response.status)}
|
|
137
|
-
})
|
|
138
|
-
.catch((err) => {
|
|
139
|
-
debug('Failed to fetch user consent status, treating it as "undetermined": %s', err.stack)
|
|
140
|
-
return {
|
|
141
|
-
status: 'undetermined',
|
|
142
|
-
reason: 'fetchError',
|
|
143
|
-
}
|
|
144
|
-
})
|
|
145
|
-
}
|
|
146
|
-
export function createTelemetryStore<UserProperties>({
|
|
147
|
-
env,
|
|
148
|
-
projectId,
|
|
149
|
-
}: {
|
|
150
|
-
projectId?: string
|
|
151
|
-
env: {[key: string]: string | undefined}
|
|
152
|
-
}) {
|
|
153
|
-
debug('Initializing telemetry')
|
|
154
|
-
|
|
155
|
-
// Note: if this function throws/rejects the events will be put back on the buffer
|
|
156
|
-
async function sendEvents(batch: TelemetryEvent[]) {
|
|
157
|
-
const token = getCliToken()
|
|
158
|
-
if (!token) {
|
|
159
|
-
// Note: since the telemetry store checks for consent before sending events, and this token
|
|
160
|
-
// check is also done during consent checking, this would normally never happen
|
|
161
|
-
debug('No user token found. Something is not quite right')
|
|
162
|
-
return Promise.reject(new Error('User is not logged in'))
|
|
163
|
-
}
|
|
164
|
-
const inspectEvents = isTrueish(env.SANITY_TELEMETRY_INSPECT)
|
|
165
|
-
if (inspectEvents) {
|
|
166
|
-
// eslint-disable-next-line no-console
|
|
167
|
-
console.info(`SANITY_TELEMETRY_INSPECT is set, appending events to "${LOG_FILE_NAME}"`)
|
|
168
|
-
await appendFile(LOG_FILE_NAME, `${batch.map((entry) => JSON.stringify(entry)).join('\n')}\n`)
|
|
169
|
-
}
|
|
170
|
-
const client = getCachedClient(token)
|
|
171
|
-
debug('Submitting %s telemetry events', batch.length)
|
|
172
|
-
try {
|
|
173
|
-
return await client.request({
|
|
174
|
-
uri: '/intake/batch',
|
|
175
|
-
method: 'POST',
|
|
176
|
-
json: true,
|
|
177
|
-
body: {projectId, batch},
|
|
178
|
-
})
|
|
179
|
-
} catch (err) {
|
|
180
|
-
const statusCode = err.response && err.response.statusCode
|
|
181
|
-
debug(
|
|
182
|
-
'Failed to send telemetry events%s: %s',
|
|
183
|
-
statusCode ? ` (HTTP ${statusCode})` : '',
|
|
184
|
-
err.stack,
|
|
185
|
-
)
|
|
186
|
-
// note: we want to throw - the telemetry store implements error handling already
|
|
187
|
-
throw err
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const sessionId = createSessionId()
|
|
192
|
-
debug('session id: %s', sessionId)
|
|
193
|
-
|
|
194
|
-
const store = createBatchedStore<UserProperties>(sessionId, {
|
|
195
|
-
resolveConsent: () => resolveConsent({env}),
|
|
196
|
-
sendEvents,
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
process.once('SIGINT', () => store.flush().finally(() => process.exit(0)))
|
|
200
|
-
process.once('beforeExit', () => store.flush())
|
|
201
|
-
process.once('unhandledRejection', () => store.flush())
|
|
202
|
-
process.once('uncaughtException', () => store.flush())
|
|
203
|
-
return store
|
|
204
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export function detectRuntime() {
|
|
2
|
-
if ('Deno' in globalThis) {
|
|
3
|
-
return 'deno'
|
|
4
|
-
}
|
|
5
|
-
if ('Bun' in globalThis) {
|
|
6
|
-
return 'bun'
|
|
7
|
-
}
|
|
8
|
-
// Consider using a more reliable way of detecting that we're actually in Node.js
|
|
9
|
-
// I first attempted using https://www.npmjs.com/package/is-really-node, but it fails
|
|
10
|
-
// due to using top level await.
|
|
11
|
-
return 'node'
|
|
12
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
// Prevent webpack from bundling in webpack context,
|
|
2
|
-
// use regular node require for unbundled context
|
|
3
|
-
|
|
4
|
-
/* eslint-disable camelcase, no-undef */
|
|
5
|
-
declare const __webpack_require__: boolean
|
|
6
|
-
declare const __non_webpack_require__: typeof require
|
|
7
|
-
|
|
8
|
-
const requireFunc: typeof require =
|
|
9
|
-
typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require
|
|
10
|
-
/* eslint-enable camelcase, no-undef */
|
|
11
|
-
|
|
12
|
-
export function dynamicRequire<T = any>(request: string): T {
|
|
13
|
-
const mod = requireFunc(request)
|
|
14
|
-
return mod.__esModule && mod.default ? mod.default : mod
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
dynamicRequire.resolve = requireFunc.resolve
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
const FALLBACK_PORT = 3000
|
|
2
|
-
|
|
3
|
-
const portMap: Record<string, number> = {
|
|
4
|
-
'nextjs': 3000,
|
|
5
|
-
'blitzjs': 3000,
|
|
6
|
-
'gatsby': 8000,
|
|
7
|
-
'remix': 3000,
|
|
8
|
-
'astro': 4321,
|
|
9
|
-
'hexo': 4000,
|
|
10
|
-
'eleventy': 8080,
|
|
11
|
-
'docusaurus': 3000,
|
|
12
|
-
'docusaurus-2': 3000,
|
|
13
|
-
'preact': 8080,
|
|
14
|
-
'solidstart': 3000,
|
|
15
|
-
'solidstart-1': 3000,
|
|
16
|
-
'dojo': 3000,
|
|
17
|
-
'ember': 4200,
|
|
18
|
-
'vue': 8080,
|
|
19
|
-
'scully': 1668,
|
|
20
|
-
'ionic-angular': 4200,
|
|
21
|
-
'angular': 4200,
|
|
22
|
-
'polymer': 8081,
|
|
23
|
-
'svelte': 5000,
|
|
24
|
-
'sveltekit': 5173,
|
|
25
|
-
'sveltekit-1': 5173,
|
|
26
|
-
'ionic-react': 3000,
|
|
27
|
-
'create-react-app': 3000,
|
|
28
|
-
'gridsome': 8080,
|
|
29
|
-
'umijs': 8000,
|
|
30
|
-
'saber': 3000,
|
|
31
|
-
'stencil': 3333,
|
|
32
|
-
'nuxtjs': 3000,
|
|
33
|
-
'redwoodjs': 8910,
|
|
34
|
-
'hugo': 1313,
|
|
35
|
-
'jekyll': 4000,
|
|
36
|
-
'brunch': 3333,
|
|
37
|
-
'middleman': 4567,
|
|
38
|
-
'zola': 1111,
|
|
39
|
-
'hydrogen': 3000,
|
|
40
|
-
'vite': 5173,
|
|
41
|
-
'vitepress': 5173,
|
|
42
|
-
'vuepress': 8080,
|
|
43
|
-
'parcel': 1234,
|
|
44
|
-
'fasthtml': 8000,
|
|
45
|
-
'sanity': 3333,
|
|
46
|
-
'sanity-v3': 3333,
|
|
47
|
-
'storybook': 6006,
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Returns the default development port for a given framework.
|
|
52
|
-
* Contains default ports for all frameworks supported by `@vercel/frameworks`.
|
|
53
|
-
* Falls back to port 3000 if framework is not found or not specified.
|
|
54
|
-
*
|
|
55
|
-
* @see https://github.com/vercel/vercel/blob/main/packages/frameworks/src/frameworks.ts
|
|
56
|
-
* for the complete list of supported frameworks
|
|
57
|
-
*
|
|
58
|
-
* @param frameworkSlug - The framework identifier from `@vercel/frameworks`
|
|
59
|
-
* @returns The default port number for the framework
|
|
60
|
-
*/
|
|
61
|
-
export function getDefaultPortForFramework(frameworkSlug?: string | null): number {
|
|
62
|
-
return portMap[frameworkSlug ?? ''] ?? FALLBACK_PORT
|
|
63
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import {padEnd} from 'lodash'
|
|
2
|
-
|
|
3
|
-
import {type CliCommandDefinition, type CliCommandGroupDefinition} from '../types'
|
|
4
|
-
import {getNoSuchCommandText} from './noSuchCommandText'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Generate documentation for all commands within a given group
|
|
8
|
-
*/
|
|
9
|
-
export function generateCommandsDocumentation(
|
|
10
|
-
commandGroups: Record<string, (CliCommandDefinition | CliCommandGroupDefinition)[]>,
|
|
11
|
-
group = 'default',
|
|
12
|
-
): string {
|
|
13
|
-
const commandGroup = commandGroups[group]
|
|
14
|
-
const commands = commandGroup && commandGroup.filter((cmd) => !cmd.hideFromHelp)
|
|
15
|
-
|
|
16
|
-
if (!commands || commands.length === 0) {
|
|
17
|
-
throw new Error(getNoSuchCommandText(group))
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Find the maximum length of a command name, so we can pad the descriptions
|
|
21
|
-
const cmdLength = commands.reduce((max, cmd) => Math.max(cmd.name.length, max), 0)
|
|
22
|
-
const prefix = group === 'default' ? '' : ` ${group}`
|
|
23
|
-
|
|
24
|
-
const rows = [
|
|
25
|
-
`usage: npx sanity${prefix} [--default] [-v|--version] [-d|--debug] [-h|--help] <command> [<args>]`,
|
|
26
|
-
'',
|
|
27
|
-
'Commands:',
|
|
28
|
-
]
|
|
29
|
-
.concat(commands.map((cmd) => ` ${padEnd(cmd.name, cmdLength + 1)} ${cmd.description}`))
|
|
30
|
-
.concat([
|
|
31
|
-
'',
|
|
32
|
-
`See 'npx sanity help${prefix} <command>' for specific information on a subcommand.`,
|
|
33
|
-
])
|
|
34
|
-
|
|
35
|
-
return rows.join('\n')
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Generate documentation for a single command within the given group
|
|
40
|
-
*/
|
|
41
|
-
export function generateCommandDocumentation(
|
|
42
|
-
command: CliCommandDefinition,
|
|
43
|
-
group?: string | null,
|
|
44
|
-
subCommand?: string,
|
|
45
|
-
): string {
|
|
46
|
-
if (!command) {
|
|
47
|
-
throw new Error(
|
|
48
|
-
subCommand
|
|
49
|
-
? `"${subCommand}" is not a subcommand of "${group}". See 'npx sanity help ${group}'`
|
|
50
|
-
: getNoSuchCommandText(group || command),
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const cmdParts = [group || command.name, subCommand].filter(Boolean).join(' ')
|
|
55
|
-
return [
|
|
56
|
-
`usage: npx sanity ${cmdParts} ${command.signature}`,
|
|
57
|
-
'',
|
|
58
|
-
` ${command.description}`,
|
|
59
|
-
'',
|
|
60
|
-
(command.helpText || '').trim(),
|
|
61
|
-
].join('\n')
|
|
62
|
-
}
|
package/src/util/getCliConfig.ts
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-sync */
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Reads the Sanity CLI config from one of the following files (in preferred order):
|
|
5
|
-
* - sanity.cli.js
|
|
6
|
-
* - sanity.cli.ts
|
|
7
|
-
*
|
|
8
|
-
* Note: There are two ways of using this:
|
|
9
|
-
* a) `getCliConfig(cwd)`
|
|
10
|
-
* b) `getCliConfig(cwd, {forked: true})`
|
|
11
|
-
*
|
|
12
|
-
* Approach a is generally a bit faster as it avoids the forking startup time, while
|
|
13
|
-
* approach b could be considered "safer" since any side-effects of running the config
|
|
14
|
-
* file will not bleed into the current CLI process directly.
|
|
15
|
-
*/
|
|
16
|
-
import fs from 'node:fs'
|
|
17
|
-
import path from 'node:path'
|
|
18
|
-
import {Worker} from 'node:worker_threads'
|
|
19
|
-
|
|
20
|
-
import {type CliConfig, type SanityJson} from '../types'
|
|
21
|
-
import {getCliWorkerPath} from './cliWorker'
|
|
22
|
-
import {dynamicRequire} from './dynamicRequire'
|
|
23
|
-
|
|
24
|
-
export type CliMajorVersion = 2 | 3
|
|
25
|
-
|
|
26
|
-
export type CliConfigResult =
|
|
27
|
-
| {config: SanityJson; path: string; version: 2}
|
|
28
|
-
| {config: CliConfig; path: string; version: 3}
|
|
29
|
-
| {config: null; path: string; version: CliMajorVersion}
|
|
30
|
-
|
|
31
|
-
export async function getCliConfig(
|
|
32
|
-
cwd: string,
|
|
33
|
-
{forked}: {forked?: boolean} = {},
|
|
34
|
-
): Promise<CliConfigResult | null> {
|
|
35
|
-
if (forked) {
|
|
36
|
-
try {
|
|
37
|
-
return await getCliConfigForked(cwd)
|
|
38
|
-
} catch {
|
|
39
|
-
// Intentional noop - try unforked variant
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const {unregister} = __DEV__
|
|
44
|
-
? {unregister: () => undefined}
|
|
45
|
-
: // eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
46
|
-
require('esbuild-register/dist/node').register({supported: {'dynamic-import': true}})
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
const v3Config = getSanityCliConfig(cwd)
|
|
50
|
-
if (v3Config) {
|
|
51
|
-
return v3Config
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return getSanityJsonConfig(cwd)
|
|
55
|
-
} catch (err) {
|
|
56
|
-
throw err
|
|
57
|
-
} finally {
|
|
58
|
-
unregister()
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function getCliConfigSync(cwd: string): CliConfigResult | null {
|
|
63
|
-
const v3Config = getSanityCliConfig(cwd)
|
|
64
|
-
return v3Config ? v3Config : getSanityJsonConfig(cwd)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async function getCliConfigForked(cwd: string): Promise<CliConfigResult | null> {
|
|
68
|
-
const workerPath = await getCliWorkerPath('getCliConfig')
|
|
69
|
-
return new Promise((resolve, reject) => {
|
|
70
|
-
const worker = new Worker(workerPath, {
|
|
71
|
-
workerData: cwd,
|
|
72
|
-
env: process.env,
|
|
73
|
-
})
|
|
74
|
-
worker.on('message', (message) => {
|
|
75
|
-
if (message.type === 'config') {
|
|
76
|
-
resolve(message.config)
|
|
77
|
-
} else {
|
|
78
|
-
const error = new Error(message.error)
|
|
79
|
-
;(error as any).type = message.errorType
|
|
80
|
-
reject(new Error(message.error))
|
|
81
|
-
}
|
|
82
|
-
})
|
|
83
|
-
worker.on('error', reject)
|
|
84
|
-
worker.on('exit', (code) => {
|
|
85
|
-
if (code !== 0) {
|
|
86
|
-
reject(new Error(`Worker stopped with exit code ${code}`))
|
|
87
|
-
}
|
|
88
|
-
})
|
|
89
|
-
})
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function getSanityJsonConfig(cwd: string): CliConfigResult | null {
|
|
93
|
-
const configPath = path.join(cwd, 'sanity.json')
|
|
94
|
-
|
|
95
|
-
if (!fs.existsSync(configPath)) {
|
|
96
|
-
return null
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
config: loadJsonConfig(configPath),
|
|
101
|
-
path: configPath,
|
|
102
|
-
version: 2,
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function getSanityCliConfig(cwd: string): CliConfigResult | null {
|
|
107
|
-
const jsConfigPath = path.join(cwd, 'sanity.cli.js')
|
|
108
|
-
const tsConfigPath = path.join(cwd, 'sanity.cli.ts')
|
|
109
|
-
|
|
110
|
-
const [js, ts] = [fs.existsSync(jsConfigPath), fs.existsSync(tsConfigPath)]
|
|
111
|
-
|
|
112
|
-
if (!js && !ts) {
|
|
113
|
-
return null
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (!js && ts) {
|
|
117
|
-
return {
|
|
118
|
-
config: importConfig(tsConfigPath),
|
|
119
|
-
path: tsConfigPath,
|
|
120
|
-
version: 3,
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (js && ts) {
|
|
125
|
-
warn('Found both `sanity.cli.js` and `sanity.cli.ts` - using sanity.cli.js')
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
config: importConfig(jsConfigPath),
|
|
130
|
-
path: jsConfigPath,
|
|
131
|
-
version: 3,
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function loadJsonConfig(filePath: string): SanityJson | null {
|
|
136
|
-
try {
|
|
137
|
-
const content = fs.readFileSync(filePath, 'utf8')
|
|
138
|
-
return JSON.parse(content)
|
|
139
|
-
} catch (err) {
|
|
140
|
-
console.error(`Error reading "${filePath}": ${err.message}`)
|
|
141
|
-
return null
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function importConfig(filePath: string): CliConfig | null {
|
|
146
|
-
try {
|
|
147
|
-
const config = dynamicRequire<CliConfig | {default: CliConfig} | null>(filePath)
|
|
148
|
-
if (config === null || typeof config !== 'object') {
|
|
149
|
-
throw new Error('Module export is not a configuration object')
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return 'default' in config ? config.default : config
|
|
153
|
-
} catch (err) {
|
|
154
|
-
// If attempting to import `defineCliConfig` or similar from `sanity/cli`,
|
|
155
|
-
// accept the fact that it might not be installed. Instead, let the CLI
|
|
156
|
-
// give a warning about the `sanity` module not being installed
|
|
157
|
-
if (err.code === 'MODULE_NOT_FOUND' && err.message.includes('sanity/cli')) {
|
|
158
|
-
return null
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
console.error(`Error reading "${filePath}": ${err.message}`)
|
|
162
|
-
return null
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function warn(warning: string) {
|
|
167
|
-
if (typeof process.send === 'function') {
|
|
168
|
-
process.send({type: 'warning', warning})
|
|
169
|
-
} else {
|
|
170
|
-
console.warn(warning)
|
|
171
|
-
}
|
|
172
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs/promises'
|
|
2
|
-
import path from 'node:path'
|
|
3
|
-
|
|
4
|
-
import pkgDir from 'pkg-dir'
|
|
5
|
-
|
|
6
|
-
export async function getCliVersion(): Promise<string> {
|
|
7
|
-
const cliPath = pkgDir.sync(__dirname)
|
|
8
|
-
|
|
9
|
-
if (!cliPath) {
|
|
10
|
-
throw new Error('Unable to resolve root of @sanity/cli module')
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
let data: string | undefined
|
|
14
|
-
try {
|
|
15
|
-
data = await fs.readFile(path.join(cliPath, 'package.json'), 'utf-8')
|
|
16
|
-
} catch (err) {
|
|
17
|
-
throw new Error(`Unable to read @sanity/cli/package.json: ${err.message}`)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const pkg = JSON.parse(data)
|
|
21
|
-
return pkg.version
|
|
22
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import {readFileSync} from 'node:fs'
|
|
2
|
-
import {join as joinPath, normalize as normalizePath} from 'node:path'
|
|
3
|
-
|
|
4
|
-
import resolveFrom from 'resolve-from'
|
|
5
|
-
|
|
6
|
-
export function getLocalVersion(moduleId: string, workDir: string): string | undefined {
|
|
7
|
-
const fromPath = workDir || process.cwd()
|
|
8
|
-
const modulePath = resolveFrom.silent(fromPath, joinPath(moduleId, 'package.json'))
|
|
9
|
-
if (modulePath) {
|
|
10
|
-
return tryGetVersion(modulePath)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// In the case of packages with an `exports` key, we may not be able to resolve `package.json`.
|
|
14
|
-
// If this happens, try to resolve the module itself and look for the last occurence of the
|
|
15
|
-
// package name, then append `package.json` to that path
|
|
16
|
-
const pathSegment = normalizePath(moduleId)
|
|
17
|
-
const parentPath = resolveFrom.silent(fromPath, moduleId)
|
|
18
|
-
if (!parentPath) {
|
|
19
|
-
return undefined
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const moduleRoot = parentPath.slice(0, parentPath.lastIndexOf(pathSegment) + pathSegment.length)
|
|
23
|
-
const manifestPath = joinPath(moduleRoot, 'package.json')
|
|
24
|
-
return tryGetVersion(manifestPath)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function tryGetVersion(modulePath: string): string | undefined {
|
|
28
|
-
try {
|
|
29
|
-
const fileContent = readFileSync(modulePath, 'utf8')
|
|
30
|
-
const manifest = JSON.parse(fileContent)
|
|
31
|
-
return manifest.version
|
|
32
|
-
} catch {
|
|
33
|
-
return undefined
|
|
34
|
-
}
|
|
35
|
-
}
|