@sanity/cli 3.93.0 → 3.93.1-bump-pkg-utils.34.5d0c0b3d22

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.
Files changed (160) hide show
  1. package/lib/_chunks-cjs/cli.js +5 -5
  2. package/lib/_chunks-cjs/cli.js.map +1 -1
  3. package/lib/_chunks-cjs/cliWorker.js.map +1 -1
  4. package/lib/_chunks-cjs/generateAction.js.map +1 -1
  5. package/lib/_chunks-cjs/getCliConfig.js.map +1 -1
  6. package/lib/_chunks-cjs/journeyConfig.js.map +1 -1
  7. package/lib/_chunks-cjs/loadEnv.js.map +1 -1
  8. package/lib/index.js.map +1 -1
  9. package/lib/index.mjs.map +1 -1
  10. package/lib/run.js.map +1 -1
  11. package/lib/workers/getAndWriteJourneySchema.js.map +1 -1
  12. package/lib/workers/getCliConfig.js.map +1 -1
  13. package/lib/workers/typegenGenerate.js.map +1 -1
  14. package/package.json +6 -7
  15. package/templates/blog/README.md +1 -1
  16. package/templates/clean/README.md +1 -1
  17. package/templates/ecommerce/README.md +1 -1
  18. package/templates/get-started/README.md +1 -1
  19. package/templates/moviedb/README.md +1 -1
  20. package/templates/quickstart/README.md +1 -1
  21. package/src/CommandRunner.ts +0 -219
  22. package/src/__telemetry__/cli.telemetry.ts +0 -29
  23. package/src/__telemetry__/init.telemetry.ts +0 -95
  24. package/src/actions/codemod/codemodAction.ts +0 -109
  25. package/src/actions/codemod/mods/deskRename.ts +0 -19
  26. package/src/actions/codemod/mods/index.ts +0 -9
  27. package/src/actions/codemod/mods/partsTypeDirective.ts +0 -28
  28. package/src/actions/codemod/mods/reactIconsV3.ts +0 -54
  29. package/src/actions/codemod/types.ts +0 -10
  30. package/src/actions/init-plugin/bootstrapFromTemplate.ts +0 -196
  31. package/src/actions/init-project/bootstrapLocalTemplate.ts +0 -201
  32. package/src/actions/init-project/bootstrapRemoteTemplate.ts +0 -118
  33. package/src/actions/init-project/createAppCliConfig.ts +0 -24
  34. package/src/actions/init-project/createCliConfig.ts +0 -31
  35. package/src/actions/init-project/createPackageManifest.ts +0 -102
  36. package/src/actions/init-project/createStudioConfig.ts +0 -53
  37. package/src/actions/init-project/determineAppTemplate.ts +0 -13
  38. package/src/actions/init-project/fsUtils.ts +0 -40
  39. package/src/actions/init-project/git.ts +0 -59
  40. package/src/actions/init-project/initProject.ts +0 -1708
  41. package/src/actions/init-project/processTemplate.ts +0 -55
  42. package/src/actions/init-project/promptForDatasetName.ts +0 -68
  43. package/src/actions/init-project/prompts/index.ts +0 -51
  44. package/src/actions/init-project/prompts/nextjs.ts +0 -59
  45. package/src/actions/init-project/readPackageJson.ts +0 -17
  46. package/src/actions/init-project/templates/appQuickstart.ts +0 -23
  47. package/src/actions/init-project/templates/appSanityUi.ts +0 -25
  48. package/src/actions/init-project/templates/blog.ts +0 -5
  49. package/src/actions/init-project/templates/clean.ts +0 -5
  50. package/src/actions/init-project/templates/getStarted.ts +0 -37
  51. package/src/actions/init-project/templates/index.ts +0 -24
  52. package/src/actions/init-project/templates/moviedb.ts +0 -35
  53. package/src/actions/init-project/templates/nextjs/index.ts +0 -238
  54. package/src/actions/init-project/templates/nextjs/schemaTypes/blog.ts +0 -252
  55. package/src/actions/init-project/templates/quickstart.ts +0 -5
  56. package/src/actions/init-project/templates/shopify.ts +0 -78
  57. package/src/actions/init-project/templates/shopifyOnline.ts +0 -50
  58. package/src/actions/init-project/updateInitialTemplateMetadata.ts +0 -24
  59. package/src/actions/login/login.telemetry.ts +0 -18
  60. package/src/actions/login/login.ts +0 -350
  61. package/src/actions/login/types.ts +0 -19
  62. package/src/actions/project/createProject.ts +0 -36
  63. package/src/actions/telemetry/setTelemetryConsent.ts +0 -101
  64. package/src/actions/typegen/generate.telemetry.ts +0 -20
  65. package/src/actions/typegen/generateAction.ts +0 -210
  66. package/src/actions/versions/findSanityModuleVersions.ts +0 -185
  67. package/src/actions/yarn/events.ts +0 -73
  68. package/src/cli.ts +0 -350
  69. package/src/cliClient.ts +0 -62
  70. package/src/commands/blueprints/addBlueprintsCommand.ts +0 -155
  71. package/src/commands/blueprints/blueprintsGroup.ts +0 -10
  72. package/src/commands/blueprints/configBlueprintsCommand.ts +0 -86
  73. package/src/commands/blueprints/deployBlueprintsCommand.ts +0 -63
  74. package/src/commands/blueprints/destroyBlueprintsCommand.ts +0 -78
  75. package/src/commands/blueprints/infoBlueprintsCommand.ts +0 -55
  76. package/src/commands/blueprints/initBlueprintsCommand.ts +0 -99
  77. package/src/commands/blueprints/logsBlueprintsCommand.ts +0 -66
  78. package/src/commands/blueprints/planBlueprintsCommand.ts +0 -51
  79. package/src/commands/blueprints/stacksBlueprintsCommand.ts +0 -66
  80. package/src/commands/codemod/codemodCommand.ts +0 -32
  81. package/src/commands/debug/debugCommand.ts +0 -26
  82. package/src/commands/debug/printDebugInfo.ts +0 -243
  83. package/src/commands/docs/docsCommand.ts +0 -20
  84. package/src/commands/functions/devFunctionsCommand.ts +0 -73
  85. package/src/commands/functions/envFunctionsCommand.ts +0 -105
  86. package/src/commands/functions/functionsGroup.ts +0 -10
  87. package/src/commands/functions/logsFunctionsCommand.ts +0 -94
  88. package/src/commands/functions/testFunctionsCommand.ts +0 -93
  89. package/src/commands/help/helpCommand.ts +0 -21
  90. package/src/commands/help/showHelp.ts +0 -58
  91. package/src/commands/index.ts +0 -72
  92. package/src/commands/init/initCommand.ts +0 -123
  93. package/src/commands/install/installCommand.ts +0 -38
  94. package/src/commands/learn/learnCommand.ts +0 -20
  95. package/src/commands/login/loginCommand.ts +0 -29
  96. package/src/commands/logout/logoutCommand.ts +0 -52
  97. package/src/commands/manage/manageCommand.ts +0 -24
  98. package/src/commands/projects/listProjectsCommand.ts +0 -62
  99. package/src/commands/projects/projectsGroup.ts +0 -10
  100. package/src/commands/telemetry/disableTelemetryCommand.ts +0 -19
  101. package/src/commands/telemetry/enableTelemetryCommand.ts +0 -19
  102. package/src/commands/telemetry/telemetryGroup.ts +0 -10
  103. package/src/commands/telemetry/telemetryStatusCommand.ts +0 -89
  104. package/src/commands/typegen/generateTypesCommand.ts +0 -56
  105. package/src/commands/typegen/typegenGroup.ts +0 -10
  106. package/src/commands/versions/printVersionResult.ts +0 -51
  107. package/src/commands/versions/versionsCommand.ts +0 -13
  108. package/src/config.ts +0 -14
  109. package/src/debug.ts +0 -3
  110. package/src/index.ts +0 -6
  111. package/src/outputters/cliOutputter.ts +0 -47
  112. package/src/packageManager/getInstallCommand.ts +0 -26
  113. package/src/packageManager/getUpgradeCommand.ts +0 -52
  114. package/src/packageManager/index.ts +0 -33
  115. package/src/packageManager/installPackages.ts +0 -99
  116. package/src/packageManager/packageManagerChoice.ts +0 -204
  117. package/src/packageManager/uninstallPackages.ts +0 -44
  118. package/src/packageManager/yarnStub.ts +0 -22
  119. package/src/prompters/cliPrompter.ts +0 -9
  120. package/src/run.ts +0 -8
  121. package/src/studioDependencies.ts +0 -25
  122. package/src/types.ts +0 -387
  123. package/src/util/canLaunchBrowser.ts +0 -12
  124. package/src/util/cliWorker.ts +0 -34
  125. package/src/util/clientWrapper.ts +0 -119
  126. package/src/util/copy.ts +0 -50
  127. package/src/util/createExpiringConfig.ts +0 -80
  128. package/src/util/createTelemetryStore.ts +0 -204
  129. package/src/util/detectRuntime.ts +0 -12
  130. package/src/util/dynamicRequire.ts +0 -17
  131. package/src/util/frameworkPort.ts +0 -63
  132. package/src/util/generateCommandsDocumentation.ts +0 -62
  133. package/src/util/getCliConfig.ts +0 -172
  134. package/src/util/getCliVersion.ts +0 -22
  135. package/src/util/getLocalVersion.ts +0 -35
  136. package/src/util/getProjectDefaults.ts +0 -103
  137. package/src/util/getProviderName.ts +0 -9
  138. package/src/util/getUserConfig.ts +0 -15
  139. package/src/util/isCi.ts +0 -7
  140. package/src/util/isCommandGroup.ts +0 -7
  141. package/src/util/isInteractive.ts +0 -3
  142. package/src/util/isTrueish.ts +0 -8
  143. package/src/util/journeyConfig.ts +0 -280
  144. package/src/util/loadEnv.ts +0 -110
  145. package/src/util/mergeCommands.ts +0 -78
  146. package/src/util/neatStack.ts +0 -30
  147. package/src/util/noSuchCommandText.ts +0 -91
  148. package/src/util/parseArguments.ts +0 -76
  149. package/src/util/pathExists.ts +0 -14
  150. package/src/util/readJson.ts +0 -6
  151. package/src/util/readdirRecursive.ts +0 -26
  152. package/src/util/remoteTemplate.ts +0 -320
  153. package/src/util/resolveLatestVersions.ts +0 -24
  154. package/src/util/resolveRootDir.ts +0 -59
  155. package/src/util/telemetryDisclosure.ts +0 -45
  156. package/src/util/updateNotifier.ts +0 -158
  157. package/src/util/writeJson.ts +0 -6
  158. package/src/workers/getAndWriteJourneySchema.ts +0 -7
  159. package/src/workers/getCliConfig.ts +0 -14
  160. 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
- }
@@ -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
- }